From a0566ce64c7ee285bf4165d1232dd9b0f784e4d2 Mon Sep 17 00:00:00 2001 From: dtoro Date: Tue, 28 Apr 2026 22:54:36 +0200 Subject: [PATCH] =?UTF-8?q?MVP=20M1=E2=80=93M3:=20visual=20port,=20TipTap?= =?UTF-8?q?=20text=20editor,=20React=20Flow=20diagram?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit apps/web — Next.js 16 + TypeScript + React 19 (no Tailwind) M1 Visual port - Manuscript theme + base styles ported verbatim from design-source - 100dvh layout with internal scroll regions (rail / narrative / dock thread) - TopBar, LeftRail (collapsible sections + collapsed strip), CanvasHeader, StatusBar, EditorShell composing the dual-canvas - SocratesDock (subtle/default/prominent) with bubbles + numbered options - Sigil (Σ + laurel) used across editor and seed screens - SeedScreen with emerging-seed rail, mini-graph, confidence bar, thread, typing indicator, input row - Routes: / (homepage), /editor/[projectId], /seed - Aristotle fixture in lib/fixtures (ported from data.js) M2 Real text editor - TipTap (StarterKit + custom Chip atom inline node + ReactNodeViewRenderer) - Slash-menu insertion via @tiptap/suggestion with arrow / number-key shortcuts - ChipFocusContext bridges narrative ↔ diagram hover/selection across the TipTap render boundary - fixtureToDoc converts the fixture narrative → ProseMirror JSON M3 Real diagram - React Flow (@xyflow/react) custom node (block / actor / constraint / system) matching prototype's softened look - Custom edge with bezier path + label renderer (association / composition / constraint variants) - Drag-create from a left-side palette via HTML5 DnD + screenToFlowPosition - NodeInspector panel: edit kind / label / properties (or expression for constraints); delete cascades to incident edges - Bidirectional focus highlighting between chips (narrative) and blocks (diagram) - Removed redundant legend (stereotype labels on nodes serve same purpose) State for M3 lives in component memory; persistence + bidirectional sync land in M4–M5. --- apps/web/.gitignore | 41 + apps/web/README.md | 36 + apps/web/app/editor/[projectId]/page.tsx | 8 + apps/web/app/layout.tsx | 30 + apps/web/app/page.tsx | 50 + apps/web/app/seed/page.tsx | 5 + .../diagram-canvas/DiagramCanvas.tsx | 203 + .../diagram-canvas/NodeInspector.tsx | 140 + .../web/components/diagram-canvas/Palette.tsx | 43 + .../diagram-canvas/edges/SysmlEdge.tsx | 61 + .../diagram-canvas/fixtureToFlow.ts | 47 + .../diagram-canvas/nodes/BlockNode.tsx | 67 + apps/web/components/editor/CanvasHeader.tsx | 22 + apps/web/components/editor/EditorShell.tsx | 87 + apps/web/components/editor/LeftRail.tsx | 140 + apps/web/components/editor/StatusBar.tsx | 20 + apps/web/components/editor/TopBar.tsx | 36 + apps/web/components/seed/SeedScreen.tsx | 185 + apps/web/components/socrates/Sigil.tsx | 42 + apps/web/components/socrates/SocratesDock.tsx | 82 + apps/web/components/text-canvas/Chip.tsx | 71 + apps/web/components/text-canvas/ChipNode.ts | 82 + apps/web/components/text-canvas/ChipView.tsx | 73 + .../components/text-canvas/FocusContext.tsx | 23 + .../components/text-canvas/SlashExtension.ts | 20 + apps/web/components/text-canvas/SlashMenu.tsx | 110 + .../web/components/text-canvas/TextCanvas.tsx | 94 + .../components/text-canvas/fixtureToDoc.ts | 43 + .../components/text-canvas/slashSuggestion.ts | 92 + apps/web/eslint.config.mjs | 18 + apps/web/lib/fixtures/aristotle.ts | 202 + apps/web/next.config.ts | 7 + apps/web/package.json | 31 + apps/web/pnpm-lock.yaml | 4403 +++++++++++++++++ apps/web/styles/base.css | 925 ++++ apps/web/styles/diagram.css | 336 ++ apps/web/styles/theme-manuscript.css | 79 + apps/web/tsconfig.json | 34 + 38 files changed, 7988 insertions(+) create mode 100644 apps/web/.gitignore create mode 100644 apps/web/README.md create mode 100644 apps/web/app/editor/[projectId]/page.tsx create mode 100644 apps/web/app/layout.tsx create mode 100644 apps/web/app/page.tsx create mode 100644 apps/web/app/seed/page.tsx create mode 100644 apps/web/components/diagram-canvas/DiagramCanvas.tsx create mode 100644 apps/web/components/diagram-canvas/NodeInspector.tsx create mode 100644 apps/web/components/diagram-canvas/Palette.tsx create mode 100644 apps/web/components/diagram-canvas/edges/SysmlEdge.tsx create mode 100644 apps/web/components/diagram-canvas/fixtureToFlow.ts create mode 100644 apps/web/components/diagram-canvas/nodes/BlockNode.tsx create mode 100644 apps/web/components/editor/CanvasHeader.tsx create mode 100644 apps/web/components/editor/EditorShell.tsx create mode 100644 apps/web/components/editor/LeftRail.tsx create mode 100644 apps/web/components/editor/StatusBar.tsx create mode 100644 apps/web/components/editor/TopBar.tsx create mode 100644 apps/web/components/seed/SeedScreen.tsx create mode 100644 apps/web/components/socrates/Sigil.tsx create mode 100644 apps/web/components/socrates/SocratesDock.tsx create mode 100644 apps/web/components/text-canvas/Chip.tsx create mode 100644 apps/web/components/text-canvas/ChipNode.ts create mode 100644 apps/web/components/text-canvas/ChipView.tsx create mode 100644 apps/web/components/text-canvas/FocusContext.tsx create mode 100644 apps/web/components/text-canvas/SlashExtension.ts create mode 100644 apps/web/components/text-canvas/SlashMenu.tsx create mode 100644 apps/web/components/text-canvas/TextCanvas.tsx create mode 100644 apps/web/components/text-canvas/fixtureToDoc.ts create mode 100644 apps/web/components/text-canvas/slashSuggestion.ts create mode 100644 apps/web/eslint.config.mjs create mode 100644 apps/web/lib/fixtures/aristotle.ts create mode 100644 apps/web/next.config.ts create mode 100644 apps/web/package.json create mode 100644 apps/web/pnpm-lock.yaml create mode 100644 apps/web/styles/base.css create mode 100644 apps/web/styles/diagram.css create mode 100644 apps/web/styles/theme-manuscript.css create mode 100644 apps/web/tsconfig.json diff --git a/apps/web/.gitignore b/apps/web/.gitignore new file mode 100644 index 0000000..5ef6a52 --- /dev/null +++ b/apps/web/.gitignore @@ -0,0 +1,41 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.* +.yarn/* +!.yarn/patches +!.yarn/plugins +!.yarn/releases +!.yarn/versions + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* +.pnpm-debug.log* + +# env files (can opt-in for committing if needed) +.env* + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/apps/web/README.md b/apps/web/README.md new file mode 100644 index 0000000..e215bc4 --- /dev/null +++ b/apps/web/README.md @@ -0,0 +1,36 @@ +This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app). + +## Getting Started + +First, run the development server: + +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` + +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. + +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. + +This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. + +## Learn More + +To learn more about Next.js, take a look at the following resources: + +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. + +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome! + +## Deploy on Vercel + +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. + +Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details. diff --git a/apps/web/app/editor/[projectId]/page.tsx b/apps/web/app/editor/[projectId]/page.tsx new file mode 100644 index 0000000..defcc94 --- /dev/null +++ b/apps/web/app/editor/[projectId]/page.tsx @@ -0,0 +1,8 @@ +import { EditorShell } from "../../../components/editor/EditorShell"; +import { aristotleFixture } from "../../../lib/fixtures/aristotle"; + +// M1: every projectId resolves to the Aristotle fixture. +// M4–M5 wire this to a real database lookup. +export default async function EditorPage(_props: { params: Promise<{ projectId: string }> }) { + return ; +} diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx new file mode 100644 index 0000000..03d9048 --- /dev/null +++ b/apps/web/app/layout.tsx @@ -0,0 +1,30 @@ +import type { Metadata } from "next"; +import "../styles/base.css"; +import "../styles/theme-manuscript.css"; +import "@xyflow/react/dist/style.css"; +import "../styles/diagram.css"; + +export const metadata: Metadata = { + title: "Socrata", + description: "Structured thinking and validation platform for product managers.", +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + + + + + {children} + + ); +} diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx new file mode 100644 index 0000000..491bc37 --- /dev/null +++ b/apps/web/app/page.tsx @@ -0,0 +1,50 @@ +import Link from "next/link"; + +export default function HomePage() { + return ( +
+

+ Socrata +

+

+ Structured thinking and validation platform for product managers. +

+
    +
  • + + → Open editor (Aristotle fixture) + +
  • +
  • + + → Seed screen (coming next) + +
  • +
+
+ ); +} diff --git a/apps/web/app/seed/page.tsx b/apps/web/app/seed/page.tsx new file mode 100644 index 0000000..fe2d668 --- /dev/null +++ b/apps/web/app/seed/page.tsx @@ -0,0 +1,5 @@ +import { SeedScreen } from "../../components/seed/SeedScreen"; + +export default function SeedPage() { + return ; +} diff --git a/apps/web/components/diagram-canvas/DiagramCanvas.tsx b/apps/web/components/diagram-canvas/DiagramCanvas.tsx new file mode 100644 index 0000000..4de96fe --- /dev/null +++ b/apps/web/components/diagram-canvas/DiagramCanvas.tsx @@ -0,0 +1,203 @@ +// React Flow-backed diagram canvas (M3). +// - Custom block/actor/constraint/system nodes +// - Custom edges (association/composition/constraint) +// - Drag-create from the left palette +// - Click-edit via the right inspector +// - Drag handles between nodes to connect +// +// State is in-memory for M3; M5 swaps it for the bidirectional sync engine. + +"use client"; + +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; +import { + ReactFlow, + ReactFlowProvider, + Background, + BackgroundVariant, + Controls, + MarkerType, + applyNodeChanges, + applyEdgeChanges, + addEdge, + useReactFlow, + type Node, + type Edge, + type NodeChange, + type EdgeChange, + type Connection, + type NodeMouseHandler, +} from "@xyflow/react"; +import { BlockNode, type BlockNodeData } from "./nodes/BlockNode"; +import { SysmlEdge, type SysmlEdgeData } from "./edges/SysmlEdge"; +import { Palette } from "./Palette"; +import { NodeInspector } from "./NodeInspector"; +import { fixtureToFlow } from "./fixtureToFlow"; +import type { Density } from "../socrates/SocratesDock"; +import type { FixtureData, AssociationKind, BlockKind } from "../../lib/fixtures/aristotle"; + +export type DiagramVariant = "softened" | "formal" | "graph"; + +interface DiagramCanvasProps { + data: FixtureData; + density?: Density; + variant?: DiagramVariant; + focusBlockId: string | null; + onSelect?: (id: string | null) => void; +} + +const nodeTypes = { sysmlBlock: BlockNode }; +const edgeTypes = { sysml: SysmlEdge }; + +let nextNodeId = 1000; +let nextEdgeId = 1000; +function freshNodeId(): string { return `n${nextNodeId++}`; } +function freshEdgeId(): string { return `e${nextEdgeId++}`; } + +export function DiagramCanvas(props: DiagramCanvasProps) { + return ( + + + + ); +} + +function DiagramInner({ data, focusBlockId, onSelect }: DiagramCanvasProps) { + const initial = useMemo(() => fixtureToFlow(data), [data]); + const [nodes, setNodes] = useState[]>(initial.nodes); + const [edges, setEdges] = useState[]>(initial.edges); + const wrapperRef = useRef(null); + const { screenToFlowPosition } = useReactFlow(); + + const onNodesChange = useCallback( + (changes: NodeChange[]) => setNodes(ns => applyNodeChanges(changes, ns) as Node[]), + [] + ); + const onEdgesChange = useCallback( + (changes: EdgeChange[]) => setEdges(es => applyEdgeChanges(changes, es) as Edge[]), + [] + ); + const onConnect = useCallback((connection: Connection) => { + const newEdge: Edge = { + id: freshEdgeId(), + source: connection.source, + target: connection.target, + type: "sysml", + data: { label: "relates_to", kind: "association" satisfies AssociationKind }, + markerEnd: { type: MarkerType.Arrow, color: "var(--edge)", width: 18, height: 18 }, + }; + setEdges(es => addEdge(newEdge, es) as Edge[]); + }, []); + + // Highlight focusBlockId from sibling components (e.g. narrative chip hover). + useEffect(() => { + setNodes(ns => + ns.map(n => ({ + ...n, + selected: n.id === focusBlockId, + })) + ); + }, [focusBlockId]); + + const onNodeClick: NodeMouseHandler = useCallback( + (_event, node) => { + onSelect?.(node.id); + }, + [onSelect] + ); + + const onPaneClick = useCallback(() => { + onSelect?.(null); + }, [onSelect]); + + const selectedNode = nodes.find(n => n.id === focusBlockId); + + // Drag-and-drop from the palette + const onDragOver = useCallback((event: React.DragEvent) => { + event.preventDefault(); + event.dataTransfer.dropEffect = "move"; + }, []); + + const onDrop = useCallback( + (event: React.DragEvent) => { + event.preventDefault(); + const kindRaw = event.dataTransfer.getData("application/sysml-kind"); + if (!kindRaw) return; + const kind = kindRaw as BlockKind | "system"; + const position = screenToFlowPosition({ x: event.clientX, y: event.clientY }); + const id = freshNodeId(); + const newNode: Node = { + id, + type: "sysmlBlock", + position, + data: { + label: kind === "system" + ? "System" + : kind === "actor" + ? "Actor" + : kind === "constraint" + ? "Constraint" + : "Block", + kind, + properties: kind === "constraint" ? [] : ["new_property"], + ...(kind === "constraint" ? { expression: "{ }" } : {}), + }, + }; + setNodes(ns => [...ns, newNode]); + onSelect?.(id); + }, + [onSelect, screenToFlowPosition] + ); + + function patchSelected(patch: Partial) { + if (!focusBlockId) return; + setNodes(ns => + ns.map(n => (n.id === focusBlockId ? { ...n, data: { ...(n.data as BlockNodeData), ...patch } } : n)) + ); + } + + function deleteSelected() { + if (!focusBlockId) return; + setNodes(ns => ns.filter(n => n.id !== focusBlockId)); + setEdges(es => es.filter(e => e.source !== focusBlockId && e.target !== focusBlockId)); + onSelect?.(null); + } + + return ( +
+ + + + + + + + {selectedNode && ( + onSelect?.(null)} + /> + )} +
+ ); +} diff --git a/apps/web/components/diagram-canvas/NodeInspector.tsx b/apps/web/components/diagram-canvas/NodeInspector.tsx new file mode 100644 index 0000000..164e617 --- /dev/null +++ b/apps/web/components/diagram-canvas/NodeInspector.tsx @@ -0,0 +1,140 @@ +// Edit panel for the selected block — rename, change kind, add/remove properties, delete. + +"use client"; + +import { useState, useEffect } from "react"; +import type { BlockKind } from "../../lib/fixtures/aristotle"; +import type { BlockNodeData } from "./nodes/BlockNode"; + +interface NodeInspectorProps { + nodeId: string; + data: BlockNodeData; + onChange: (patch: Partial) => void; + onDelete: () => void; + onClose: () => void; +} + +const KINDS: Array = ["system", "block", "actor", "constraint"]; + +export function NodeInspector({ nodeId, data, onChange, onDelete, onClose }: NodeInspectorProps) { + // Local label state for smooth typing — push on blur + const [label, setLabel] = useState(data.label); + const [expression, setExpression] = useState(data.expression ?? ""); + + useEffect(() => { + setLabel(data.label); + setExpression(data.expression ?? ""); + }, [nodeId, data.label, data.expression]); + + function commitLabel() { + if (label.trim() && label !== data.label) onChange({ label: label.trim() }); + } + + function commitExpression() { + onChange({ expression }); + } + + function updateProp(idx: number, value: string) { + const next = [...data.properties]; + next[idx] = value; + onChange({ properties: next }); + } + + function removeProp(idx: number) { + onChange({ properties: data.properties.filter((_, i) => i !== idx) }); + } + + function addProp() { + onChange({ properties: [...data.properties, "new_property"] }); + } + + return ( +
e.stopPropagation()}> +
+ Kind + +
+ +
+ Label + setLabel(e.target.value)} + onBlur={commitLabel} + onKeyDown={e => { + if (e.key === "Enter") { + e.preventDefault(); + (e.target as HTMLInputElement).blur(); + } + }} + /> +
+ + {data.kind === "constraint" ? ( +
+ Expression + setExpression(e.target.value)} + onBlur={commitExpression} + placeholder="{ tenancy = institutional }" + /> +
+ ) : ( +
+ Properties +
+ {data.properties.map((p, i) => ( +
+ updateProp(i, e.target.value)} + onKeyDown={e => { + if (e.key === "Enter") { + e.preventDefault(); + (e.target as HTMLInputElement).blur(); + } + }} + /> + +
+ ))} + +
+
+ )} + +
+ + +
+
+ ); +} diff --git a/apps/web/components/diagram-canvas/Palette.tsx b/apps/web/components/diagram-canvas/Palette.tsx new file mode 100644 index 0000000..2f7f4a4 --- /dev/null +++ b/apps/web/components/diagram-canvas/Palette.tsx @@ -0,0 +1,43 @@ +// Drag source for new blocks. Drop on the React Flow canvas to create. + +"use client"; + +import type { BlockKind } from "../../lib/fixtures/aristotle"; + +interface PaletteItem { + kind: BlockKind | "system"; + label: string; + glyph: string; +} + +const ITEMS: PaletteItem[] = [ + { kind: "system", label: "System", glyph: "◎" }, + { kind: "block", label: "Block", glyph: "▢" }, + { kind: "actor", label: "Actor", glyph: "◐" }, + { kind: "constraint", label: "Constraint", glyph: "{}" }, +]; + +export function Palette() { + function onDragStart(event: React.DragEvent, kind: string) { + event.dataTransfer.setData("application/sysml-kind", kind); + event.dataTransfer.effectAllowed = "move"; + } + + return ( +
+
Add
+ {ITEMS.map(item => ( +
onDragStart(e, item.kind)} + title={`Drag to create a ${item.label}`} + > + {item.glyph} + {item.label} +
+ ))} +
+ ); +} diff --git a/apps/web/components/diagram-canvas/edges/SysmlEdge.tsx b/apps/web/components/diagram-canvas/edges/SysmlEdge.tsx new file mode 100644 index 0000000..e5b8068 --- /dev/null +++ b/apps/web/components/diagram-canvas/edges/SysmlEdge.tsx @@ -0,0 +1,61 @@ +// Custom edge that renders association / composition / constraint variants. +// - association: solid line with arrow +// - composition: solid line with diamond marker at the source side +// - constraint: dashed line, no arrow + +"use client"; + +import { BaseEdge, EdgeLabelRenderer, getBezierPath, type EdgeProps } from "@xyflow/react"; +import type { AssociationKind } from "../../../lib/fixtures/aristotle"; + +export interface SysmlEdgeData extends Record { + label?: string; + kind: AssociationKind; +} + +export function SysmlEdge(props: EdgeProps) { + const { sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data, markerEnd, markerStart } = props; + const d = (data ?? {}) as SysmlEdgeData; + const kind = d.kind ?? "association"; + + const [edgePath, labelX, labelY] = getBezierPath({ + sourceX, sourceY, + sourcePosition, + targetX, targetY, + targetPosition, + curvature: 0.25, + }); + + const isConstraint = kind === "constraint"; + + return ( + <> + + + {d.label && ( + +
+ {d.label} +
+
+ )} + + ); +} diff --git a/apps/web/components/diagram-canvas/fixtureToFlow.ts b/apps/web/components/diagram-canvas/fixtureToFlow.ts new file mode 100644 index 0000000..58ad9b8 --- /dev/null +++ b/apps/web/components/diagram-canvas/fixtureToFlow.ts @@ -0,0 +1,47 @@ +// Convert FixtureData → React Flow nodes/edges. +// Positions in the fixture are normalized 0..1 against a 720×460 board; we map +// to absolute pixel coordinates so React Flow can render them. + +import { MarkerType, type Edge, type Node } from "@xyflow/react"; +import type { BlockNodeData } from "./nodes/BlockNode"; +import type { SysmlEdgeData } from "./edges/SysmlEdge"; +import type { FixtureData, AssociationKind } from "../../lib/fixtures/aristotle"; + +const BOARD_W = 720; +const BOARD_H = 460; + +function markerForKind(kind: AssociationKind) { + if (kind === "composition") { + // React Flow doesn't ship a diamond marker; use the closed-arrow as the + // closest stock alternative. M3 ships this — a custom diamond can be + // added later if needed. + return { type: MarkerType.ArrowClosed, color: "var(--edge)", width: 18, height: 18 }; + } + if (kind === "constraint") return undefined; + return { type: MarkerType.Arrow, color: "var(--edge)", width: 18, height: 18 }; +} + +export function fixtureToFlow(data: FixtureData): { nodes: Node[]; edges: Edge[] } { + const nodes: Node[] = data.blocks.map(b => ({ + id: b.id, + type: "sysmlBlock", + position: { x: b.x * BOARD_W, y: b.y * BOARD_H }, + data: { + label: b.label, + kind: b.kind, + properties: [...b.properties], + ...(b.kind === "constraint" ? { expression: "{ tenancy = institutional }" } : {}), + }, + })); + + const edges: Edge[] = data.associations.map(a => ({ + id: a.id, + source: a.from, + target: a.to, + type: "sysml", + data: { label: a.label, kind: a.kind }, + markerEnd: markerForKind(a.kind), + })); + + return { nodes, edges }; +} diff --git a/apps/web/components/diagram-canvas/nodes/BlockNode.tsx b/apps/web/components/diagram-canvas/nodes/BlockNode.tsx new file mode 100644 index 0000000..b704583 --- /dev/null +++ b/apps/web/components/diagram-canvas/nodes/BlockNode.tsx @@ -0,0 +1,67 @@ +// SysML block / actor / constraint rendered as a React Flow custom node. +// Drives the softened look from the prototype: stereotype label, divider, property compartment. + +"use client"; + +import { Handle, Position, type NodeProps } from "@xyflow/react"; +import type { BlockKind } from "../../../lib/fixtures/aristotle"; + +export interface BlockNodeData extends Record { + label: string; + kind: BlockKind | "system"; + properties: string[]; + /** For constraint kinds, optional one-line expression. */ + expression?: string; +} + +const STEREO: Record = { + block: "block", + actor: "actor", + constraint: "constraint", + system: "system", +}; + +export function BlockNode({ data, selected }: NodeProps) { + const d = data as BlockNodeData; + const kind = d.kind ?? "block"; + const isConstraint = kind === "constraint"; + + const cls = [ + "sysml-node", + `sysml-node-${kind}`, + selected ? "sysml-node-selected" : "", + ] + .filter(Boolean) + .join(" "); + + return ( +
+ + + +
«{STEREO[kind] ?? "block"}»
+
{d.label}
+ + {!isConstraint &&
} + + {!isConstraint ? ( +
+ {d.properties.length === 0 ? ( + no properties + ) : ( + d.properties.slice(0, 6).map((p, i) => ( + · {p} + )) + )} +
+ ) : ( +
+ {d.expression ?? "{ }"} +
+ )} + + + +
+ ); +} diff --git a/apps/web/components/editor/CanvasHeader.tsx b/apps/web/components/editor/CanvasHeader.tsx new file mode 100644 index 0000000..6217d28 --- /dev/null +++ b/apps/web/components/editor/CanvasHeader.tsx @@ -0,0 +1,22 @@ +// Header above each canvas (Narrative / Model). Title + subtitle on the left, optional actions on the right. +// Ported from docs/design-source/socrata/project/editor-shell.jsx (CanvasHeader). + +import type { ReactNode } from "react"; + +interface CanvasHeaderProps { + title: string; + subtitle: string; + right?: ReactNode; +} + +export function CanvasHeader({ title, subtitle, right }: CanvasHeaderProps) { + return ( +
+
+
{title}
+
{subtitle}
+
+
{right}
+
+ ); +} diff --git a/apps/web/components/editor/EditorShell.tsx b/apps/web/components/editor/EditorShell.tsx new file mode 100644 index 0000000..48a2da8 --- /dev/null +++ b/apps/web/components/editor/EditorShell.tsx @@ -0,0 +1,87 @@ +// The dual-canvas workspace shell. +// Composes TopBar / SocratesDock / LeftRail / TextCanvas / DiagramCanvas / StatusBar. +// Ported from docs/design-source/socrata/project/editor-shell.jsx (EditorShell). + +"use client"; + +import { useState } from "react"; +import { TopBar } from "./TopBar"; +import { LeftRail } from "./LeftRail"; +import { CanvasHeader } from "./CanvasHeader"; +import { StatusBar } from "./StatusBar"; +import { TextCanvas } from "../text-canvas/TextCanvas"; +import { DiagramCanvas, type DiagramVariant } from "../diagram-canvas/DiagramCanvas"; +import { SocratesDock, type Density, type SocratesPresence } from "../socrates/SocratesDock"; +import type { MarkupStyle } from "../text-canvas/Chip"; +import type { FixtureData } from "../../lib/fixtures/aristotle"; + +interface EditorShellProps { + data: FixtureData; + density?: Density; + markupStyle?: MarkupStyle; + diagramStyle?: DiagramVariant; + presence?: SocratesPresence; +} + +export function EditorShell({ + data, + density = "comfortable", + markupStyle = "color", + diagramStyle = "softened", + presence = "default", +}: EditorShellProps) { + const [focusBlockId, setFocusBlockId] = useState(null); + + return ( +
+ + +
+ + + +
+
+ +
+ +
+
+ +
+ +
+ + Fit + 100% + Layout +
+ } + /> +
+ +
+ +
+
+ + +
+ ); +} diff --git a/apps/web/components/editor/LeftRail.tsx b/apps/web/components/editor/LeftRail.tsx new file mode 100644 index 0000000..c76d741 --- /dev/null +++ b/apps/web/components/editor/LeftRail.tsx @@ -0,0 +1,140 @@ +// Outline / Model / Requirements sections, each independently collapsible. +// The whole rail can also collapse to a 36px vertical strip. +// Ported from docs/design-source/socrata/project/editor-shell.jsx (LeftRail). + +"use client"; + +import { useState } from "react"; +import type { FixtureData } from "../../lib/fixtures/aristotle"; + +interface LeftRailProps { + data: FixtureData; + focusBlockId: string | null; + setFocusBlockId: (id: string | null) => void; +} + +export function LeftRail({ data, focusBlockId, setFocusBlockId }: LeftRailProps) { + const [collapsed, setCollapsed] = useState(false); + const [open, setOpen] = useState({ outline: true, model: true, requirements: true }); + const toggle = (k: keyof typeof open) => setOpen(s => ({ ...s, [k]: !s[k] })); + + if (collapsed) { + return ( + + ); + } + + return ( + + ); +} diff --git a/apps/web/components/editor/StatusBar.tsx b/apps/web/components/editor/StatusBar.tsx new file mode 100644 index 0000000..6c6f201 --- /dev/null +++ b/apps/web/components/editor/StatusBar.tsx @@ -0,0 +1,20 @@ +// Bottom status bar with version + summary + owner. +// Ported from docs/design-source/socrata/project/editor-shell.jsx (statusbar block). + +import type { FixtureData } from "../../lib/fixtures/aristotle"; + +interface StatusBarProps { + data: FixtureData; +} + +export function StatusBar({ data }: StatusBarProps) { + return ( +
+ Socrata · v0.4 · Phase 1 + + 3 assumptions open · 2 risks tracked · 1 proposal pending + + {data.project.owner} +
+ ); +} diff --git a/apps/web/components/editor/TopBar.tsx b/apps/web/components/editor/TopBar.tsx new file mode 100644 index 0000000..b8e0f2a --- /dev/null +++ b/apps/web/components/editor/TopBar.tsx @@ -0,0 +1,36 @@ +// Top-level brand row: name + breadcrumbs on the left, sync pill + avatar on the right. +// Ported from docs/design-source/socrata/project/editor-shell.jsx (TopBar). + +import type { FixtureData } from "../../lib/fixtures/aristotle"; + +interface TopBarProps { + data: FixtureData; +} + +export function TopBar({ data }: TopBarProps) { + return ( +
+
+
+ Socrata +
+
+ / + {data.project.scope} + / + {data.project.name} + + {data.project.branch} + +
+
+
+
+ model in sync · {data.project.lastSync} +
+
+
MC
+
+
+ ); +} diff --git a/apps/web/components/seed/SeedScreen.tsx b/apps/web/components/seed/SeedScreen.tsx new file mode 100644 index 0000000..dd7835d --- /dev/null +++ b/apps/web/components/seed/SeedScreen.tsx @@ -0,0 +1,185 @@ +// Seed onboarding screen — two-column layout: emerging-seed rail (left) + Socrates conversation (right). +// Ported from docs/design-source/socrata/project/seed-screen.jsx. + +import { Sigil } from "../socrates/Sigil"; + +interface SeedField { + key: string; + label: string; + value: string; + inferred?: boolean; +} + +interface ThreadTurn { + who: "socrates" | "user"; + text: string; +} + +const fields: SeedField[] = [ + { + key: "problem", + label: "Problem", + value: "First-year STEM students disengage in the long tail between lectures and office hours; a self-efficacy gap forms quickly.", + }, + { + key: "user", + label: "Target user", + value: "Undergraduates at large public universities, weeks 3–10 of an intro course.", + }, + { + key: "outcome", + label: "Desired outcome", + value: "Students re-engage with material via a low-stakes thinking partner — without producing solutions.", + }, + { + key: "hypothesis", + label: "Initial hypothesis", + value: "Students will adopt a tool that explicitly refuses to solve their homework.", + inferred: true, + }, + { + key: "constraint", + label: "Constraint", + value: "FERPA tenancy, P50 < 1.2s.", + inferred: true, + }, +]; + +const thread: ThreadTurn[] = [ + { + who: "socrates", + text: "Welcome. I'm Socrates. Before we model anything, let me understand what you're really proposing. In one sentence — what is the smallest, most honest version of the problem?", + }, + { + who: "user", + text: "Students disengage between lectures because they have nobody to think with at 11pm.", + }, + { + who: "socrates", + text: "Good. Two follow-ups. First, who specifically — and why now? Second, when you say 'think with', do you mean a tutor that explains, or a partner that asks? These are quite different products.", + }, + { + who: "user", + text: "Public-university undergrads, weeks 3–10. A partner that asks. The market is saturated with explainers.", + }, + { + who: "socrates", + text: "Then the central tension is restraint: a tool that holds its tongue. Most LLM products are rewarded for being helpful. Yours will be rewarded for being patient. Should I draft this as a Constraint on the model — refusal_policy : single-valued — and surface it for your review?", + }, +]; + +export function SeedScreen() { + return ( +
+
+
+ + Socrata + · + Seed · forming +
+
+ Interview + Form +
+
+ +
+ {/* Left: emerging seed */} +
+
Emerging seed
+
+ {fields.map(f => ( +
+
+ {f.label} + {f.inferred && inferred · 0.74} +
+
{f.value}
+
+ ))} +
+ +
Initial model · drafting
+
+
+ «block» + Student + self_efficacy +
+
+
+ «block» + Aristotle + refusal_policy + interaction_style +
+
+
+ «constraint» + FERPA boundary +
+
+ +
+
+ Model confidence + 0.62 +
+
+
+
+
+ Three more clarifying questions should bring this above 0.80. +
+
+
+ + {/* Right: Socrates conversation */} +
+
+ {thread.map((m, i) => ( +
+ {m.who === "socrates" && ( +
+ +
+ )} +
+
{m.who === "socrates" ? "Socrates" : "You"}
+
{m.text}
+
+
+ ))} + +
+
+ +
+
+
Socrates
+
+ drafting next question +
+
+
+
+ +
+
+ + + Public-university undergrads, weeks 3–10. A partner that asks. The market is saturated with explainers. + + +
+
+ + +
+
+
+
+
+ ); +} diff --git a/apps/web/components/socrates/Sigil.tsx b/apps/web/components/socrates/Sigil.tsx new file mode 100644 index 0000000..ea87c02 --- /dev/null +++ b/apps/web/components/socrates/Sigil.tsx @@ -0,0 +1,42 @@ +// Σ inside a softened laurel, themed via CSS variables. +// Ported from docs/design-source/socrata/project/socrates.jsx (SocratesSigil). + +interface SigilProps { + size?: number; + mood?: "thinking" | "still"; +} + +export function Sigil({ size = 44, mood = "thinking" }: SigilProps) { + return ( +
+ + + + + + + + + + {/* Laurel */} + + + {/* Σ */} + + Σ + + {mood === "thinking" && ( + + )} + +
+ ); +} diff --git a/apps/web/components/socrates/SocratesDock.tsx b/apps/web/components/socrates/SocratesDock.tsx new file mode 100644 index 0000000..f950167 --- /dev/null +++ b/apps/web/components/socrates/SocratesDock.tsx @@ -0,0 +1,82 @@ +// Active-thread dock with Sigil header, conversation bubbles, numbered options. +// Ported from docs/design-source/socrata/project/socrates.jsx (SocratesDock). +// "subtle" presence renders a floating sigil + count badge. + +import { Sigil } from "./Sigil"; +import type { FixtureSocratesTurn } from "../../lib/fixtures/aristotle"; + +export type SocratesPresence = "subtle" | "default" | "prominent"; +export type Density = "comfortable" | "compact"; + +interface SocratesDockProps { + thread: FixtureSocratesTurn[]; + presence: SocratesPresence; + density: Density; +} + +export function SocratesDock({ thread, presence }: SocratesDockProps) { + if (presence === "subtle") { + return ( +
+ +
3
+
+ ); + } + + return ( + + ); +} diff --git a/apps/web/components/text-canvas/Chip.tsx b/apps/web/components/text-canvas/Chip.tsx new file mode 100644 index 0000000..b2c8b0e --- /dev/null +++ b/apps/web/components/text-canvas/Chip.tsx @@ -0,0 +1,71 @@ +// Inline chip referencing a model element. +// Renders four visual styles via CSS (pill / color / underline / bracket). +// Ported from docs/design-source/socrata/project/text-canvas.jsx (Chip). +// M1: static. M2: becomes a TipTap node-view. + +import type { ChipKind } from "../../lib/fixtures/aristotle"; + +export type MarkupStyle = "pill" | "color" | "underline" | "bracket"; + +const KIND_LABEL: Record = { + block: "block", + property: "property", + association: "assoc", + requirement: "req", +}; + +function kindGlyph(kind: ChipKind): string { + switch (kind) { + case "block": return "▢"; + case "property": return "·"; + case "association": return "→"; + case "requirement": return "§"; + } +} + +interface ChipProps { + kind: ChipKind; + id: string; + label: string; + markupStyle: MarkupStyle; + focused?: boolean; + onHover?: (id: string | null) => void; + onClick?: (id: string, kind: ChipKind) => void; +} + +export function Chip({ kind, id, label, markupStyle, focused, onHover, onClick }: ChipProps) { + const cls = `chip chip-${kind} chip-style-${markupStyle}${focused ? " chip-focus" : ""}`; + const handlers = { + onMouseEnter: () => onHover?.(id), + onMouseLeave: () => onHover?.(null), + onClick: () => onClick?.(id, kind), + }; + + if (markupStyle === "bracket") { + return ( + + [ + {KIND_LABEL[kind]}: + {label} + ] + + ); + } + + if (markupStyle === "underline") { + return ( + + {kindGlyph(kind)} + {label} + + ); + } + + // pill (default) and color both render as filled chips. + return ( + + {kindGlyph(kind)} + {label} + + ); +} diff --git a/apps/web/components/text-canvas/ChipNode.ts b/apps/web/components/text-canvas/ChipNode.ts new file mode 100644 index 0000000..cf4eb99 --- /dev/null +++ b/apps/web/components/text-canvas/ChipNode.ts @@ -0,0 +1,82 @@ +// TipTap node definition for inline model-element chips. +// +// M2: chips are inline, atomic, selectable. They carry { kind, refId, label }. +// In MVP M5 the label will be derived from a live model lookup keyed by refId; +// for M2 we store it directly on the node so renaming + persistence Just Work. + +import { Node, mergeAttributes } from "@tiptap/core"; +import { ReactNodeViewRenderer } from "@tiptap/react"; +import type { ChipKind } from "../../lib/fixtures/aristotle"; +import { ChipView } from "./ChipView"; + +export interface ChipAttrs { + kind: ChipKind; + refId: string | null; + label: string; +} + +declare module "@tiptap/core" { + interface Commands { + chip: { + insertChip: (attrs: ChipAttrs) => ReturnType; + }; + } +} + +export const ChipNode = Node.create({ + name: "chip", + group: "inline", + inline: true, + atom: true, + selectable: true, + draggable: false, + + addAttributes() { + return { + kind: { + default: "block", + parseHTML: el => el.getAttribute("data-kind") ?? "block", + renderHTML: attrs => ({ "data-kind": attrs.kind }), + }, + refId: { + default: null, + parseHTML: el => el.getAttribute("data-ref-id"), + renderHTML: attrs => (attrs.refId ? { "data-ref-id": attrs.refId } : {}), + }, + label: { + default: "untitled", + parseHTML: el => el.getAttribute("data-label") ?? el.textContent ?? "untitled", + renderHTML: attrs => ({ "data-label": attrs.label }), + }, + }; + }, + + parseHTML() { + return [{ tag: "span[data-chip]" }]; + }, + + renderHTML({ HTMLAttributes, node }) { + return [ + "span", + mergeAttributes({ "data-chip": "" }, HTMLAttributes), + `${node.attrs.label}`, + ]; + }, + + addNodeView() { + return ReactNodeViewRenderer(ChipView); + }, + + addCommands() { + return { + insertChip: + (attrs: ChipAttrs) => + ({ chain }) => + chain() + .insertContent({ type: this.name, attrs }) + // Insert a trailing space so the caret leaves the chip cleanly + .insertContent(" ") + .run(), + }; + }, +}); diff --git a/apps/web/components/text-canvas/ChipView.tsx b/apps/web/components/text-canvas/ChipView.tsx new file mode 100644 index 0000000..7d343d3 --- /dev/null +++ b/apps/web/components/text-canvas/ChipView.tsx @@ -0,0 +1,73 @@ +// React NodeView for the chip TipTap node. +// Renders identically to the static Chip via the same CSS classes. + +"use client"; + +import { NodeViewWrapper } from "@tiptap/react"; +import type { NodeViewProps } from "@tiptap/react"; +import type { ChipKind } from "../../lib/fixtures/aristotle"; +import type { MarkupStyle } from "./Chip"; +import { useChipFocus } from "./FocusContext"; + +const KIND_LABEL: Record = { + block: "block", + property: "property", + association: "assoc", + requirement: "req", +}; + +function kindGlyph(kind: ChipKind): string { + switch (kind) { + case "block": return "▢"; + case "property": return "·"; + case "association": return "→"; + case "requirement": return "§"; + } +} + +export function ChipView({ node, selected, editor }: NodeViewProps) { + const kind = (node.attrs.kind as ChipKind) ?? "block"; + const label = (node.attrs.label as string) ?? "untitled"; + const refId = (node.attrs.refId as string | null) ?? null; + // Read the current markup style from the editor's storage; defaults to "color". + const markupStyle = ((editor.storage as Record).markupStyle as MarkupStyle) ?? "color"; + + const { focusBlockId, setFocusBlockId } = useChipFocus(); + const isFocused = (refId !== null && refId === focusBlockId) || selected; + + const cls = `chip chip-${kind} chip-style-${markupStyle}${isFocused ? " chip-focus" : ""}`; + const handlers = refId + ? { + onMouseEnter: () => setFocusBlockId(refId), + onMouseLeave: () => setFocusBlockId(null), + onClick: () => setFocusBlockId(refId), + } + : {}; + + if (markupStyle === "bracket") { + return ( + + [ + {KIND_LABEL[kind]}: + {label} + ] + + ); + } + + if (markupStyle === "underline") { + return ( + + {kindGlyph(kind)} + {label} + + ); + } + + return ( + + {kindGlyph(kind)} + {label} + + ); +} diff --git a/apps/web/components/text-canvas/FocusContext.tsx b/apps/web/components/text-canvas/FocusContext.tsx new file mode 100644 index 0000000..016d56f --- /dev/null +++ b/apps/web/components/text-canvas/FocusContext.tsx @@ -0,0 +1,23 @@ +// React context for cross-canvas focus state. +// +// The chip node views are mounted via TipTap's ReactNodeViewRenderer; they +// can't reach into props on the editor instance, but they can use React +// Context (it propagates through any React tree, including TipTap's). + +"use client"; + +import { createContext, useContext } from "react"; + +export interface ChipFocusValue { + focusBlockId: string | null; + setFocusBlockId: (id: string | null) => void; +} + +export const ChipFocusContext = createContext({ + focusBlockId: null, + setFocusBlockId: () => {}, +}); + +export function useChipFocus(): ChipFocusValue { + return useContext(ChipFocusContext); +} diff --git a/apps/web/components/text-canvas/SlashExtension.ts b/apps/web/components/text-canvas/SlashExtension.ts new file mode 100644 index 0000000..96de037 --- /dev/null +++ b/apps/web/components/text-canvas/SlashExtension.ts @@ -0,0 +1,20 @@ +// TipTap extension wrapping the slash-menu suggestion plugin. + +"use client"; + +import { Extension } from "@tiptap/core"; +import Suggestion from "@tiptap/suggestion"; +import { slashSuggestion } from "./slashSuggestion"; + +export const SlashExtension = Extension.create({ + name: "slashMenu", + + addProseMirrorPlugins() { + return [ + Suggestion({ + editor: this.editor, + ...slashSuggestion, + }), + ]; + }, +}); diff --git a/apps/web/components/text-canvas/SlashMenu.tsx b/apps/web/components/text-canvas/SlashMenu.tsx new file mode 100644 index 0000000..c8d261d --- /dev/null +++ b/apps/web/components/text-canvas/SlashMenu.tsx @@ -0,0 +1,110 @@ +// Slash menu — appears when the user types `/`. Shows the four chip kinds. +// On selection, inserts a chip with a placeholder label that the user can +// then rename inline. + +"use client"; + +import { useEffect, useImperativeHandle, useState, forwardRef } from "react"; +import type { ChipKind } from "../../lib/fixtures/aristotle"; + +export interface SlashItem { + kind: ChipKind; + label: string; + hint: string; + glyph: string; +} + +export const SLASH_ITEMS: SlashItem[] = [ + { kind: "block", label: "Block", hint: "an entity in the system", glyph: "▢" }, + { kind: "property", label: "Property", hint: "an attribute of a block", glyph: "·" }, + { kind: "association", label: "Association", hint: "a relationship", glyph: "→" }, + { kind: "requirement", label: "Requirement", hint: "a stated goal (REQ-NNN)", glyph: "§" }, +]; + +export interface SlashMenuHandle { + onKeyDown: (event: KeyboardEvent) => boolean; +} + +interface SlashMenuProps { + query: string; + command: (item: SlashItem) => void; +} + +export const SlashMenu = forwardRef(function SlashMenu( + { query, command }, + ref +) { + const filtered = SLASH_ITEMS.filter( + item => + query.length === 0 || + item.kind.toLowerCase().startsWith(query.toLowerCase()) || + item.label.toLowerCase().startsWith(query.toLowerCase()) + ); + const [activeIndex, setActiveIndex] = useState(0); + + useEffect(() => { + setActiveIndex(0); + }, [query]); + + useImperativeHandle(ref, () => ({ + onKeyDown(event: KeyboardEvent) { + if (filtered.length === 0) return false; + if (event.key === "ArrowUp") { + setActiveIndex(prev => (prev - 1 + filtered.length) % filtered.length); + return true; + } + if (event.key === "ArrowDown") { + setActiveIndex(prev => (prev + 1) % filtered.length); + return true; + } + if (event.key === "Enter" || event.key === "Tab") { + const choice = filtered[activeIndex]; + if (choice) { + command(choice); + return true; + } + } + // Number-key shortcut: 1–4 picks the corresponding item + const num = parseInt(event.key, 10); + if (!Number.isNaN(num) && num >= 1 && num <= filtered.length) { + const choice = filtered[num - 1]; + if (choice) { + command(choice); + return true; + } + } + return false; + }, + })); + + if (filtered.length === 0) { + return ( +
+ no matches for “{query}” +
+ ); + } + + return ( +
+ {filtered.map((item, idx) => ( + + ))} +
+ ); +}); diff --git a/apps/web/components/text-canvas/TextCanvas.tsx b/apps/web/components/text-canvas/TextCanvas.tsx new file mode 100644 index 0000000..47c242b --- /dev/null +++ b/apps/web/components/text-canvas/TextCanvas.tsx @@ -0,0 +1,94 @@ +// TipTap-backed narrative editor. +// Renders the same prose surface as the static port, but typing actually works +// and chips can be inserted via the slash menu (`/block`, `/property`, etc.). + +"use client"; + +import { useEditor, EditorContent } from "@tiptap/react"; +import StarterKit from "@tiptap/starter-kit"; +import { useEffect, useMemo } from "react"; +import { ChipNode } from "./ChipNode"; +import { SlashExtension } from "./SlashExtension"; +import { ChipFocusContext } from "./FocusContext"; +import { fixtureToDoc } from "./fixtureToDoc"; +import type { Density } from "../socrates/SocratesDock"; +import type { FixtureData } from "../../lib/fixtures/aristotle"; +import type { MarkupStyle } from "./Chip"; + +interface TextCanvasProps { + data: FixtureData; + density: Density; + markupStyle: MarkupStyle; + focusBlockId: string | null; + setFocusBlockId: (id: string | null) => void; +} + +export function TextCanvas({ data, density, markupStyle, focusBlockId, setFocusBlockId }: TextCanvasProps) { + const padY = density === "compact" ? 10 : 18; + const padX = density === "compact" ? 22 : 36; + const focusValue = useMemo( + () => ({ focusBlockId, setFocusBlockId }), + [focusBlockId, setFocusBlockId] + ); + + const editor = useEditor({ + immediatelyRender: false, + extensions: [ + StarterKit.configure({ + heading: { levels: [1, 2] }, + // Drop features we don't need yet + codeBlock: false, + blockquote: false, + horizontalRule: false, + bulletList: false, + orderedList: false, + listItem: false, + strike: false, + code: false, + link: false, + }), + ChipNode, + SlashExtension, + ], + content: fixtureToDoc(data), + editorProps: { + attributes: { + class: "text-canvas tiptap", + style: `padding: ${padY}px ${padX}px;`, + }, + }, + }); + + // Push the markup style into the editor so the ChipView NodeView can read it. + useEffect(() => { + if (!editor) return; + (editor.storage as Record).markupStyle = markupStyle; + // Force a re-render of all chip node views so they pick up the new style. + editor.view.dispatch(editor.state.tr.setMeta("force-update", true)); + }, [editor, markupStyle]); + + if (!editor) { + return ( +
+
+ loading editor… +
+
+ ); + } + + return ( + + +
+ Σ + + Socrates · margin + + “Refuses to produce solutions” is a strong constraint. Have you decided what counts as a “solution” vs. a “scaffold”? This boundary will determine whether the refusal policy is enforceable. + + +
+
+ ); +} diff --git a/apps/web/components/text-canvas/fixtureToDoc.ts b/apps/web/components/text-canvas/fixtureToDoc.ts new file mode 100644 index 0000000..5e02212 --- /dev/null +++ b/apps/web/components/text-canvas/fixtureToDoc.ts @@ -0,0 +1,43 @@ +// Convert the fixture's narrative shape to a ProseMirror document JSON. +// Used as the initial content for the TipTap editor. + +import type { JSONContent } from "@tiptap/react"; +import type { FixtureData, NarrativeNode } from "../../lib/fixtures/aristotle"; + +export function fixtureToDoc(data: FixtureData): JSONContent { + const content: JSONContent[] = data.narrative.map(node => narrativeNodeToJSON(node)); + return { + type: "doc", + content, + }; +} + +function narrativeNodeToJSON(node: NarrativeNode): JSONContent { + if (node.type === "h1") { + return { + type: "heading", + attrs: { level: 1 }, + content: node.text ? [{ type: "text", text: node.text }] : [], + }; + } + if (node.type === "h2") { + return { + type: "heading", + attrs: { level: 2 }, + content: node.text ? [{ type: "text", text: node.text }] : [], + }; + } + // paragraph + const inline: JSONContent[] = []; + for (const child of node.children ?? []) { + if (child.t === "text") { + inline.push({ type: "text", text: child.v }); + } else if (child.t === "chip") { + inline.push({ + type: "chip", + attrs: { kind: child.kind, refId: child.id, label: child.label }, + }); + } + } + return { type: "paragraph", content: inline }; +} diff --git a/apps/web/components/text-canvas/slashSuggestion.ts b/apps/web/components/text-canvas/slashSuggestion.ts new file mode 100644 index 0000000..f61f5e8 --- /dev/null +++ b/apps/web/components/text-canvas/slashSuggestion.ts @@ -0,0 +1,92 @@ +// Suggestion plugin config that wires the slash menu into TipTap. +// Renders SlashMenu in a fixed-position floating panel near the caret. + +"use client"; + +import type { Editor, Range } from "@tiptap/core"; +import type { SuggestionOptions, SuggestionProps, SuggestionKeyDownProps } from "@tiptap/suggestion"; +import { createRoot, type Root } from "react-dom/client"; +import { createElement, createRef } from "react"; +import { SlashMenu, SLASH_ITEMS, type SlashItem, type SlashMenuHandle } from "./SlashMenu"; + +export const slashSuggestion: Omit, "editor"> = { + char: "/", + startOfLine: false, + allowSpaces: false, + + items: ({ query }) => + SLASH_ITEMS.filter( + item => + query.length === 0 || + item.kind.toLowerCase().startsWith(query.toLowerCase()) || + item.label.toLowerCase().startsWith(query.toLowerCase()) + ), + + command: ({ editor, range, props }: { editor: Editor; range: Range; props: SlashItem }) => { + editor + .chain() + .focus() + .deleteRange(range) + .insertChip({ + kind: props.kind, + refId: null, + label: props.kind === "requirement" ? "REQ-001" : "untitled", + }) + .run(); + }, + + render: () => { + let container: HTMLDivElement | null = null; + let root: Root | null = null; + const handleRef = createRef(); + + function position(rect: DOMRect | null) { + if (!container || !rect) return; + container.style.position = "fixed"; + container.style.top = `${rect.bottom + 6}px`; + container.style.left = `${rect.left}px`; + container.style.zIndex = "1000"; + } + + function rerender(props: SuggestionProps) { + if (!root) return; + root.render( + createElement(SlashMenu, { + ref: handleRef, + query: props.query, + command: (item: SlashItem) => props.command(item), + }) + ); + } + + return { + onStart(props) { + container = document.createElement("div"); + document.body.appendChild(container); + root = createRoot(container); + rerender(props); + position(props.clientRect?.() ?? null); + }, + + onUpdate(props) { + rerender(props); + position(props.clientRect?.() ?? null); + }, + + onKeyDown(props: SuggestionKeyDownProps) { + if (props.event.key === "Escape") { + props.event.preventDefault(); + return true; + } + return handleRef.current?.onKeyDown(props.event) ?? false; + }, + + onExit() { + if (root) root.unmount(); + if (container && container.parentNode) container.parentNode.removeChild(container); + root = null; + container = null; + }, + }; + }, +}; diff --git a/apps/web/eslint.config.mjs b/apps/web/eslint.config.mjs new file mode 100644 index 0000000..05e726d --- /dev/null +++ b/apps/web/eslint.config.mjs @@ -0,0 +1,18 @@ +import { defineConfig, globalIgnores } from "eslint/config"; +import nextVitals from "eslint-config-next/core-web-vitals"; +import nextTs from "eslint-config-next/typescript"; + +const eslintConfig = defineConfig([ + ...nextVitals, + ...nextTs, + // Override default ignores of eslint-config-next. + globalIgnores([ + // Default ignores of eslint-config-next: + ".next/**", + "out/**", + "build/**", + "next-env.d.ts", + ]), +]); + +export default eslintConfig; diff --git a/apps/web/lib/fixtures/aristotle.ts b/apps/web/lib/fixtures/aristotle.ts new file mode 100644 index 0000000..bb5eacf --- /dev/null +++ b/apps/web/lib/fixtures/aristotle.ts @@ -0,0 +1,202 @@ +// Sample project content — a realistic PM idea: an AI study companion for university students. +// Ported from docs/design-source/socrata/project/data.js. +// Used to populate the textual narrative + diagram during M1's static visual port. + +export type ChipKind = "block" | "property" | "association" | "requirement"; + +export interface ChipToken { + t: "chip"; + kind: ChipKind; + id: string; + label: string; +} + +export interface TextToken { + t: "text"; + v: string; +} + +export type NarrativeInline = ChipToken | TextToken; + +export interface NarrativeNode { + type: "h1" | "h2" | "p"; + text?: string; + children?: NarrativeInline[]; +} + +export type BlockKind = "block" | "actor" | "constraint"; + +export interface FixtureBlock { + id: string; + label: string; + kind: BlockKind; + /** Position normalized to a 720×460 board (matches diagram.jsx). */ + x: number; + y: number; + w: number; + h: number; + properties: string[]; +} + +export type AssociationKind = "association" | "composition" | "constraint"; + +export interface FixtureAssociation { + id: string; + from: string; + to: string; + label: string; + kind: AssociationKind; +} + +export interface FixtureAssumption { + id: string; + text: string; + status: "open" | "validated" | "invalidated"; + linked: string[]; +} + +export interface FixtureRisk { + id: string; + text: string; + severity: "low" | "med" | "high"; + linked: string[]; +} + +export interface FixtureSocratesTurn { + who: "socrates" | "user"; + text: string; + options?: Array<{ n: number; label: string; sub: string }>; +} + +export interface FixtureProposal { + title: string; + impactedBlocks: string[]; + addedConstraints: number; + affectedRequirements: string[]; + iteration: number; +} + +export interface FixtureData { + project: { + name: string; + tagline: string; + scope: string; + owner: string; + branch: string; + lastSync: string; + }; + narrative: NarrativeNode[]; + blocks: FixtureBlock[]; + associations: FixtureAssociation[]; + assumptions: FixtureAssumption[]; + risks: FixtureRisk[]; + socratesThread: FixtureSocratesTurn[]; + proposal: FixtureProposal; +} + +export const aristotleFixture: FixtureData = { + project: { + name: "Aristotle", + tagline: "AI study companion for first-year STEM students", + scope: "Higher education · undergraduate", + owner: "M. Chen · PM", + branch: "main", + lastSync: "2 min ago", + }, + narrative: [ + { type: "h1", text: "Problem framing" }, + { + type: "p", + children: [ + { t: "text", v: "First-year STEM students at large public universities frequently disengage from coursework not because the material is intractable, but because the " }, + { t: "chip", kind: "block", id: "student", label: "Student" }, + { t: "text", v: " lacks a low-stakes thinking partner during the long tail between lectures and office hours. The " }, + { t: "chip", kind: "block", id: "course", label: "Course" }, + { t: "text", v: " produces problem sets that assume mastery of prerequisite scaffolding, and a " }, + { t: "chip", kind: "property", id: "selfEfficacy", label: "self_efficacy" }, + { t: "text", v: " gap forms quickly." }, + ], + }, + { + type: "p", + children: [ + { t: "text", v: "Aristotle is a study companion that " }, + { t: "chip", kind: "association", id: "guides", label: "guides" }, + { t: "text", v: " the student through Socratic prompts rather than answers, scoped to their current " }, + { t: "chip", kind: "block", id: "assignment", label: "Assignment" }, + { t: "text", v: ". It refuses to produce solutions; it only produces questions calibrated to a student's evolving understanding." }, + ], + }, + { type: "h2", text: "Constraints" }, + { + type: "p", + children: [ + { t: "chip", kind: "requirement", id: "REQ-001", label: "REQ-001" }, + { t: "text", v: " The companion must never output a complete solution to a graded problem. " }, + { t: "chip", kind: "requirement", id: "REQ-002", label: "REQ-002" }, + { t: "text", v: " Response latency under 1.2s P50 to preserve flow. " }, + { t: "chip", kind: "requirement", id: "REQ-003", label: "REQ-003" }, + { t: "text", v: " Operates within FERPA boundaries; coursework never leaves institutional tenancy." }, + ], + }, + { type: "h2", text: "Why now" }, + { + type: "p", + children: [ + { t: "text", v: "Two large public-university pilots indicated that students would adopt a tool that explicitly does not solve their homework — an inversion of the prevailing market." }, + ], + }, + ], + blocks: [ + { id: "student", label: "Student", kind: "block", x: 0.10, y: 0.18, w: 168, h: 96, + properties: ["self_efficacy", "course_load", "prior_grade"] }, + { id: "aristotle", label: "Aristotle", kind: "block", x: 0.42, y: 0.18, w: 184, h: 110, + properties: ["interaction_style", "scope_window", "refusal_policy"] }, + { id: "course", label: "Course", kind: "block", x: 0.74, y: 0.10, w: 168, h: 96, + properties: ["syllabus", "prerequisites"] }, + { id: "assignment", label: "Assignment", kind: "block", x: 0.74, y: 0.58, w: 168, h: 96, + properties: ["due_at", "rubric", "graded"] }, + { id: "instructor", label: "Instructor", kind: "actor", x: 0.10, y: 0.62, w: 144, h: 76, + properties: ["policy_set"] }, + { id: "ferpa", label: "FERPA boundary", kind: "constraint", x: 0.42, y: 0.66, w: 184, h: 72, + properties: [] }, + ], + associations: [ + { id: "a1", from: "student", to: "aristotle", label: "consults", kind: "association" }, + { id: "a2", from: "aristotle", to: "assignment", label: "scoped_to", kind: "association" }, + { id: "a3", from: "course", to: "assignment", label: "contains", kind: "composition" }, + { id: "a4", from: "instructor", to: "aristotle", label: "configures", kind: "association" }, + { id: "a5", from: "aristotle", to: "ferpa", label: "obeys", kind: "constraint" }, + { id: "a6", from: "student", to: "course", label: "enrolled_in", kind: "association" }, + ], + assumptions: [ + { id: "ASM-1", text: "Students will accept a tool that refuses to give answers", status: "open", linked: ["aristotle"] }, + { id: "ASM-2", text: "Faculty will not classify Socratic prompts as academic dishonesty", status: "validated", linked: ["aristotle", "instructor"] }, + { id: "ASM-3", text: "1.2s P50 latency is achievable with on-prem inference", status: "open", linked: ["aristotle"] }, + ], + risks: [ + { id: "RSK-1", text: "Refusal policy circumvented via prompt injection", severity: "high", linked: ["aristotle"] }, + { id: "RSK-2", text: "FERPA tenancy adds 4–6 weeks of procurement per institution", severity: "med", linked: ["ferpa"] }, + ], + socratesThread: [ + { who: "socrates", text: "You've defined Aristotle as scoped to a single Assignment. What happens when a student wants to compare techniques across two assignments — does the scope expand, or does the student switch contexts?" }, + { who: "user", text: "Switch contexts. We don't want cross-assignment leakage of solution patterns." }, + { who: "socrates", text: "Good. That decision has an implication: the property scope_window on Aristotle becomes single-valued, and we may want a Constraint that forbids cross-Assignment retrieval. Should I draft that as a proposal?" }, + { + who: "socrates", + text: "Given the context-switch decision, three things follow. Pick where to go next:", + options: [ + { n: 1, label: "Draft the constraint", sub: "no cross-Assignment retrieval" }, + { n: 2, label: "Revisit scope_window", sub: "single-valued vs. multi-valued" }, + { n: 3, label: "Park it", sub: "I'll come back later" }, + ], + }, + ], + proposal: { + title: "Add constraint: no cross-Assignment retrieval", + impactedBlocks: ["aristotle", "assignment"], + addedConstraints: 1, + affectedRequirements: ["REQ-001"], + iteration: 2, + }, +}; diff --git a/apps/web/next.config.ts b/apps/web/next.config.ts new file mode 100644 index 0000000..e9ffa30 --- /dev/null +++ b/apps/web/next.config.ts @@ -0,0 +1,7 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + /* config options here */ +}; + +export default nextConfig; diff --git a/apps/web/package.json b/apps/web/package.json new file mode 100644 index 0000000..42923b7 --- /dev/null +++ b/apps/web/package.json @@ -0,0 +1,31 @@ +{ + "name": "web", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "eslint" + }, + "dependencies": { + "@tiptap/core": "^3.22.5", + "@tiptap/extension-mention": "^3.22.5", + "@tiptap/pm": "^3.22.5", + "@tiptap/react": "^3.22.5", + "@tiptap/starter-kit": "^3.22.5", + "@tiptap/suggestion": "^3.22.5", + "@xyflow/react": "^12.10.2", + "next": "16.2.4", + "react": "19.2.4", + "react-dom": "19.2.4" + }, + "devDependencies": { + "@types/node": "^20", + "@types/react": "^19", + "@types/react-dom": "^19", + "eslint": "^9", + "eslint-config-next": "16.2.4", + "typescript": "^5" + } +} diff --git a/apps/web/pnpm-lock.yaml b/apps/web/pnpm-lock.yaml new file mode 100644 index 0000000..172a0f4 --- /dev/null +++ b/apps/web/pnpm-lock.yaml @@ -0,0 +1,4403 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@tiptap/core': + specifier: ^3.22.5 + version: 3.22.5(@tiptap/pm@3.22.5) + '@tiptap/extension-mention': + specifier: ^3.22.5 + version: 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)(@tiptap/suggestion@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)) + '@tiptap/pm': + specifier: ^3.22.5 + version: 3.22.5 + '@tiptap/react': + specifier: ^3.22.5 + version: 3.22.5(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + '@tiptap/starter-kit': + specifier: ^3.22.5 + version: 3.22.5 + '@tiptap/suggestion': + specifier: ^3.22.5 + version: 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + '@xyflow/react': + specifier: ^12.10.2 + version: 12.10.2(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + next: + specifier: 16.2.4 + version: 16.2.4(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4) + react: + specifier: 19.2.4 + version: 19.2.4 + react-dom: + specifier: 19.2.4 + version: 19.2.4(react@19.2.4) + devDependencies: + '@types/node': + specifier: ^20 + version: 20.19.39 + '@types/react': + specifier: ^19 + version: 19.2.14 + '@types/react-dom': + specifier: ^19 + version: 19.2.3(@types/react@19.2.14) + eslint: + specifier: ^9 + version: 9.39.4 + eslint-config-next: + specifier: 16.2.4 + version: 16.2.4(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + typescript: + specifier: ^5 + version: 5.9.3 + +packages: + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.0': + resolution: {integrity: sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.2': + resolution: {integrity: sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} + + '@floating-ui/dom@1.7.6': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} + + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@next/env@16.2.4': + resolution: {integrity: sha512-dKkkOzOSwFYe5RX6y26fZgkSpVAlIOJKQHIiydQcrWH6y/97+RceSOAdjZ14Qa3zLduVUy0TXcn+EiM6t4rPgw==} + + '@next/eslint-plugin-next@16.2.4': + resolution: {integrity: sha512-tOX826JJ96gYK/go18sPUgMq9FK1tqxBFfUCEufJb5XIkWFFmpgU7mahJANKGkHs7F41ir3tReJ3Lv5La0RvhA==} + + '@next/swc-darwin-arm64@16.2.4': + resolution: {integrity: sha512-OXTFFox5EKN1Ym08vfrz+OXxmCcEjT4SFMbNRsWZE99dMqt2Kcusl5MqPXcW232RYkMLQTy0hqgAMEsfEd/l2A==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@16.2.4': + resolution: {integrity: sha512-XhpVnUfmYWvD3YrXu55XdcAkQtOnvaI6wtQa8fuF5fGoKoxIUZ0kWPtcOfqJEWngFF/lOS9l3+O9CcownhiQxQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@16.2.4': + resolution: {integrity: sha512-Mx/tjlNA3G8kg14QvuGAJ4xBwPk1tUHq56JxZ8CXnZwz1Etz714soCEzGQQzVMz4bEnGPowzkV6Xrp6wAkEWOQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@16.2.4': + resolution: {integrity: sha512-iVMMp14514u7Nup2umQS03nT/bN9HurK8ufylC3FZNykrwjtx7V1A7+4kvhbDSCeonTVqV3Txnv0Lu+m2oDXNg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@16.2.4': + resolution: {integrity: sha512-EZOvm1aQWgnI/N/xcWOlnS3RQBk0VtVav5Zo7n4p0A7UKyTDx047k8opDbXgBpHl4CulRqRfbw3QrX2w5UOXMQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@16.2.4': + resolution: {integrity: sha512-h9FxsngCm9cTBf71AR4fGznDEDx1hS7+kSEiIRjq5kO1oXWm07DxVGZjCvk0SGx7TSjlUqhI8oOyz7NfwAdPoA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@16.2.4': + resolution: {integrity: sha512-3NdJV5OXMSOeJYijX+bjaLge3mJBlh4ybydbT4GFoB/2hAojWHtMhl3CYlYoMrjPuodp0nzFVi4Tj2+WaMg+Ow==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@16.2.4': + resolution: {integrity: sha512-kMVGgsqhO5YTYODD9IPGGhA6iprWidQckK3LmPeW08PIFENRmgfb4MjXHO+p//d+ts2rpjvK5gXWzXSMrPl9cw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@swc/helpers@0.5.15': + resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} + + '@tiptap/core@3.22.5': + resolution: {integrity: sha512-L1lhWz6ujGny8LduTJ7MBWYhzigwOvfUJUrJ7IzOJSuy3+OAzisdGDD1GV7LEO/hU0Hr2Mkm1wajRIHExvS9HQ==} + peerDependencies: + '@tiptap/pm': 3.22.5 + + '@tiptap/extension-blockquote@3.22.5': + resolution: {integrity: sha512-ajyP5W8fG5Hrru47T/eF3xMKOpNvWofgNJqBTeNuGl02sYxsy9a4EunyFxudsaZP9WW3VOD4SaIWr5+MqpbnOQ==} + peerDependencies: + '@tiptap/core': 3.22.5 + + '@tiptap/extension-bold@3.22.5': + resolution: {integrity: sha512-l/uDtpJISiFFyfctvnODNWBN/XPZI1jVZRacTRDDnSn8+x6KQ7G2qgFYueU7KvVJGDFVT39Iio56mcFRG/Pozg==} + peerDependencies: + '@tiptap/core': 3.22.5 + + '@tiptap/extension-bubble-menu@3.22.5': + resolution: {integrity: sha512-yrNlFQQJY5MmhBpmD8tnmaSmyUQrEvgyPKa3bzVeWEhDSG1CW4A0ZSMx3hrA9yFO0HWfw3IJmvSCycEZQBalpQ==} + peerDependencies: + '@tiptap/core': 3.22.5 + '@tiptap/pm': 3.22.5 + + '@tiptap/extension-bullet-list@3.22.5': + resolution: {integrity: sha512-cf54fG9AybU8NgPMv1TOcoqAkELeRc/VpnSCt/rIJZphWQx9nsFmrtkrlCatrIcCaGtNZYwlHlMnC5LVVMu0uA==} + peerDependencies: + '@tiptap/extension-list': 3.22.5 + + '@tiptap/extension-code-block@3.22.5': + resolution: {integrity: sha512-d123kCfLdJTi4fue1m0+TNFztDkmIRSZGZmGu6H9KqwG5Q7IzjT9o8lzRsz+pXxYqHvqgYmXoEpM6srbzXx/Ag==} + peerDependencies: + '@tiptap/core': 3.22.5 + '@tiptap/pm': 3.22.5 + + '@tiptap/extension-code@3.22.5': + resolution: {integrity: sha512-mwDNOJC9rYbDu/JcqrN4dbUQRklJU8Fuk2raxD/IvFw9qUIcPCmxQ2XT9UTKmZz/Ju7Kdy72fss6XpgWv6gLAQ==} + peerDependencies: + '@tiptap/core': 3.22.5 + + '@tiptap/extension-document@3.22.5': + resolution: {integrity: sha512-8NJERd+pCtvSuEP4C4WMGYmRRCV12ePZL7bC+QUdFlbdXg+kNZS0zZ7hh879tYA0Kidbi8rWWD1Tx+H2ezkmMw==} + peerDependencies: + '@tiptap/core': 3.22.5 + + '@tiptap/extension-dropcursor@3.22.5': + resolution: {integrity: sha512-Mp40DaFrY3sEUVtFqmxrR0BmU4G3k8GCYYNGqNa9OqWv7BrcFDC03V2n3okESDKt4MKkzhQQmypq+ouLy8dLfA==} + peerDependencies: + '@tiptap/extensions': 3.22.5 + + '@tiptap/extension-floating-menu@3.22.5': + resolution: {integrity: sha512-dhem4sTPhyQgQ+pFp2Oud4k4FSQz9PVMgeQAC9288SmGwxBkJNveDAw6sKTMrumqDvwkJrtslXIupq9TZYQnzg==} + peerDependencies: + '@floating-ui/dom': ^1.0.0 + '@tiptap/core': 3.22.5 + '@tiptap/pm': 3.22.5 + + '@tiptap/extension-gapcursor@3.22.5': + resolution: {integrity: sha512-4WkMu7qqjbsm8hCQS+8X+la1wjriN0SKoRdvpfKH33qM50MB34tYJuGLAO+y7TTh4MMMco3AZCKPBL5JVMqNIg==} + peerDependencies: + '@tiptap/extensions': 3.22.5 + + '@tiptap/extension-hard-break@3.22.5': + resolution: {integrity: sha512-n0R2mUVYZU2AVbJhg/WcY9+zx690wVwvsItHJf0DrYbf1tCYHx+PRHUt/AoXk6u8BSmnkb8/FDziS8m3mjfpSg==} + peerDependencies: + '@tiptap/core': 3.22.5 + + '@tiptap/extension-heading@3.22.5': + resolution: {integrity: sha512-hjyEG4947PAhMBfP1G6B0QAh6+y9mp2C5BQmNjprA05/lQzDAT7KFZzNh8ZVp3ol6aICKq/N1gFOW9Dc/9FUOw==} + peerDependencies: + '@tiptap/core': 3.22.5 + + '@tiptap/extension-horizontal-rule@3.22.5': + resolution: {integrity: sha512-vUV0/ugIbXOc8SJib0h8UMhgcqZXWu/dkEhlswZN4VVven1o5enkfxEiDw+OyIJHi5rUkrdhsQ/KTxG/Xb7X8A==} + peerDependencies: + '@tiptap/core': 3.22.5 + '@tiptap/pm': 3.22.5 + + '@tiptap/extension-italic@3.22.5': + resolution: {integrity: sha512-4T8baSiLkeIymTgEwirxDFt5YgYofkP3m1+MGYdGy2HKcOK+1vpvlPhEO1X5qtZngtJW5S4+njKjinRg52A4PA==} + peerDependencies: + '@tiptap/core': 3.22.5 + + '@tiptap/extension-link@3.22.5': + resolution: {integrity: sha512-d671MvF3GPKoS2OVxjIlQ7hIE7MS3hREdR+d4cvnnoiLLD+ZJ6KgDnxmWqF0a1s4qxLWK2KxKRSOIfYGE31QWQ==} + peerDependencies: + '@tiptap/core': 3.22.5 + '@tiptap/pm': 3.22.5 + + '@tiptap/extension-list-item@3.22.5': + resolution: {integrity: sha512-W7uTmyKLhlsvuTPLv+8WwnsY+mlikBFIoLSvVcBaFt4MwpsZ+DeB6KQg02Y7tbtaAnG7rXu9Fvw2QORh2P728A==} + peerDependencies: + '@tiptap/extension-list': 3.22.5 + + '@tiptap/extension-list-keymap@3.22.5': + resolution: {integrity: sha512-cGUnxJ0y515e1bVHNjUmbx7oWHoEon59w6BA5N2KwV9iW2mZZchlTX4yxJSOX+ixeVRChsa7YwC3Z1jUZ6AMEg==} + peerDependencies: + '@tiptap/extension-list': 3.22.5 + + '@tiptap/extension-list@3.22.5': + resolution: {integrity: sha512-cVO3ZHCgxAWZ4zrFSs81FO2nyCk1wb2EHkpLpW98FzbJLkN9rDkazhW99P3HRWy/CvUldOT+8ecI1YrQtBojMg==} + peerDependencies: + '@tiptap/core': 3.22.5 + '@tiptap/pm': 3.22.5 + + '@tiptap/extension-mention@3.22.5': + resolution: {integrity: sha512-rGTbTjyxLc5C/6QjfbQF53nMbxjVgJU1VK6Si1i1J2c5DU09COgEFlYvi4YHjb3xz39SprPfG+GTtgD96eg7Ww==} + peerDependencies: + '@tiptap/core': 3.22.5 + '@tiptap/pm': 3.22.5 + '@tiptap/suggestion': 3.22.5 + + '@tiptap/extension-ordered-list@3.22.5': + resolution: {integrity: sha512-OXdh4k4CNrukwiSdWdEQ49uvgnqvR0Z9aNSP4HI5/kZQ/Te1NtRtYCpUrzWyO/7CtjcCisXHti0o9C/TV8YMbQ==} + peerDependencies: + '@tiptap/extension-list': 3.22.5 + + '@tiptap/extension-paragraph@3.22.5': + resolution: {integrity: sha512-52KCto4+XKpnBWpIufspWLyq4UWxAWC72ANPdGuIhbi72NRTabiTbTVN40uwGSPkyakeESG0/vKdWJCVvB4f0g==} + peerDependencies: + '@tiptap/core': 3.22.5 + + '@tiptap/extension-strike@3.22.5': + resolution: {integrity: sha512-42WrrFK5gOom/0znH85x12Mw5IQ/6O6DWdyUWoRIrNA/qJpuHtU8oVU+bIgU2tuomMGHruRjIzgBQv5sBjEtww==} + peerDependencies: + '@tiptap/core': 3.22.5 + + '@tiptap/extension-text@3.22.5': + resolution: {integrity: sha512-bzpDOdAEo1JeoVZDIyV0oY0jGXkEG+AzF70SzHoRSjOvFDtKWunyXf9eO1OnOr2/fmMcckT2qwUBNBMQplWBzw==} + peerDependencies: + '@tiptap/core': 3.22.5 + + '@tiptap/extension-underline@3.22.5': + resolution: {integrity: sha512-9ut09rJD0iEbS6sk7yd2j6IwuFDLTNmDEGTDLodvqAfi+bq7ddsTDv0YviXoZaA9sdHAdTEVr2ITy2m6WK5jpA==} + peerDependencies: + '@tiptap/core': 3.22.5 + + '@tiptap/extensions@3.22.5': + resolution: {integrity: sha512-Ifg4MzKCj3uRqe3ieTwYnomu2y4p7EXr2avVSKZYfh12i2dyWe2Gkn1KuZDREANVE+gHqFlQjJRYzhJFwzSCrg==} + peerDependencies: + '@tiptap/core': 3.22.5 + '@tiptap/pm': 3.22.5 + + '@tiptap/pm@3.22.5': + resolution: {integrity: sha512-Cr9Mv4igxvI2tKMiahw48sZxva3PfDzypErH8IB82N+9qa9n9ygVMt0BOaDg53hLKxEEVeYr2S/wCcJIVFgBTw==} + + '@tiptap/react@3.22.5': + resolution: {integrity: sha512-36WHEs+vPmB//V1ff7Ujcnpz7Ey5g8lhpI/0+hoanSbdiPMTQ7qZVWwMovIkMKDlqWVp2fxBgeYM1861jyFzTw==} + peerDependencies: + '@tiptap/core': 3.22.5 + '@tiptap/pm': 3.22.5 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + '@types/react-dom': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tiptap/starter-kit@3.22.5': + resolution: {integrity: sha512-LZ/LYbwH6rnDi5DnRyagkuNsYAVyhM+yJvvz+ZuYA0JkPiTXJV86J5PWSKew8M0gVfMHcNVtKjfQCvViFCeIgw==} + + '@tiptap/suggestion@3.22.5': + resolution: {integrity: sha512-Uv79Ht/o4mx1GWIT65jeQTE67LMrA+K7d8p51XOe9PJw0H0fS3iCdeMJ8tAo3h6QrMJFejdsB7z8jJL9UbAnhA==} + peerDependencies: + '@tiptap/core': 3.22.5 + '@tiptap/pm': 3.22.5 + + '@tybys/wasm-util@0.10.1': + resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-drag@3.0.7': + resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-selection@3.0.11': + resolution: {integrity: sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==} + + '@types/d3-transition@3.0.9': + resolution: {integrity: sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==} + + '@types/d3-zoom@3.0.8': + resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/node@20.19.39': + resolution: {integrity: sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + '@types/use-sync-external-store@0.0.6': + resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==} + + '@typescript-eslint/eslint-plugin@8.59.1': + resolution: {integrity: sha512-BOziFIfE+6osHO9FoJG4zjoHUcvI7fTNBSpdAwrNH0/TLvzjsk2oo8XSSOT2HhqUyhZPfHv4UOffoJ9oEEQ7Ag==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.59.1 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.59.1': + resolution: {integrity: sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.59.1': + resolution: {integrity: sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.59.1': + resolution: {integrity: sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.59.1': + resolution: {integrity: sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.59.1': + resolution: {integrity: sha512-klWPBR2ciQHS3f++ug/mVnWKPjBUo7icEL3FAO1lhAR1Z1i5NQYZ1EannMSRYcq5qCv5wNALlXr6fksRHyYl7w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.59.1': + resolution: {integrity: sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.59.1': + resolution: {integrity: sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.59.1': + resolution: {integrity: sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.59.1': + resolution: {integrity: sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + + '@xyflow/react@12.10.2': + resolution: {integrity: sha512-CgIi6HwlcHXwlkTpr0fxLv/0sRVNZ8IdwKLzzeCscaYBwpvfcH1QFOCeaTCuEn1FQEs/B8CjnTSjhs8udgmBgQ==} + peerDependencies: + react: '>=17' + react-dom: '>=17' + + '@xyflow/system@0.0.76': + resolution: {integrity: sha512-hvwvnRS1B3REwVDlWexsq7YQaPZeG3/mKo1jv38UmnpWmxihp14bW6VtEOuHEwJX2FvzFw8k77LyKSk/wiZVNA==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.11.3: + resolution: {integrity: sha512-zBQouZixDTbo3jMGqHKyePxYxr1e5W8UdTmBQ7sNtaA9M2bE32daxxPLS/jojhKOHxQ7LWwPjfiwf/fhaJWzlg==} + engines: {node: '>=4'} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + baseline-browser-mapping@2.10.24: + resolution: {integrity: sha512-I2NkZOOrj2XuguvWCK6OVh9GavsNjZjK908Rq3mIBK25+GD8vPX5w2WdxVqnQ7xx3SrZJiCiZFu+/Oz50oSYSA==} + engines: {node: '>=6.0.0'} + hasBin: true + + brace-expansion@1.1.14: + resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} + + brace-expansion@5.0.5: + resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + engines: {node: 18 || 20 || >=22} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001791: + resolution: {integrity: sha512-yk0l/YSrOnFZk3UROpDLQD9+kC1l4meK/wed583AXrzoarMGJcbRi2Q4RaUYbKxYAsZ8sWmaSa/DsLmdBeI1vQ==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + classcat@5.0.5: + resolution: {integrity: sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + electron-to-chromium@1.5.344: + resolution: {integrity: sha512-4MxfbmNDm+KPh066EZy+eUnkcDPcZ35wNmOWzFuh/ijvHsve6kbLTLURy88uCNK5FbpN+yk2nQY6BYh1GEt+wg==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + es-abstract@1.24.2: + resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.3.2: + resolution: {integrity: sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-next@16.2.4: + resolution: {integrity: sha512-A6ekXYFj/YQxBPMl45g3e+U8zJo+X2+ZQwcz34pPKjpc/3S4roBA2Rd9xWB4FKuSxhofo1/95WjzmUY+wHrOhg==} + peerDependencies: + eslint: '>=9.0.0' + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + + eslint-import-resolver-node@0.3.10: + resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} + + eslint-import-resolver-typescript@3.10.1: + resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-react-hooks@7.1.1: + resolution: {integrity: sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0 + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-equals@5.4.0: + resolution: {integrity: sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==} + engines: {node: '>=6.0.0'} + + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.4.0: + resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + engines: {node: '>= 0.4'} + + hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + + hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + linkifyjs@4.3.2: + resolution: {integrity: sha512-NT1CJtq3hHIreOianA8aSXn6Cw0JzYOuDQbOrSPe7gqFnCpKP++MQe3ODgO3oh2GJFORkAAdqredOa60z63GbA==} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + next@16.2.4: + resolution: {integrity: sha512-kPvz56wF5frc+FxlHI5qnklCzbq53HTwORaWBGdT0vNoKh1Aya9XC8aPauH4NJxqtzbWsS5mAbctm4cr+EkQ2Q==} + engines: {node: '>=20.9.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + node-exports-info@1.6.0: + resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} + engines: {node: '>= 0.4'} + + node-releases@2.0.38: + resolution: {integrity: sha512-3qT/88Y3FbH/Kx4szpQQ4HzUbVrHPKTLVpVocKiLfoYvw9XSGOX2FmD2d6DrXbVYyAQTF2HeF6My8jmzx7/CRw==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + orderedmap@2.1.1: + resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + prosemirror-changeset@2.4.1: + resolution: {integrity: sha512-96WBLhOaYhJ+kPhLg3uW359Tz6I/MfcrQfL4EGv4SrcqKEMC1gmoGrXHecPE8eOwTVCJ4IwgfzM8fFad25wNfw==} + + prosemirror-commands@1.7.1: + resolution: {integrity: sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==} + + prosemirror-dropcursor@1.8.2: + resolution: {integrity: sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==} + + prosemirror-gapcursor@1.4.1: + resolution: {integrity: sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw==} + + prosemirror-history@1.5.0: + resolution: {integrity: sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg==} + + prosemirror-keymap@1.2.3: + resolution: {integrity: sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==} + + prosemirror-model@1.25.4: + resolution: {integrity: sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==} + + prosemirror-schema-list@1.5.1: + resolution: {integrity: sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==} + + prosemirror-state@1.4.4: + resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==} + + prosemirror-tables@1.8.5: + resolution: {integrity: sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw==} + + prosemirror-transform@1.12.0: + resolution: {integrity: sha512-GxboyN4AMIsoHNtz5uf2r2Ru551i5hWeCMD6E2Ib4Eogqoub0NflniaBPVQ4MrGE5yZ8JV9tUHg9qcZTTrcN4w==} + + prosemirror-view@1.41.8: + resolution: {integrity: sha512-TnKDdohEatgyZNGCDWIdccOHXhYloJwbwU+phw/a23KBvJIR9lWQWW7WHHK3vBdOLDNuF7TaX98GObUZOWkOnA==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-dom@19.2.4: + resolution: {integrity: sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==} + peerDependencies: + react: ^19.2.4 + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react@19.2.4: + resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==} + engines: {node: '>=0.10.0'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@2.0.0-next.6: + resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rope-sequence@1.3.4: + resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.4: + resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} + engines: {node: '>=0.4'} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + engines: {node: '>=12.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typescript-eslint@8.59.1: + resolution: {integrity: sha512-xqDcFVBmlrltH64lklOVp1wYxgJr6LVdg3NamBgH2OOQDLFdTKfIZXF5PfghrnXQKXZGTQs8tr1vL7fJvq8CTQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + w3c-keyname@2.2.8: + resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod-validation-error@4.0.2: + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + zod@4.3.6: + resolution: {integrity: sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==} + + zustand@4.5.7: + resolution: {integrity: sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==} + engines: {node: '>=12.7.0'} + peerDependencies: + '@types/react': '>=16.8' + immer: '>=9.0.6' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + +snapshots: + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.0': {} + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.2': + dependencies: + '@babel/types': 7.29.0 + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.2 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.2 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': + dependencies: + eslint: 9.39.4 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.15.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@floating-ui/core@1.7.5': + dependencies: + '@floating-ui/utils': 0.2.11 + optional: true + + '@floating-ui/dom@1.7.6': + dependencies: + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 + optional: true + + '@floating-ui/utils@0.2.11': + optional: true + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@img/colour@1.1.0': + optional: true + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.10.0 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@next/env@16.2.4': {} + + '@next/eslint-plugin-next@16.2.4': + dependencies: + fast-glob: 3.3.1 + + '@next/swc-darwin-arm64@16.2.4': + optional: true + + '@next/swc-darwin-x64@16.2.4': + optional: true + + '@next/swc-linux-arm64-gnu@16.2.4': + optional: true + + '@next/swc-linux-arm64-musl@16.2.4': + optional: true + + '@next/swc-linux-x64-gnu@16.2.4': + optional: true + + '@next/swc-linux-x64-musl@16.2.4': + optional: true + + '@next/swc-win32-arm64-msvc@16.2.4': + optional: true + + '@next/swc-win32-x64-msvc@16.2.4': + optional: true + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@rtsao/scc@1.1.0': {} + + '@swc/helpers@0.5.15': + dependencies: + tslib: 2.8.1 + + '@tiptap/core@3.22.5(@tiptap/pm@3.22.5)': + dependencies: + '@tiptap/pm': 3.22.5 + + '@tiptap/extension-blockquote@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + + '@tiptap/extension-bold@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + + '@tiptap/extension-bubble-menu@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)': + dependencies: + '@floating-ui/dom': 1.7.6 + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + '@tiptap/pm': 3.22.5 + optional: true + + '@tiptap/extension-bullet-list@3.22.5(@tiptap/extension-list@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/extension-list': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + + '@tiptap/extension-code-block@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + '@tiptap/pm': 3.22.5 + + '@tiptap/extension-code@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + + '@tiptap/extension-document@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + + '@tiptap/extension-dropcursor@3.22.5(@tiptap/extensions@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/extensions': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + + '@tiptap/extension-floating-menu@3.22.5(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)': + dependencies: + '@floating-ui/dom': 1.7.6 + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + '@tiptap/pm': 3.22.5 + optional: true + + '@tiptap/extension-gapcursor@3.22.5(@tiptap/extensions@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/extensions': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + + '@tiptap/extension-hard-break@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + + '@tiptap/extension-heading@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + + '@tiptap/extension-horizontal-rule@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + '@tiptap/pm': 3.22.5 + + '@tiptap/extension-italic@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + + '@tiptap/extension-link@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + '@tiptap/pm': 3.22.5 + linkifyjs: 4.3.2 + + '@tiptap/extension-list-item@3.22.5(@tiptap/extension-list@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/extension-list': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + + '@tiptap/extension-list-keymap@3.22.5(@tiptap/extension-list@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/extension-list': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + + '@tiptap/extension-list@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + '@tiptap/pm': 3.22.5 + + '@tiptap/extension-mention@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)(@tiptap/suggestion@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + '@tiptap/pm': 3.22.5 + '@tiptap/suggestion': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + + '@tiptap/extension-ordered-list@3.22.5(@tiptap/extension-list@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/extension-list': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + + '@tiptap/extension-paragraph@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + + '@tiptap/extension-strike@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + + '@tiptap/extension-text@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + + '@tiptap/extension-underline@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + + '@tiptap/extensions@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + '@tiptap/pm': 3.22.5 + + '@tiptap/pm@3.22.5': + dependencies: + prosemirror-changeset: 2.4.1 + prosemirror-commands: 1.7.1 + prosemirror-dropcursor: 1.8.2 + prosemirror-gapcursor: 1.4.1 + prosemirror-history: 1.5.0 + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.4 + prosemirror-schema-list: 1.5.1 + prosemirror-state: 1.4.4 + prosemirror-tables: 1.8.5 + prosemirror-transform: 1.12.0 + prosemirror-view: 1.41.8 + + '@tiptap/react@3.22.5(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + '@tiptap/pm': 3.22.5 + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + '@types/use-sync-external-store': 0.0.6 + fast-equals: 5.4.0 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + use-sync-external-store: 1.6.0(react@19.2.4) + optionalDependencies: + '@tiptap/extension-bubble-menu': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + '@tiptap/extension-floating-menu': 3.22.5(@floating-ui/dom@1.7.6)(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + transitivePeerDependencies: + - '@floating-ui/dom' + + '@tiptap/starter-kit@3.22.5': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + '@tiptap/extension-blockquote': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5)) + '@tiptap/extension-bold': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5)) + '@tiptap/extension-bullet-list': 3.22.5(@tiptap/extension-list@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)) + '@tiptap/extension-code': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5)) + '@tiptap/extension-code-block': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + '@tiptap/extension-document': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5)) + '@tiptap/extension-dropcursor': 3.22.5(@tiptap/extensions@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)) + '@tiptap/extension-gapcursor': 3.22.5(@tiptap/extensions@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)) + '@tiptap/extension-hard-break': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5)) + '@tiptap/extension-heading': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5)) + '@tiptap/extension-horizontal-rule': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + '@tiptap/extension-italic': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5)) + '@tiptap/extension-link': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + '@tiptap/extension-list': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + '@tiptap/extension-list-item': 3.22.5(@tiptap/extension-list@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)) + '@tiptap/extension-list-keymap': 3.22.5(@tiptap/extension-list@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)) + '@tiptap/extension-ordered-list': 3.22.5(@tiptap/extension-list@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)) + '@tiptap/extension-paragraph': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5)) + '@tiptap/extension-strike': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5)) + '@tiptap/extension-text': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5)) + '@tiptap/extension-underline': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5)) + '@tiptap/extensions': 3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5) + '@tiptap/pm': 3.22.5 + + '@tiptap/suggestion@3.22.5(@tiptap/core@3.22.5(@tiptap/pm@3.22.5))(@tiptap/pm@3.22.5)': + dependencies: + '@tiptap/core': 3.22.5(@tiptap/pm@3.22.5) + '@tiptap/pm': 3.22.5 + + '@tybys/wasm-util@0.10.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/d3-color@3.1.3': {} + + '@types/d3-drag@3.0.7': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-selection@3.0.11': {} + + '@types/d3-transition@3.0.9': + dependencies: + '@types/d3-selection': 3.0.11 + + '@types/d3-zoom@3.0.8': + dependencies: + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/node@20.19.39': + dependencies: + undici-types: 6.21.0 + + '@types/react-dom@19.2.3(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + '@types/use-sync-external-store@0.0.6': {} + + '@typescript-eslint/eslint-plugin@8.59.1(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.59.1(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.1 + '@typescript-eslint/type-utils': 8.59.1(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.1(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.1 + eslint: 9.39.4 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.59.1 + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/typescript-estree': 8.59.1(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.1 + debug: 4.4.3 + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.59.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@5.9.3) + '@typescript-eslint/types': 8.59.1 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.59.1': + dependencies: + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/visitor-keys': 8.59.1 + + '@typescript-eslint/tsconfig-utils@8.59.1(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.59.1(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/typescript-estree': 8.59.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.1(eslint@9.39.4)(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.4 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.59.1': {} + + '@typescript-eslint/typescript-estree@8.59.1(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.59.1(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.59.1(typescript@5.9.3) + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/visitor-keys': 8.59.1 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.7.4 + tinyglobby: 0.2.16 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.59.1(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@typescript-eslint/scope-manager': 8.59.1 + '@typescript-eslint/types': 8.59.1 + '@typescript-eslint/typescript-estree': 8.59.1(typescript@5.9.3) + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.59.1': + dependencies: + '@typescript-eslint/types': 8.59.1 + eslint-visitor-keys: 5.0.1 + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + + '@xyflow/react@12.10.2(@types/react@19.2.14)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)': + dependencies: + '@xyflow/system': 0.0.76 + classcat: 5.0.5 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + zustand: 4.5.7(@types/react@19.2.14)(react@19.2.4) + transitivePeerDependencies: + - '@types/react' + - immer + + '@xyflow/system@0.0.76': + dependencies: + '@types/d3-drag': 3.0.7 + '@types/d3-interpolate': 3.0.4 + '@types/d3-selection': 3.0.11 + '@types/d3-transition': 3.0.9 + '@types/d3-zoom': 3.0.8 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-zoom: 3.0.0 + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + argparse@2.0.1: {} + + aria-query@5.3.2: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-includes@3.1.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + ast-types-flow@0.0.8: {} + + async-function@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axe-core@4.11.3: {} + + axobject-query@4.1.0: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + baseline-browser-mapping@2.10.24: {} + + brace-expansion@1.1.14: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.5: + dependencies: + balanced-match: 4.0.4 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.24 + caniuse-lite: 1.0.30001791 + electron-to-chromium: 1.5.344 + node-releases: 2.0.38 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001791: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + classcat@5.0.5: {} + + client-only@0.0.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + concat-map@0.0.1: {} + + convert-source-map@2.0.0: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.2.3: {} + + d3-color@3.1.0: {} + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-ease@3.0.1: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-selection@3.0.0: {} + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + damerau-levenshtein@1.0.8: {} + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + detect-libc@2.1.2: + optional: true + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + electron-to-chromium@1.5.344: {} + + emoji-regex@9.2.2: {} + + es-abstract@1.24.2: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.4 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.20 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-iterator-helpers@1.3.2: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + math-intrinsics: 1.1.0 + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.3 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.3 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-next@16.2.4(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3): + dependencies: + '@next/eslint-plugin-next': 16.2.4 + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint@9.39.4) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint@9.39.4))(eslint@9.39.4) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4) + eslint-plugin-react: 7.37.5(eslint@9.39.4) + eslint-plugin-react-hooks: 7.1.1(eslint@9.39.4) + globals: 16.4.0 + typescript-eslint: 8.59.1(eslint@9.39.4)(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + + eslint-import-resolver-node@0.3.10: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.1 + resolve: 2.0.0-next.6 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint@9.39.4): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3 + eslint: 9.39.4 + get-tsconfig: 4.14.0 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.16 + unrs-resolver: 1.11.1 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint@9.39.4))(eslint@9.39.4) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint@9.39.4))(eslint@9.39.4): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.59.1(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint@9.39.4) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint@9.39.4))(eslint@9.39.4): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint@9.39.4))(eslint@9.39.4) + hasown: 2.0.3 + is-core-module: 2.16.1 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.59.1(eslint@9.39.4)(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.9 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.11.3 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.39.4 + hasown: 2.0.3 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-react-hooks@7.1.1(eslint@9.39.4): + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.2 + eslint: 9.39.4 + hermes-parser: 0.25.1 + zod: 4.3.6 + zod-validation-error: 4.0.2(zod@4.3.6) + transitivePeerDependencies: + - supports-color + + eslint-plugin-react@7.37.5(eslint@9.39.4): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.3.2 + eslint: 9.39.4 + estraverse: 5.3.0 + hasown: 2.0.3 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.5 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.6 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.4: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.8 + ajv: 6.15.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + fast-deep-equal@3.1.3: {} + + fast-equals@5.4.0: {} + + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flatted@3.4.2: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.3 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + generator-function@2.0.1: {} + + gensync@1.0.0-beta.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.14.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globals@16.4.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + gopd@1.2.0: {} + + has-bigints@1.1.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hasown@2.0.3: + dependencies: + function-bind: 1.1.2 + + hermes-estree@0.25.1: {} + + hermes-parser@0.25.1: + dependencies: + hermes-estree: 0.25.1 + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.3 + side-channel: 1.1.0 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-bun-module@2.0.0: + dependencies: + semver: 7.7.4 + + is-callable@1.2.7: {} + + is-core-module@2.16.1: + dependencies: + hasown: 2.0.3 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.3 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.20 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + + js-tokens@4.0.0: {} + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + linkifyjs@4.3.2: {} + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + math-intrinsics@1.1.0: {} + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.5 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.14 + + minimist@1.2.8: {} + + ms@2.1.3: {} + + nanoid@3.3.11: {} + + napi-postinstall@0.3.4: {} + + natural-compare@1.4.0: {} + + next@16.2.4(@babel/core@7.29.0)(react-dom@19.2.4(react@19.2.4))(react@19.2.4): + dependencies: + '@next/env': 16.2.4 + '@swc/helpers': 0.5.15 + baseline-browser-mapping: 2.10.24 + caniuse-lite: 1.0.30001791 + postcss: 8.4.31 + react: 19.2.4 + react-dom: 19.2.4(react@19.2.4) + styled-jsx: 5.1.6(@babel/core@7.29.0)(react@19.2.4) + optionalDependencies: + '@next/swc-darwin-arm64': 16.2.4 + '@next/swc-darwin-x64': 16.2.4 + '@next/swc-linux-arm64-gnu': 16.2.4 + '@next/swc-linux-arm64-musl': 16.2.4 + '@next/swc-linux-x64-gnu': 16.2.4 + '@next/swc-linux-x64-musl': 16.2.4 + '@next/swc-win32-arm64-msvc': 16.2.4 + '@next/swc-win32-x64-msvc': 16.2.4 + sharp: 0.34.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + node-exports-info@1.6.0: + dependencies: + array.prototype.flatmap: 1.3.3 + es-errors: 1.3.0 + object.entries: 1.1.9 + semver: 6.3.1 + + node-releases@2.0.38: {} + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.entries@1.1.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + orderedmap@2.1.1: {} + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + picomatch@4.0.4: {} + + possible-typed-array-names@1.1.0: {} + + postcss@8.4.31: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + prosemirror-changeset@2.4.1: + dependencies: + prosemirror-transform: 1.12.0 + + prosemirror-commands@1.7.1: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + + prosemirror-dropcursor@1.8.2: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + prosemirror-view: 1.41.8 + + prosemirror-gapcursor@1.4.1: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-view: 1.41.8 + + prosemirror-history@1.5.0: + dependencies: + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + prosemirror-view: 1.41.8 + rope-sequence: 1.3.4 + + prosemirror-keymap@1.2.3: + dependencies: + prosemirror-state: 1.4.4 + w3c-keyname: 2.2.8 + + prosemirror-model@1.25.4: + dependencies: + orderedmap: 2.1.1 + + prosemirror-schema-list@1.5.1: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + + prosemirror-state@1.4.4: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-transform: 1.12.0 + prosemirror-view: 1.41.8 + + prosemirror-tables@1.8.5: + dependencies: + prosemirror-keymap: 1.2.3 + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + prosemirror-view: 1.41.8 + + prosemirror-transform@1.12.0: + dependencies: + prosemirror-model: 1.25.4 + + prosemirror-view@1.41.8: + dependencies: + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.12.0 + + punycode@2.3.1: {} + + queue-microtask@1.2.3: {} + + react-dom@19.2.4(react@19.2.4): + dependencies: + react: 19.2.4 + scheduler: 0.27.0 + + react-is@16.13.1: {} + + react@19.2.4: {} + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@2.0.0-next.6: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.1 + node-exports-info: 1.6.0 + object-keys: 1.1.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + rope-sequence@1.3.4: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.4: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + scheduler@0.27.0: {} + + semver@6.3.1: {} + + semver@7.7.4: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.7.4 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + optional: true + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + source-map-js@1.2.1: {} + + stable-hash@0.0.5: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.24.2 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + strip-bom@3.0.0: {} + + strip-json-comments@3.1.1: {} + + styled-jsx@5.1.6(@babel/core@7.29.0)(react@19.2.4): + dependencies: + client-only: 0.0.1 + react: 19.2.4 + optionalDependencies: + '@babel/core': 7.29.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + tinyglobby@0.2.16: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + ts-api-utils@2.5.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.1: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typescript-eslint@8.59.1(eslint@9.39.4)(typescript@5.9.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.59.1(@typescript-eslint/parser@8.59.1(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/parser': 8.59.1(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.59.1(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.1(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + typescript@5.9.3: {} + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + undici-types@6.21.0: {} + + unrs-resolver@1.11.1: + dependencies: + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + use-sync-external-store@1.6.0(react@19.2.4): + dependencies: + react: 19.2.4 + + w3c-keyname@2.2.8: {} + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.20 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.20: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + yallist@3.1.1: {} + + yocto-queue@0.1.0: {} + + zod-validation-error@4.0.2(zod@4.3.6): + dependencies: + zod: 4.3.6 + + zod@4.3.6: {} + + zustand@4.5.7(@types/react@19.2.14)(react@19.2.4): + dependencies: + use-sync-external-store: 1.6.0(react@19.2.4) + optionalDependencies: + '@types/react': 19.2.14 + react: 19.2.4 diff --git a/apps/web/styles/base.css b/apps/web/styles/base.css new file mode 100644 index 0000000..b43b4a2 --- /dev/null +++ b/apps/web/styles/base.css @@ -0,0 +1,925 @@ +/* ─── Base shared styles (theme variables defined per-aesthetic in HTML) ─── */ + +* { box-sizing: border-box; } +html, body { margin: 0; padding: 0; height: 100%; } +body { + font-family: var(--font-body); + color: var(--fg); + background: var(--bg); + /* Direct children fill the viewport */ + display: flex; + flex-direction: column; + min-height: 100dvh; +} +body > * { flex: 1; min-height: 0; } +button { font-family: inherit; } + +/* ─── Shell ─── */ +.shell { + width: 100%; + height: 100dvh; + min-height: 0; + display: flex; + flex-direction: column; + background: var(--bg); + color: var(--fg); + font-family: var(--font-body); + font-size: 13.5px; + line-height: 1.55; + overflow: hidden; + letter-spacing: var(--tracking); +} +.shell-density-compact { font-size: 12.5px; line-height: 1.45; } + +/* ─── Top bar ─── */ +.topbar { + display: flex; + align-items: center; + justify-content: space-between; + height: 44px; + padding: 0 16px; + background: var(--surface); + border-bottom: 1px solid var(--border); + flex-shrink: 0; +} +.topbar-left { display: flex; align-items: center; gap: 14px; } +.brand { display: flex; align-items: center; gap: 8px; } +.brand-name { font-family: var(--font-display); font-weight: 600; font-size: 15px; letter-spacing: 0.01em; } +.breadcrumbs { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--muted); font-family: var(--font-mono); } +.bc-sep { opacity: 0.45; } +.bc-active { color: var(--fg); } +.bc-branch { margin-left: 10px; padding: 2px 8px; border-radius: 4px; background: var(--accent-soft); color: var(--accent-strong); font-size: 11.5px; } +.bc-branch-glyph { margin-right: 4px; } + +.topbar-right { display: flex; align-items: center; gap: 10px; } +.sync-pill { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--muted); font-family: var(--font-mono); } +.sync-dot { width: 6px; height: 6px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 3px var(--ok-soft); } +.topbar-divider { width: 1px; height: 18px; background: var(--border); } +.icon-btn { + width: 26px; height: 26px; border-radius: 5px; border: 1px solid transparent; + background: transparent; color: var(--muted); font-size: 13px; + display: inline-flex; align-items: center; justify-content: center; cursor: pointer; + font-family: var(--font-mono); +} +.icon-btn:hover { background: var(--surface-2); color: var(--fg); border-color: var(--border); } +.avatar { + width: 26px; height: 26px; border-radius: 50%; + background: var(--accent); color: var(--accent-on); + font-size: 11px; font-weight: 600; + display: inline-flex; align-items: center; justify-content: center; + font-family: var(--font-display); letter-spacing: 0.02em; +} + +/* ─── Body layout ─── */ +.shell-body { + flex: 1; + display: grid; + grid-template-columns: 320px 184px 1fr; + min-height: 0; +} +.shell-density-compact .shell-body { grid-template-columns: 296px 168px 1fr; } +.shell-presence-prominent .shell-body { grid-template-columns: 360px 184px 1fr; } +.shell-presence-subtle .shell-body { grid-template-columns: 0px 184px 1fr; } + +/* ─── Left rail ─── */ +.leftrail { + border-right: 1px solid var(--border); + border-left: 1px solid var(--border); + background: var(--surface); + padding: 8px 8px; + overflow-y: auto; + font-size: 11.5px; + position: relative; +} +.leftrail-collapsed { + padding: 14px 0; + display: flex; flex-direction: column; align-items: center; gap: 14px; + width: 36px; + min-width: 36px; +} +.rail-collapsed-stack { + display: flex; flex-direction: column; gap: 18px; + margin-top: 8px; +} +.rail-collapsed-tag { + font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.08em; + color: var(--muted); writing-mode: vertical-rl; text-orientation: mixed; + cursor: pointer; +} +.rail-collapsed-tag:hover { color: var(--fg); } +.rail-section-head { + display: flex; align-items: center; gap: 5px; + width: 100%; + background: transparent; border: none; padding: 0 4px; + cursor: pointer; + margin-bottom: 4px; + color: inherit; + height: 20px; +} +.rail-section-head:hover .rail-label { color: var(--fg); } +.rail-caret { display: none; } +.rail-section .rail-label { margin-bottom: 0; padding: 0; } +.rail-collapse-btn { + position: absolute; top: 8px; right: 6px; + width: 18px; height: 18px; border-radius: 4px; + border: none; background: transparent; color: var(--muted); + cursor: pointer; font-size: 11px; line-height: 1; + display: flex; align-items: center; justify-content: center; +} +.rail-collapse-btn:hover { background: var(--surface-2); color: var(--fg); } +.leftrail-collapsed .rail-collapse-btn { position: static; } +.rail-collapse-btn-bottom { display: none; } +.shell-density-compact .leftrail { padding: 10px 10px; font-size: 11.5px; } +.rail-section { margin-bottom: 10px; } +.rail-label { + text-transform: uppercase; + font-size: 9.5px; + font-family: var(--font-mono); + letter-spacing: 0.10em; + color: var(--muted); + margin-bottom: 4px; + padding: 0 4px; +} +.rail-list { list-style: none; padding: 0; margin: 0; } +.rail-item { + padding: 2px 6px; border-radius: 3px; cursor: pointer; color: var(--fg); + display: flex; align-items: center; gap: 6px; + font-size: 11.5px; line-height: 1.35; +} +.rail-item-text { flex: 1; } +.rail-count { + font-family: var(--font-mono); font-size: 9.5px; + padding: 1px 5px; border-radius: 3px; + background: var(--surface-2); color: var(--muted-strong); + letter-spacing: 0.02em; + flex-shrink: 0; +} +.rail-count-asm { background: var(--c-prop-bg); color: var(--c-prop-fg); } +.rail-count-req { background: var(--c-block-bg); color: var(--c-block-fg); } +.rail-count-q { background: var(--accent-soft); color: var(--accent-strong); } +.rail-count-risk { background: var(--warn-soft); color: var(--warn-strong); } +.rail-item:hover { background: var(--surface-2); } +.rail-item-active { background: var(--accent-soft); color: var(--accent-strong); } +.rail-item-muted { color: var(--muted); } + +.rail-blocks { display: flex; flex-direction: column; gap: 1px; } +.rail-block { + display: flex; align-items: center; gap: 6px; + padding: 2px 6px; border-radius: 3px; cursor: pointer; + font-family: var(--font-mono); font-size: 10.5px; + line-height: 1.4; +} +.rail-block:hover { background: var(--surface-2); } +.rail-block-active { background: var(--accent-soft); color: var(--accent-strong); } +.rail-block-glyph { color: var(--muted); width: 12px; } +.rail-constraint .rail-block-glyph { color: var(--warn); } +.rail-actor .rail-block-glyph { color: var(--info); } +.rail-block-label { flex: 1; } +.rail-block-count { + font-size: 10px; color: var(--muted); + background: var(--surface-2); padding: 1px 5px; border-radius: 3px; + display: inline-flex; align-items: center; gap: 3px; + cursor: help; +} +.rail-block-count-glyph { opacity: 0.6; } + +.rail-req { + display: flex; align-items: center; justify-content: space-between; + padding: 2px 6px; font-family: var(--font-mono); font-size: 10px; color: var(--muted-strong); +} +.req-tag { letter-spacing: 0.04em; } +.req-status { width: 6px; height: 6px; border-radius: 50%; } +.req-traced { background: var(--ok); } +.req-untraced { background: var(--warn); } + +/* ─── Canvases ─── */ +.canvases { display: grid; grid-template-columns: 1fr 1px 1fr; min-height: 0; background: var(--bg); } +.canvas { display: flex; flex-direction: column; min-height: 0; min-width: 0; } +.canvas-divider { background: var(--border); } +.canvas-header { + height: auto; min-height: 44px; padding: 8px 16px; flex-shrink: 0; + display: flex; align-items: center; justify-content: space-between; + border-bottom: 1px solid var(--border); background: var(--surface); +} +.shell-density-compact .canvas-header { min-height: 38px; padding: 6px 12px; } +.canvas-title { font-family: var(--font-display); font-weight: 600; font-size: 12.5px; letter-spacing: 0.02em; line-height: 1.3; } +.canvas-sub { font-size: 10.5px; color: var(--muted); font-family: var(--font-mono); line-height: 1.3; margin-top: 2px; } +.canvas-actions { display: flex; gap: 2px; background: var(--surface-2); padding: 2px; border-radius: 5px; } +.canvas-mode-pill { + font-size: 10.5px; padding: 3px 8px; border-radius: 4px; + color: var(--muted); cursor: pointer; font-family: var(--font-mono); +} +.canvas-mode-active { background: var(--surface); color: var(--fg); box-shadow: 0 1px 2px var(--shadow); } + +.canvas-scroll { flex: 1; overflow-y: auto; min-height: 0; position: relative; } +.canvas-scroll-diagram { overflow: hidden; } + +/* ─── Text canvas ─── */ +.text-canvas { + max-width: 720px; + margin: 0 auto; + font-family: var(--font-prose); + color: var(--fg); +} +.t-h1 { + font-family: var(--font-display); + font-weight: 600; + font-size: 22px; + letter-spacing: -0.01em; + margin: 14px 0 16px 0; + color: var(--fg); +} +.t-h2 { + font-family: var(--font-display); + font-weight: 600; + font-size: 15px; + letter-spacing: 0.01em; + margin: 24px 0 8px 0; + color: var(--fg); +} +.t-p { + margin: 0 0 14px 0; + font-size: 14.5px; + line-height: 1.65; + color: var(--prose); + text-wrap: pretty; +} +.shell-density-compact .t-p { font-size: 13px; line-height: 1.55; margin-bottom: 10px; } +.shell-density-compact .t-h1 { font-size: 19px; } +.shell-density-compact .t-h2 { font-size: 13.5px; } + +/* ─── Chips ─── */ +.chip { + display: inline-flex; align-items: baseline; gap: 3px; + padding: 1px 6px; border-radius: 4px; cursor: pointer; + font-family: var(--font-mono); + font-size: 0.86em; + vertical-align: baseline; + transition: background .12s, box-shadow .12s; + white-space: nowrap; +} +.chip-glyph { font-size: 0.85em; opacity: 0.75; } +.chip-label { font-weight: 500; } +.chip-focus { box-shadow: 0 0 0 1.5px var(--accent); } + +/* pill (default) */ +.chip-style-pill { background: var(--chip-bg); color: var(--chip-fg); } +.chip-style-pill:hover { background: var(--chip-bg-hover); } + +/* color-coded by kind */ +.chip-style-color.chip-block { background: var(--c-block-bg); color: var(--c-block-fg); } +.chip-style-color.chip-property { background: var(--c-prop-bg); color: var(--c-prop-fg); } +.chip-style-color.chip-association { background: var(--c-assoc-bg); color: var(--c-assoc-fg); } +.chip-style-color.chip-requirement { background: var(--c-req-bg); color: var(--c-req-fg); } + +/* underline */ +.chip-style-underline { + background: transparent; + padding: 0 1px; + border-bottom: 1.5px solid var(--accent); + border-radius: 0; + color: var(--fg); +} +.chip-style-underline.chip-block { border-bottom-color: var(--c-block-fg); } +.chip-style-underline.chip-property { border-bottom-color: var(--c-prop-fg); } +.chip-style-underline.chip-association { border-bottom-color: var(--c-assoc-fg); } +.chip-style-underline.chip-requirement { border-bottom-color: var(--c-req-fg); } +.chip-style-underline:hover { background: var(--chip-bg); } + +/* bracket */ +.chip-style-bracket { + background: transparent; + color: var(--muted-strong); + padding: 0 1px; +} +.chip-style-bracket .chip-bracket { color: var(--muted); opacity: 0.6; } +.chip-style-bracket .chip-kind { color: var(--accent); margin-right: 3px; } +.chip-style-bracket .chip-label { color: var(--fg); } +.chip-style-bracket:hover { background: var(--chip-bg); border-radius: 3px; } + +/* ─── Margin note ─── */ +.margin-note { + display: flex; gap: 12px; + margin: 24px 0 8px 0; + padding: 12px 14px; + background: var(--note-bg); + border-left: 2px solid var(--accent); + border-radius: 0 6px 6px 0; + font-family: var(--font-prose); + font-size: 13px; + color: var(--prose); +} +.margin-note-glyph { + font-family: var(--font-display); font-weight: 600; + color: var(--accent); font-size: 17px; line-height: 1; + flex-shrink: 0; +} +.margin-note-who { + display: block; + font-family: var(--font-mono); font-size: 10.5px; + color: var(--accent); letter-spacing: 0.04em; text-transform: uppercase; + margin-bottom: 4px; +} +.margin-note-text { line-height: 1.5; } + +/* ─── Diagram ─── */ +.diagram-grid { + position: absolute; inset: 0; + background-image: radial-gradient(var(--grid-dot) 1px, transparent 1px); + background-size: 18px 18px; + background-position: 0 0; + opacity: 0.7; + pointer-events: none; +} +.diagram-legend { + position: absolute; bottom: 12px; left: 12px; + display: flex; gap: 14px; + background: var(--surface); + border: 1px solid var(--border); + padding: 6px 10px; + border-radius: 5px; + font-family: var(--font-mono); + font-size: 10.5px; + color: var(--muted); +} +.legend-sw { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-right: 5px; vertical-align: -1px; } +.legend-block { background: var(--block-bg); border: 1px solid var(--block-border); } +.legend-actor { background: var(--block-actor-bg); border: 1px solid var(--block-border); } +.legend-constraint { background: var(--block-constraint-bg); border: 1px dashed var(--block-border); } + +/* ─── Socrates dock ─── */ +.dock { + border-right: 1px solid var(--border); + background: var(--surface); + display: flex; flex-direction: column; + overflow: hidden; + font-size: 12.5px; + min-height: 0; +} + +.dock-header { + display: flex; align-items: center; gap: 8px; + padding: 8px 10px; + border-bottom: 1px solid var(--border); + flex-shrink: 0; +} +.dock-header-text { flex: 1; min-width: 0; } +.dock-header-action { + width: 22px; height: 22px; border-radius: 4px; + border: 1px solid var(--border-strong); + background: transparent; color: var(--muted); + cursor: pointer; font-size: 13px; line-height: 1; + display: flex; align-items: center; justify-content: center; +} +.dock-header-action:hover { background: var(--surface-2); color: var(--fg); } + +.dock-thread-wrap { + flex: 1; + min-height: 0; + overflow-y: auto; + padding: 10px 10px 6px; + display: flex; flex-direction: column; +} +.dock-section-label-inline { + margin-bottom: 8px; + flex-shrink: 0; +} +.dock-thread { + display: flex; flex-direction: column; gap: 8px; + flex: 1; +} +.bubble { + padding: 8px 10px; border-radius: 8px; + font-family: var(--font-prose); font-size: 12.5px; line-height: 1.5; + display: flex; gap: 8px; + align-items: flex-start; +} +.bubble-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; } +.bubble-text { display: block; } + +.dock-input-wrap { + flex-shrink: 0; + padding: 8px 10px; + border-top: 1px solid var(--border); + background: var(--surface); +} +.dock-input { margin-top: 0; } + +/* Numbered options inside a bubble */ +.bubble-options { + display: flex; flex-direction: column; gap: 3px; + margin-top: 2px; +} +.bubble-option { + display: flex; align-items: center; gap: 8px; + padding: 4px 7px; + background: var(--surface); + border: 1px solid var(--border-strong); + border-radius: 5px; + cursor: pointer; + text-align: left; + font-family: var(--font-prose); + color: var(--fg); + width: 100%; + transition: background .12s, border-color .12s; +} +.bubble-option:hover { + background: var(--surface-2); + border-color: var(--accent); +} +.bubble-option-num { + width: 15px; height: 15px; flex-shrink: 0; + border-radius: 3px; + background: var(--accent-soft); color: var(--accent-strong); + font-family: var(--font-mono); font-size: 9.5px; font-weight: 600; + display: flex; align-items: center; justify-content: center; +} +.bubble-option-text { flex: 1; min-width: 0; display: flex; align-items: baseline; gap: 6px; } +.bubble-option-label { + font-size: 11.5px; font-weight: 500; color: var(--fg); + line-height: 1.25; +} +.bubble-option-sub { + font-family: var(--font-mono); font-size: 9.5px; + color: var(--muted); + line-height: 1.25; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.bubble-option-key { display: none; } +.bubble-options-hint { + font-family: var(--font-mono); font-size: 9.5px; + color: var(--muted); + margin-top: 3px; + padding: 0 2px; +} +.bubble-options-hint kbd { + font-family: var(--font-mono); font-size: 9px; + padding: 0 3px; border-radius: 2px; + background: var(--surface-2); color: var(--muted-strong); + border: 1px solid var(--border); + margin: 0 1px; +} +.dock-subtle { + position: fixed; bottom: 24px; right: 24px; + width: 50px; height: 50px; + border-radius: 50%; border: 1px solid var(--border); + background: var(--surface); + display: flex; align-items: center; justify-content: center; + box-shadow: 0 6px 20px var(--shadow-strong); + cursor: pointer; + z-index: 10; +} +.dock-subtle-count { + position: absolute; top: -4px; right: -4px; + width: 18px; height: 18px; border-radius: 50%; + background: var(--accent); color: var(--accent-on); + font-size: 10px; font-weight: 600; + display: flex; align-items: center; justify-content: center; + font-family: var(--font-mono); +} + +.dock-header { + display: flex; align-items: center; gap: 8px; + padding: 8px 10px; + border-bottom: 1px solid var(--border); +} +.dock-name { font-family: var(--font-display); font-weight: 600; font-size: 12.5px; } +.dock-status { display: flex; align-items: center; gap: 4px; font-size: 10px; color: var(--muted); font-family: var(--font-mono); } +.dock-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--ok); box-shadow: 0 0 0 2px var(--ok-soft); } + +.dock-section { padding: 8px 10px; border-bottom: 1px solid var(--border); } +.dock-section:last-child { border-bottom: none; } +.dock-section-label { + text-transform: uppercase; + font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.10em; + color: var(--muted); margin-bottom: 6px; +} +.dock-section-label-2 { margin-top: 16px; } + +.dock-thread { display: flex; flex-direction: column; gap: 8px; } +.bubble-socrates { + background: var(--bubble-socrates); + color: var(--prose); + border-left: 2px solid var(--accent); + border-radius: 2px 8px 8px 2px; + padding-left: 10px; +} +.bubble-socrates .bubble-sigil { + display: inline-block; + font-family: var(--font-display); font-weight: 600; + color: var(--accent); margin-right: 6px; + flex-shrink: 0; +} +.bubble-user { + background: var(--bubble-user); + color: var(--fg); + align-self: flex-end; + max-width: 88%; +} + +.dock-input { + display: flex; align-items: center; gap: 6px; + padding: 7px 10px; + border: 1px solid var(--border-strong); + border-radius: 6px; + font-family: var(--font-mono); + font-size: 11.5px; + color: var(--muted); + background: var(--bg); +} +.dock-input-prompt { color: var(--accent); } +.dock-input-placeholder { flex: 1; } +.dock-input-shortcut { font-size: 10px; opacity: 0.55; } + +/* Proposal */ +.proposal { + background: var(--surface-2); + border: 1px solid var(--border); + border-radius: 6px; + padding: 10px; +} +.proposal-title { + font-family: var(--font-display); font-weight: 600; font-size: 12.5px; + color: var(--fg); margin-bottom: 8px; + line-height: 1.35; +} +.proposal-meta { display: flex; flex-direction: column; gap: 4px; margin-bottom: 10px; } +.proposal-row { display: flex; gap: 8px; font-family: var(--font-mono); font-size: 10.5px; align-items: baseline; } +.proposal-key { color: var(--muted); width: 70px; flex-shrink: 0; } +.proposal-val { display: flex; gap: 4px; flex-wrap: wrap; } +.proposal-pill { + background: var(--accent-soft); color: var(--accent-strong); + padding: 1px 6px; border-radius: 3px; font-size: 10.5px; +} +.proposal-pill-req { background: var(--c-req-bg); color: var(--c-req-fg); } + +.proposal-actions { display: flex; gap: 6px; } +.btn { + flex: 1; + padding: 6px 10px; + border-radius: 5px; + border: 1px solid var(--border-strong); + background: var(--surface); + color: var(--fg); + font-family: var(--font-mono); + font-size: 11.5px; + cursor: pointer; +} +.btn:hover { background: var(--surface-2); } +.btn-primary { background: var(--accent); color: var(--accent-on); border-color: var(--accent); } +.btn-primary:hover { background: var(--accent-strong); } +.btn-ghost { background: transparent; border-color: transparent; color: var(--muted); flex: 0; padding: 6px 8px; } + +/* Watch list */ +.watch { display: flex; flex-direction: column; gap: 6px; } +.watch-row { + display: flex; gap: 8px; align-items: flex-start; + font-size: 11.5px; line-height: 1.4; color: var(--prose); +} +.watch-tag { + font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.04em; + background: var(--c-prop-bg); color: var(--c-prop-fg); + padding: 2px 5px; border-radius: 3px; + flex-shrink: 0; margin-top: 1px; +} +.watch-tag-risk { background: var(--warn-soft); color: var(--warn-strong); } +.watch-validated .watch-tag { background: var(--ok-soft); color: var(--ok-strong); } +.watch-text { flex: 1; } +.watch-risk-high .watch-text { color: var(--fg); } + +/* ─── Status bar ─── */ +.statusbar { + height: 24px; flex-shrink: 0; + display: flex; align-items: center; gap: 12px; + padding: 0 16px; + font-family: var(--font-mono); font-size: 10.5px; color: var(--muted); + border-top: 1px solid var(--border); + background: var(--surface); +} +.status-spacer { flex: 1; } + +/* ─── Sigil ─── */ +.sigil { position: relative; } +.sigil-pulse { + animation: sigilpulse 2.4s ease-in-out infinite; + transform-origin: center; +} +@keyframes sigilpulse { + 0%, 100% { opacity: 0.3; r: 2; } + 50% { opacity: 1; r: 3.5; } +} + +/* ─── Seed screen ─── */ +.seed-screen { + width: 100%; height: 100dvh; min-height: 0; + display: flex; flex-direction: column; + background: var(--bg); + font-family: var(--font-body); + color: var(--fg); + overflow: hidden; +} +.seed-top { + display: flex; align-items: center; justify-content: space-between; + padding: 12px 20px; + border-bottom: 1px solid var(--border); + background: var(--surface); + flex-shrink: 0; +} +.seed-top-left { display: flex; align-items: center; gap: 10px; } +.seed-brand { font-family: var(--font-display); font-weight: 600; font-size: 16px; } +.seed-pip { color: var(--muted); } +.seed-step { font-family: var(--font-mono); font-size: 11.5px; color: var(--muted); } +.seed-top-right { display: flex; gap: 2px; background: var(--surface-2); padding: 2px; border-radius: 5px; } +.seed-mode-pill { + font-family: var(--font-mono); font-size: 11px; padding: 4px 12px; + border-radius: 4px; color: var(--muted); cursor: pointer; +} +.seed-mode-active { background: var(--surface); color: var(--fg); box-shadow: 0 1px 2px var(--shadow); } + +.seed-body { + flex: 1; + display: grid; + grid-template-columns: minmax(280px, 380px) 1fr; + min-height: 0; +} + +.seed-left { + border-right: 1px solid var(--border); + background: var(--surface); + padding: 22px 22px 18px; + overflow-y: auto; +} +.seed-section-label { + text-transform: uppercase; + font-family: var(--font-mono); font-size: 10px; letter-spacing: 0.14em; + color: var(--muted); margin-bottom: 12px; +} +.seed-section-label-2 { margin-top: 24px; } +.seed-fields { display: flex; flex-direction: column; gap: 14px; } +.seed-field { + padding-left: 12px; + border-left: 2px solid var(--border-strong); +} +.seed-field-inferred { border-left-color: var(--accent); border-left-style: dashed; } +.seed-field-label { + font-family: var(--font-mono); font-size: 10.5px; + color: var(--muted); letter-spacing: 0.04em; + margin-bottom: 3px; + display: flex; gap: 8px; align-items: baseline; +} +.seed-conf { font-size: 9.5px; color: var(--accent); opacity: 0.85; } +.seed-field-value { + font-family: var(--font-prose); + font-size: 13.5px; line-height: 1.5; + color: var(--fg); + text-wrap: pretty; +} + +.seed-mini-graph { + display: grid; + grid-template-columns: 1fr; + gap: 8px; + padding: 14px; + background: var(--bg); + border: 1px solid var(--border); + border-radius: 6px; + position: relative; +} +.mini-block { + border: 1px solid var(--block-border); + background: var(--block-bg); + padding: 8px 10px; + border-radius: 6px; + display: flex; flex-direction: column; gap: 1px; +} +.mini-block-3 { background: var(--block-constraint-bg); border-style: dashed; } +.mini-block-focus { + border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); +} +.mini-stereo { font-family: var(--font-mono); font-size: 9.5px; color: var(--muted); letter-spacing: 0.04em; } +.mini-name { font-family: var(--font-display); font-weight: 600; font-size: 13px; } +.mini-prop { font-family: var(--font-mono); font-size: 11px; color: var(--muted-strong); margin-top: 2px; } +.mini-edge { + height: 14px; + background: linear-gradient(to bottom, var(--edge), var(--edge)) center/1px 100% no-repeat; + margin-left: 18px; + position: relative; +} +.mini-edge::after { + content: ""; position: absolute; left: -3px; bottom: 0; + border-left: 4px solid transparent; border-right: 4px solid transparent; + border-top: 5px solid var(--edge); +} + +.seed-confidence { margin-top: 18px; } +.seed-confidence-row { + display: flex; justify-content: space-between; + font-family: var(--font-mono); font-size: 11px; color: var(--muted); + margin-bottom: 5px; +} +.seed-confidence-bar { + height: 4px; border-radius: 2px; + background: var(--surface-2); + overflow: hidden; +} +.seed-confidence-fill { + height: 100%; background: var(--accent); +} +.seed-confidence-hint { + margin-top: 6px; + font-size: 11px; color: var(--muted); font-family: var(--font-prose); + font-style: italic; +} + +.seed-right { + display: flex; flex-direction: column; + min-height: 0; + background: var(--bg); +} +.seed-thread { + flex: 1; min-height: 0; + overflow-y: auto; + padding: 22px 36px; + display: flex; flex-direction: column; gap: 18px; + max-width: 760px; + margin: 0 auto; + width: 100%; +} +.seed-bubble { + display: flex; gap: 14px; +} +.seed-bubble-user { justify-content: flex-end; } +.seed-bubble-avatar { flex-shrink: 0; padding-top: 2px; } +.seed-bubble-body { max-width: 78%; } +.seed-bubble-user .seed-bubble-body { + background: var(--bubble-user); + padding: 10px 14px; + border-radius: 12px 12px 2px 12px; + color: var(--fg); +} +.seed-bubble-who { + font-family: var(--font-mono); font-size: 10.5px; + color: var(--muted); letter-spacing: 0.04em; + text-transform: uppercase; margin-bottom: 4px; +} +.seed-bubble-user .seed-bubble-who { display: none; } +.seed-bubble-text { + font-family: var(--font-prose); + font-size: 14.5px; line-height: 1.6; + color: var(--prose); + text-wrap: pretty; +} +.seed-bubble-user .seed-bubble-text { color: var(--fg); } + +.seed-bubble-typing .seed-bubble-text { color: var(--muted); } +.seed-typing { display: flex; align-items: center; gap: 6px; font-size: 12.5px; color: var(--muted); font-family: var(--font-mono); } +.seed-typing span { + width: 4px; height: 4px; border-radius: 50%; + background: var(--accent); opacity: 0.35; + animation: typing 1.4s ease-in-out infinite; +} +.seed-typing span:nth-child(2) { animation-delay: 0.2s; } +.seed-typing span:nth-child(3) { animation-delay: 0.4s; } +@keyframes typing { + 0%, 80%, 100% { opacity: 0.25; transform: translateY(0); } + 40% { opacity: 1; transform: translateY(-2px); } +} + +.seed-input-row { + border-top: 1px solid var(--border); + background: var(--surface); + padding: 14px 36px; + max-width: 760px; margin: 0 auto; width: 100%; + display: flex; flex-direction: column; gap: 10px; + flex-shrink: 0; +} +.seed-input { + display: flex; align-items: baseline; gap: 8px; + padding: 10px 14px; + background: var(--bg); + border: 1px solid var(--border-strong); + border-radius: 8px; + font-family: var(--font-prose); + font-size: 14px; + line-height: 1.5; + color: var(--fg); +} +.seed-input-prompt { color: var(--accent); font-family: var(--font-mono); } +.seed-input-text { flex: 1; } +.seed-input-caret { + display: inline-block; + width: 1.5px; height: 16px; + background: var(--accent); + animation: caret 1s steps(1) infinite; + vertical-align: -3px; +} +@keyframes caret { 50% { opacity: 0; } } +.seed-input-actions { display: flex; justify-content: flex-end; gap: 8px; } +.seed-btn { + padding: 6px 12px; + border-radius: 5px; + border: 1px solid var(--border-strong); + background: var(--surface); + color: var(--fg); + font-family: var(--font-mono); + font-size: 11.5px; + cursor: pointer; +} +.seed-btn-primary { background: var(--accent); color: var(--accent-on); border-color: var(--accent); } + +/* ─── Slash menu (M2) ─── */ +.slash-menu { + background: var(--surface); + border: 1px solid var(--border-strong); + border-radius: 6px; + box-shadow: 0 8px 24px var(--shadow-strong); + padding: 4px; + min-width: 280px; + display: flex; flex-direction: column; gap: 2px; +} +.slash-menu-empty { + padding: 10px 12px; + font-family: var(--font-mono); + font-size: 11.5px; + color: var(--muted); +} +.slash-menu-item { + display: grid; + grid-template-columns: 20px 1fr auto auto; + align-items: center; + gap: 8px; + padding: 6px 8px; + border-radius: 4px; + background: transparent; + border: none; + cursor: pointer; + text-align: left; + font-family: inherit; + color: var(--fg); +} +.slash-menu-item:hover, +.slash-menu-item-active { + background: var(--accent-soft); + color: var(--accent-strong); +} +.slash-menu-glyph { + font-family: var(--font-mono); + font-size: 13px; + color: var(--muted); + text-align: center; +} +.slash-menu-glyph-block { color: var(--c-block-fg); } +.slash-menu-glyph-property { color: var(--c-prop-fg); } +.slash-menu-glyph-association { color: var(--c-assoc-fg); } +.slash-menu-glyph-requirement { color: var(--c-req-fg); } +.slash-menu-label { + font-family: var(--font-display); + font-size: 13px; + font-weight: 500; +} +.slash-menu-hint { + font-family: var(--font-mono); + font-size: 10.5px; + color: var(--muted); + margin-right: 4px; +} +.slash-menu-key { + font-family: var(--font-mono); + font-size: 10px; + background: var(--surface-2); + color: var(--muted-strong); + border: 1px solid var(--border); + padding: 1px 5px; + border-radius: 3px; +} + +/* TipTap-rendered narrative root */ +.tiptap { outline: none; } +.tiptap:focus { outline: none; } +.tiptap p.t-p, +.tiptap > p { + margin: 0 0 14px 0; + font-size: 14.5px; + line-height: 1.65; + color: var(--prose); + text-wrap: pretty; +} +.tiptap > h1 { + font-family: var(--font-display); + font-weight: 600; + font-size: 22px; + margin: 14px 0 16px 0; +} +.tiptap > h2 { + font-family: var(--font-display); + font-weight: 600; + font-size: 15px; + margin: 24px 0 8px 0; +} + +/* Make ProseMirror's inline-atom selection look like our chip-focus state. */ +.tiptap .ProseMirror-selectednode .chip { + box-shadow: 0 0 0 1.5px var(--accent); +} diff --git a/apps/web/styles/diagram.css b/apps/web/styles/diagram.css new file mode 100644 index 0000000..70d7606 --- /dev/null +++ b/apps/web/styles/diagram.css @@ -0,0 +1,336 @@ +/* React Flow styling overrides for the Manuscript theme. */ + +.diagram-flow { + width: 100%; + height: 100%; + background: var(--diagram-bg); +} + +/* Hide the default attribution badge for cleaner aesthetic */ +.react-flow__attribution { + display: none; +} + +.react-flow__pane { + cursor: default; +} + +/* Background dots */ +.react-flow__background { + background-color: var(--diagram-bg); +} + +/* Connection line drawn while drag-creating an edge */ +.react-flow__connection-path { + stroke: var(--accent); + stroke-width: 1.5; + stroke-dasharray: 4 3; +} + +/* Selection box */ +.react-flow__nodesselection-rect, +.react-flow__selection { + background: var(--accent-soft); + border: 1px dashed var(--accent); +} + +/* Node base wrapper — we draw our own card; React Flow's outer just provides position. */ +.react-flow__node { + font-family: var(--font-body); + cursor: grab; +} +.react-flow__node:active { cursor: grabbing; } + +/* Custom node card (BlockNode component) */ +.sysml-node { + position: relative; + background: var(--block-bg); + border: 1px solid var(--block-border); + border-radius: 8px; + box-shadow: 0 2px 4px var(--shadow); + font-family: var(--font-body); + user-select: none; + display: flex; flex-direction: column; + min-width: 168px; +} +.sysml-node-actor { + background: var(--block-actor-bg); +} +.sysml-node-constraint { + background: var(--block-constraint-bg); + border-style: dashed; +} +.sysml-node-system { + border-color: var(--accent); + border-width: 1.5px; +} +.sysml-node-selected, +.react-flow__node.selected .sysml-node { + border-color: var(--accent); + box-shadow: 0 0 0 2px var(--accent-soft), 0 2px 4px var(--shadow); +} +.sysml-node-stereo { + font-family: var(--font-mono); + font-size: 9px; + color: var(--muted); + letter-spacing: 0.04em; + padding: 6px 12px 0 12px; +} +.sysml-node-title { + font-family: var(--font-display); + font-weight: 600; + font-size: 13px; + color: var(--fg); + padding: 1px 12px 8px 12px; +} +.sysml-node-divider { + height: 1px; + background: var(--block-divider); +} +.sysml-node-props { + padding: 6px 12px 8px 12px; + display: flex; flex-direction: column; gap: 3px; +} +.sysml-node-prop { + font-family: var(--font-mono); + font-size: 11.5px; + color: var(--muted-strong); +} +.sysml-node-prop-empty { + font-family: var(--font-mono); + font-size: 10.5px; + color: var(--muted); + font-style: italic; +} +.sysml-node-constraint-body { + padding: 4px 12px 8px 12px; + font-family: var(--font-mono); + font-size: 11px; + color: var(--muted-strong); +} + +/* Connection handles — kept subtle; visible on hover */ +.react-flow__handle { + width: 8px; + height: 8px; + background: var(--surface); + border: 1.25px solid var(--accent); + opacity: 0; + transition: opacity 0.15s; +} +.react-flow__node:hover .react-flow__handle, +.react-flow__node.selected .react-flow__handle { + opacity: 1; +} + +/* Edges */ +.react-flow__edge-path { + stroke: var(--edge); + stroke-width: 1; +} +.react-flow__edge.selected .react-flow__edge-path { + stroke: var(--accent); + stroke-width: 1.5; +} +.react-flow__edge-text { + font-family: var(--font-mono); + font-size: 10.5px; + fill: var(--edge-label); +} +.react-flow__edge-textbg { + fill: var(--diagram-bg); +} + +.sysml-edge-label { + background: var(--diagram-bg); + border: 0.75px solid var(--edge-soft); + border-radius: 4px; + padding: 1px 6px; + font-family: var(--font-mono); + font-size: 10.5px; + color: var(--edge-label); + white-space: nowrap; + pointer-events: all; +} + +/* Controls (zoom in/out/fit) — positioned via React Flow's `position` prop */ +.react-flow__controls { + box-shadow: 0 2px 8px var(--shadow); + background: var(--surface); + border: 1px solid var(--border); + border-radius: 6px; + overflow: hidden; +} +.react-flow__controls-button { + background: transparent; + border: none; + border-bottom: 1px solid var(--border); + color: var(--muted-strong); + width: 26px; + height: 26px; + padding: 0; + display: flex; + align-items: center; + justify-content: center; +} +.react-flow__controls-button:last-child { border-bottom: none; } +.react-flow__controls-button:hover { + background: var(--surface-2); + color: var(--fg); +} +.react-flow__controls-button svg { + fill: currentColor; + width: 11px; + height: 11px; + max-width: 11px; + max-height: 11px; +} + +/* Palette — drag source for new blocks */ +.diagram-palette { + position: absolute; + top: 12px; + left: 12px; + display: flex; flex-direction: column; gap: 6px; + z-index: 5; + background: var(--surface); + border: 1px solid var(--border); + border-radius: 6px; + padding: 6px; + box-shadow: 0 2px 8px var(--shadow); +} +.diagram-palette-label { + font-family: var(--font-mono); + font-size: 9.5px; + color: var(--muted); + letter-spacing: 0.10em; + text-transform: uppercase; + padding: 2px 4px 4px 4px; +} +.diagram-palette-item { + display: flex; align-items: center; gap: 8px; + padding: 5px 8px; + border-radius: 4px; + background: var(--bg); + border: 1px solid var(--border); + cursor: grab; + font-family: var(--font-mono); + font-size: 11px; + color: var(--fg); +} +.diagram-palette-item:hover { + background: var(--accent-soft); + border-color: var(--accent); + color: var(--accent-strong); +} +.diagram-palette-item:active { cursor: grabbing; } +.diagram-palette-glyph { + width: 14px; height: 14px; + display: inline-flex; align-items: center; justify-content: center; + font-size: 11px; + color: var(--muted); +} + +/* Inspector panel for selected node */ +.diagram-inspector { + position: absolute; + top: 12px; + right: 12px; + width: 240px; + background: var(--surface); + border: 1px solid var(--border); + border-radius: 6px; + padding: 10px 12px; + box-shadow: 0 2px 8px var(--shadow); + z-index: 5; + display: flex; flex-direction: column; gap: 8px; + font-family: var(--font-body); +} +.diagram-inspector-row { + display: flex; flex-direction: column; gap: 3px; +} +.diagram-inspector-label { + font-family: var(--font-mono); + font-size: 9.5px; + color: var(--muted); + letter-spacing: 0.08em; + text-transform: uppercase; +} +.diagram-inspector-input { + font-family: inherit; + font-size: 13px; + padding: 5px 7px; + background: var(--bg); + border: 1px solid var(--border-strong); + border-radius: 4px; + color: var(--fg); + outline: none; +} +.diagram-inspector-input:focus { border-color: var(--accent); } +.diagram-inspector-select { + font-family: var(--font-mono); + font-size: 11.5px; + padding: 4px 6px; + background: var(--bg); + border: 1px solid var(--border-strong); + border-radius: 4px; + color: var(--fg); +} +.diagram-inspector-prop { + display: flex; gap: 4px; align-items: center; +} +.diagram-inspector-prop input { + flex: 1; + font-family: var(--font-mono); + font-size: 11.5px; + padding: 3px 6px; + background: var(--bg); + border: 1px solid var(--border); + border-radius: 3px; + color: var(--fg); + outline: none; +} +.diagram-inspector-prop input:focus { border-color: var(--accent); } +.diagram-inspector-prop-x { + width: 18px; height: 18px; + display: flex; align-items: center; justify-content: center; + background: transparent; + border: none; + color: var(--muted); + cursor: pointer; + font-size: 13px; +} +.diagram-inspector-prop-x:hover { color: var(--warn-strong); } +.diagram-inspector-add { + margin-top: 2px; + padding: 4px 8px; + background: transparent; + border: 1px dashed var(--border-strong); + border-radius: 4px; + color: var(--muted-strong); + font-family: var(--font-mono); + font-size: 10.5px; + cursor: pointer; +} +.diagram-inspector-add:hover { + background: var(--accent-soft); + border-color: var(--accent); + color: var(--accent-strong); +} +.diagram-inspector-actions { + display: flex; gap: 6px; margin-top: 6px; +} +.diagram-inspector-btn { + flex: 1; + padding: 5px 8px; + font-family: var(--font-mono); + font-size: 11px; + background: var(--surface); + border: 1px solid var(--border-strong); + border-radius: 4px; + cursor: pointer; + color: var(--fg); +} +.diagram-inspector-btn:hover { background: var(--surface-2); } +.diagram-inspector-btn-danger { color: var(--warn-strong); } +.diagram-inspector-btn-danger:hover { background: var(--warn-soft); } diff --git a/apps/web/styles/theme-manuscript.css b/apps/web/styles/theme-manuscript.css new file mode 100644 index 0000000..c51f1fd --- /dev/null +++ b/apps/web/styles/theme-manuscript.css @@ -0,0 +1,79 @@ +/* MANUSCRIPT — warm parchment, scholarly serif, ink-blue accent. + Document-first; Socrates feels like a character in a book. */ + +.theme-manuscript { + --font-display: "Newsreader", "Source Serif Pro", "Iowan Old Style", Georgia, serif; + --font-prose: "Newsreader", "Source Serif Pro", "Iowan Old Style", Georgia, serif; + --font-body: "Söhne", "Inter Tight", -apple-system, system-ui, sans-serif; + --font-mono: "JetBrains Mono", "IBM Plex Mono", ui-monospace, Menlo, monospace; + --tracking: 0; + + --bg: #f5efe2; /* parchment */ + --surface: #faf5e9; + --surface-2: #ede4cf; + --fg: #2a241a; + --prose: #3d3527; + --muted: #8a7c63; + --muted-strong: #5e533f; + --border: #d9ceb3; + --border-strong: #b8a982; + + --accent: #2c4a6b; /* ink blue */ + --accent-strong: #1c3550; + --accent-soft: #d6def0; + --accent-on: #faf5e9; + + --ok: #5e7a3a; + --ok-soft: #d9e3c7; + --ok-strong: #3d5421; + --warn: #a8551c; + --warn-soft: #f0d9c2; + --warn-strong: #6b3309; + --info: #5b6e8a; + + --shadow: rgba(60,40,15,0.08); + --shadow-strong: rgba(60,40,15,0.18); + + --grid-dot: rgba(120,90,40,0.18); + --diagram-bg: #f0e9d6; + + --block-bg: #fdfaf0; + --block-border: #b8a982; + --block-divider: #d9ceb3; + --block-actor-bg: #f0e6cf; + --block-constraint-bg:#f5dccb; + + --edge: #6e5d3d; + --edge-soft: #c8b88f; + --edge-label: #5e533f; + + --note-bg: #f0e3c4; + + --bubble-socrates: #f0e3c4; + --bubble-user: #ede4cf; + + --chip-bg: #ede4cf; + --chip-bg-hover: #e2d6b8; + --chip-fg: #2a241a; + + /* color-coded chips */ + --c-block-bg: #d6def0; --c-block-fg: #1c3550; + --c-prop-bg: #e8e0c2; --c-prop-fg: #6b5a25; + --c-assoc-bg: #d9e3c7; --c-assoc-fg: #3d5421; + --c-req-bg: #f0d9c2; --c-req-fg: #6b3309; +} + +/* Manuscript-only flourishes: drop-cap-ish heading underline */ +.theme-manuscript .t-h1 { + border-bottom: 1px solid var(--border-strong); + padding-bottom: 8px; + font-style: italic; + letter-spacing: -0.005em; +} +.theme-manuscript .t-h2 { + font-style: italic; + font-weight: 500; + color: var(--accent-strong); +} +.theme-manuscript .brand-name { font-style: italic; } +.theme-manuscript .canvas-title { font-style: italic; font-weight: 500; } diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json new file mode 100644 index 0000000..3a13f90 --- /dev/null +++ b/apps/web/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "react-jsx", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": ["./*"] + } + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts", + "**/*.mts" + ], + "exclude": ["node_modules"] +}