+ {/* Save button — only shown for authenticated users with unsaved edits */}
+ {!shareToken && editedMarkdown !== null && (
+
+ )}
+
{/* Copy button */}
diff --git a/surfsense_web/components/ui/block-selection.tsx b/surfsense_web/components/ui/block-selection.tsx
new file mode 100644
index 000000000..386fe8852
--- /dev/null
+++ b/surfsense_web/components/ui/block-selection.tsx
@@ -0,0 +1,44 @@
+'use client';
+
+import * as React from 'react';
+
+import { DndPlugin } from '@platejs/dnd';
+import { useBlockSelected } from '@platejs/selection/react';
+import { cva } from 'class-variance-authority';
+import { type PlateElementProps, usePluginOption } from 'platejs/react';
+
+export const blockSelectionVariants = cva(
+ 'pointer-events-none absolute inset-0 z-1 bg-brand/[.13] transition-opacity',
+ {
+ defaultVariants: {
+ active: true,
+ },
+ variants: {
+ active: {
+ false: 'opacity-0',
+ true: 'opacity-100',
+ },
+ },
+ }
+);
+
+export function BlockSelection(props: PlateElementProps) {
+ const isBlockSelected = useBlockSelected();
+ const isDragging = usePluginOption(DndPlugin, 'isDragging');
+
+ if (
+ !isBlockSelected ||
+ props.plugin.key === 'tr' ||
+ props.plugin.key === 'table'
+ )
+ return null;
+
+ return (
+
+ );
+}
diff --git a/surfsense_web/components/ui/blockquote-node-static.tsx b/surfsense_web/components/ui/blockquote-node-static.tsx
new file mode 100644
index 000000000..5d471f805
--- /dev/null
+++ b/surfsense_web/components/ui/blockquote-node-static.tsx
@@ -0,0 +1,13 @@
+import * as React from 'react';
+
+import { type SlateElementProps, SlateElement } from 'platejs/static';
+
+export function BlockquoteElementStatic(props: SlateElementProps) {
+ return (
+
+ );
+}
diff --git a/surfsense_web/components/ui/blockquote-node.tsx b/surfsense_web/components/ui/blockquote-node.tsx
new file mode 100644
index 000000000..ba5bec4e8
--- /dev/null
+++ b/surfsense_web/components/ui/blockquote-node.tsx
@@ -0,0 +1,13 @@
+'use client';
+
+import { type PlateElementProps, PlateElement } from 'platejs/react';
+
+export function BlockquoteElement(props: PlateElementProps) {
+ return (
+
+ );
+}
diff --git a/surfsense_web/components/ui/callout-node.tsx b/surfsense_web/components/ui/callout-node.tsx
new file mode 100644
index 000000000..2d24cb864
--- /dev/null
+++ b/surfsense_web/components/ui/callout-node.tsx
@@ -0,0 +1,83 @@
+'use client';
+
+import * as React from 'react';
+
+import type { TCalloutElement } from 'platejs';
+
+import { CalloutPlugin } from '@platejs/callout/react';
+import { cva } from 'class-variance-authority';
+import { type PlateElementProps, PlateElement, useEditorPlugin } from 'platejs/react';
+
+import { cn } from '@/lib/utils';
+
+const calloutVariants = cva(
+ 'my-1 flex w-full items-start gap-2 rounded-lg border p-4',
+ {
+ defaultVariants: {
+ variant: 'info',
+ },
+ variants: {
+ variant: {
+ info: 'border-blue-200 bg-blue-50 dark:border-blue-800 dark:bg-blue-950/50',
+ warning: 'border-yellow-200 bg-yellow-50 dark:border-yellow-800 dark:bg-yellow-950/50',
+ error: 'border-red-200 bg-red-50 dark:border-red-800 dark:bg-red-950/50',
+ success: 'border-green-200 bg-green-50 dark:border-green-800 dark:bg-green-950/50',
+ note: 'border-muted bg-muted/50',
+ tip: 'border-purple-200 bg-purple-50 dark:border-purple-800 dark:bg-purple-950/50',
+ },
+ },
+ }
+);
+
+const calloutIcons: Record
= {
+ info: '💡',
+ warning: '⚠️',
+ error: '🚨',
+ success: '✅',
+ note: '📝',
+ tip: '💜',
+};
+
+const variantCycle = ['info', 'warning', 'error', 'success', 'note', 'tip'] as const;
+
+export function CalloutElement({
+ children,
+ ...props
+}: PlateElementProps) {
+ const { editor } = useEditorPlugin(CalloutPlugin);
+ const element = props.element;
+ const variant = element.variant || 'info';
+ const icon = element.icon || calloutIcons[variant] || '💡';
+
+ const cycleVariant = React.useCallback(() => {
+ const currentIndex = variantCycle.indexOf(variant as (typeof variantCycle)[number]);
+ const nextIndex = (currentIndex + 1) % variantCycle.length;
+ const nextVariant = variantCycle[nextIndex];
+
+ editor.tf.setNodes(
+ {
+ variant: nextVariant,
+ icon: calloutIcons[nextVariant],
+ },
+ { at: props.path }
+ );
+ }, [editor, variant, props.path]);
+
+ return (
+
+
+ {children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/code-block-node-static.tsx b/surfsense_web/components/ui/code-block-node-static.tsx
new file mode 100644
index 000000000..8e52618e6
--- /dev/null
+++ b/surfsense_web/components/ui/code-block-node-static.tsx
@@ -0,0 +1,161 @@
+import * as React from 'react';
+
+import type { TCodeBlockElement } from 'platejs';
+
+import {
+ type SlateElementProps,
+ type SlateLeafProps,
+ SlateElement,
+ SlateLeaf,
+} from 'platejs/static';
+
+export function CodeBlockElementStatic(
+ props: SlateElementProps
+) {
+ return (
+
+
+
+ );
+}
+
+export function CodeLineElementStatic(props: SlateElementProps) {
+ return ;
+}
+
+export function CodeSyntaxLeafStatic(props: SlateLeafProps) {
+ const tokenClassName = props.leaf.className as string;
+
+ return ;
+}
+
+/**
+ * DOCX-compatible code block components.
+ * Uses inline styles for proper rendering in Word documents.
+ */
+
+export function CodeBlockElementDocx(
+ props: SlateElementProps
+) {
+ return (
+
+
+ {props.children}
+
+
+ );
+}
+
+export function CodeLineElementDocx(props: SlateElementProps) {
+ return (
+
+ );
+}
+
+// Syntax highlighting color map for common token types
+const syntaxColors: Record = {
+ 'hljs-addition': '#22863a',
+ 'hljs-attr': '#005cc5',
+ 'hljs-attribute': '#005cc5',
+ 'hljs-built_in': '#e36209',
+ 'hljs-bullet': '#735c0f',
+ 'hljs-comment': '#6a737d',
+ 'hljs-deletion': '#b31d28',
+ 'hljs-doctag': '#d73a49',
+ 'hljs-emphasis': '#24292e',
+ 'hljs-formula': '#6a737d',
+ 'hljs-keyword': '#d73a49',
+ 'hljs-literal': '#005cc5',
+ 'hljs-meta': '#005cc5',
+ 'hljs-name': '#22863a',
+ 'hljs-number': '#005cc5',
+ 'hljs-operator': '#005cc5',
+ 'hljs-quote': '#22863a',
+ 'hljs-regexp': '#032f62',
+ 'hljs-section': '#005cc5',
+ 'hljs-selector-attr': '#005cc5',
+ 'hljs-selector-class': '#005cc5',
+ 'hljs-selector-id': '#005cc5',
+ 'hljs-selector-pseudo': '#22863a',
+ 'hljs-selector-tag': '#22863a',
+ 'hljs-string': '#032f62',
+ 'hljs-strong': '#24292e',
+ 'hljs-symbol': '#e36209',
+ 'hljs-template-tag': '#d73a49',
+ 'hljs-template-variable': '#d73a49',
+ 'hljs-title': '#6f42c1',
+ 'hljs-type': '#d73a49',
+ 'hljs-variable': '#005cc5',
+};
+
+// Convert regular spaces to non-breaking spaces to preserve indentation in Word
+const preserveSpaces = (text: string): string => {
+ // Replace regular spaces with non-breaking spaces
+ return text.replace(/ /g, '\u00A0');
+};
+
+export function CodeSyntaxLeafDocx(props: SlateLeafProps) {
+ const tokenClassName = props.leaf.className as string;
+
+ // Extract color from className
+ let color: string | undefined;
+ let fontWeight: string | undefined;
+ let fontStyle: string | undefined;
+
+ if (tokenClassName) {
+ const classes = tokenClassName.split(' ');
+ for (const cls of classes) {
+ if (syntaxColors[cls]) {
+ color = syntaxColors[cls];
+ }
+ if (cls === 'hljs-strong' || cls === 'hljs-section') {
+ fontWeight = 'bold';
+ }
+ if (cls === 'hljs-emphasis') {
+ fontStyle = 'italic';
+ }
+ }
+ }
+
+ // Get the text content and preserve spaces
+ const text = props.leaf.text as string;
+ const preservedText = preserveSpaces(text);
+
+ return (
+
+ {preservedText}
+
+ );
+}
diff --git a/surfsense_web/components/ui/code-block-node.tsx b/surfsense_web/components/ui/code-block-node.tsx
new file mode 100644
index 000000000..b846297db
--- /dev/null
+++ b/surfsense_web/components/ui/code-block-node.tsx
@@ -0,0 +1,289 @@
+'use client';
+
+import * as React from 'react';
+
+import { formatCodeBlock, isLangSupported } from '@platejs/code-block';
+import { BracesIcon, Check, CheckIcon, CopyIcon } from 'lucide-react';
+import { type TCodeBlockElement, type TCodeSyntaxLeaf, NodeApi } from 'platejs';
+import {
+ type PlateElementProps,
+ type PlateLeafProps,
+ PlateElement,
+ PlateLeaf,
+} from 'platejs/react';
+import { useEditorRef, useElement, useReadOnly } from 'platejs/react';
+
+import { Button } from '@/components/ui/button';
+import {
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList,
+} from '@/components/ui/command';
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from '@/components/ui/popover';
+import { cn } from '@/lib/utils';
+
+export function CodeBlockElement(props: PlateElementProps) {
+ const { editor, element } = props;
+
+ return (
+
+
+
+ {props.children}
+
+
+
+ {isLangSupported(element.lang) && (
+
+ )}
+
+
+
+ NodeApi.string(element)}
+ />
+
+
+
+ );
+}
+
+function CodeBlockCombobox() {
+ const [open, setOpen] = React.useState(false);
+ const readOnly = useReadOnly();
+ const editor = useEditorRef();
+ const element = useElement();
+ const value = element.lang || 'plaintext';
+ const [searchValue, setSearchValue] = React.useState('');
+
+ const items = React.useMemo(
+ () =>
+ languages.filter(
+ (language) =>
+ !searchValue ||
+ language.label.toLowerCase().includes(searchValue.toLowerCase())
+ ),
+ [searchValue]
+ );
+
+ if (readOnly) return null;
+
+ return (
+
+
+
+
+ setSearchValue('')}
+ >
+
+ setSearchValue(value)}
+ placeholder="Search language..."
+ />
+ No language found.
+
+
+
+ {items.map((language) => (
+ {
+ editor.tf.setNodes(
+ { lang: value },
+ { at: element }
+ );
+ setSearchValue(value);
+ setOpen(false);
+ }}
+ >
+
+ {language.label}
+
+ ))}
+
+
+
+
+
+ );
+}
+
+function CopyButton({
+ value,
+ ...props
+}: { value: (() => string) | string } & Omit<
+ React.ComponentProps,
+ 'value'
+>) {
+ const [hasCopied, setHasCopied] = React.useState(false);
+
+ React.useEffect(() => {
+ setTimeout(() => {
+ setHasCopied(false);
+ }, 2000);
+ }, [hasCopied]);
+
+ return (
+
+ );
+}
+
+export function CodeLineElement(props: PlateElementProps) {
+ return ;
+}
+
+export function CodeSyntaxLeaf(props: PlateLeafProps) {
+ const tokenClassName = props.leaf.className as string;
+
+ return ;
+}
+
+const languages: { label: string; value: string }[] = [
+ { label: 'Auto', value: 'auto' },
+ { label: 'Plain Text', value: 'plaintext' },
+ { label: 'ABAP', value: 'abap' },
+ { label: 'Agda', value: 'agda' },
+ { label: 'Arduino', value: 'arduino' },
+ { label: 'ASCII Art', value: 'ascii' },
+ { label: 'Assembly', value: 'x86asm' },
+ { label: 'Bash', value: 'bash' },
+ { label: 'BASIC', value: 'basic' },
+ { label: 'BNF', value: 'bnf' },
+ { label: 'C', value: 'c' },
+ { label: 'C#', value: 'csharp' },
+ { label: 'C++', value: 'cpp' },
+ { label: 'Clojure', value: 'clojure' },
+ { label: 'CoffeeScript', value: 'coffeescript' },
+ { label: 'Coq', value: 'coq' },
+ { label: 'CSS', value: 'css' },
+ { label: 'Dart', value: 'dart' },
+ { label: 'Dhall', value: 'dhall' },
+ { label: 'Diff', value: 'diff' },
+ { label: 'Docker', value: 'dockerfile' },
+ { label: 'EBNF', value: 'ebnf' },
+ { label: 'Elixir', value: 'elixir' },
+ { label: 'Elm', value: 'elm' },
+ { label: 'Erlang', value: 'erlang' },
+ { label: 'F#', value: 'fsharp' },
+ { label: 'Flow', value: 'flow' },
+ { label: 'Fortran', value: 'fortran' },
+ { label: 'Gherkin', value: 'gherkin' },
+ { label: 'GLSL', value: 'glsl' },
+ { label: 'Go', value: 'go' },
+ { label: 'GraphQL', value: 'graphql' },
+ { label: 'Groovy', value: 'groovy' },
+ { label: 'Haskell', value: 'haskell' },
+ { label: 'HCL', value: 'hcl' },
+ { label: 'HTML', value: 'html' },
+ { label: 'Idris', value: 'idris' },
+ { label: 'Java', value: 'java' },
+ { label: 'JavaScript', value: 'javascript' },
+ { label: 'JSON', value: 'json' },
+ { label: 'Julia', value: 'julia' },
+ { label: 'Kotlin', value: 'kotlin' },
+ { label: 'LaTeX', value: 'latex' },
+ { label: 'Less', value: 'less' },
+ { label: 'Lisp', value: 'lisp' },
+ { label: 'LiveScript', value: 'livescript' },
+ { label: 'LLVM IR', value: 'llvm' },
+ { label: 'Lua', value: 'lua' },
+ { label: 'Makefile', value: 'makefile' },
+ { label: 'Markdown', value: 'markdown' },
+ { label: 'Markup', value: 'markup' },
+ { label: 'MATLAB', value: 'matlab' },
+ { label: 'Mathematica', value: 'mathematica' },
+ { label: 'Mermaid', value: 'mermaid' },
+ { label: 'Nix', value: 'nix' },
+ { label: 'Notion Formula', value: 'notion' },
+ { label: 'Objective-C', value: 'objectivec' },
+ { label: 'OCaml', value: 'ocaml' },
+ { label: 'Pascal', value: 'pascal' },
+ { label: 'Perl', value: 'perl' },
+ { label: 'PHP', value: 'php' },
+ { label: 'PowerShell', value: 'powershell' },
+ { label: 'Prolog', value: 'prolog' },
+ { label: 'Protocol Buffers', value: 'protobuf' },
+ { label: 'PureScript', value: 'purescript' },
+ { label: 'Python', value: 'python' },
+ { label: 'R', value: 'r' },
+ { label: 'Racket', value: 'racket' },
+ { label: 'Reason', value: 'reasonml' },
+ { label: 'Ruby', value: 'ruby' },
+ { label: 'Rust', value: 'rust' },
+ { label: 'Sass', value: 'scss' },
+ { label: 'Scala', value: 'scala' },
+ { label: 'Scheme', value: 'scheme' },
+ { label: 'SCSS', value: 'scss' },
+ { label: 'Shell', value: 'shell' },
+ { label: 'Smalltalk', value: 'smalltalk' },
+ { label: 'Solidity', value: 'solidity' },
+ { label: 'SQL', value: 'sql' },
+ { label: 'Swift', value: 'swift' },
+ { label: 'TOML', value: 'toml' },
+ { label: 'TypeScript', value: 'typescript' },
+ { label: 'VB.Net', value: 'vbnet' },
+ { label: 'Verilog', value: 'verilog' },
+ { label: 'VHDL', value: 'vhdl' },
+ { label: 'Visual Basic', value: 'vbnet' },
+ { label: 'WebAssembly', value: 'wasm' },
+ { label: 'XML', value: 'xml' },
+ { label: 'YAML', value: 'yaml' },
+];
diff --git a/surfsense_web/components/ui/code-node-static.tsx b/surfsense_web/components/ui/code-node-static.tsx
new file mode 100644
index 000000000..9b056659a
--- /dev/null
+++ b/surfsense_web/components/ui/code-node-static.tsx
@@ -0,0 +1,17 @@
+import * as React from 'react';
+
+import type { SlateLeafProps } from 'platejs/static';
+
+import { SlateLeaf } from 'platejs/static';
+
+export function CodeLeafStatic(props: SlateLeafProps) {
+ return (
+
+ {props.children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/code-node.tsx b/surfsense_web/components/ui/code-node.tsx
new file mode 100644
index 000000000..5295b9c83
--- /dev/null
+++ b/surfsense_web/components/ui/code-node.tsx
@@ -0,0 +1,19 @@
+'use client';
+
+import * as React from 'react';
+
+import type { PlateLeafProps } from 'platejs/react';
+
+import { PlateLeaf } from 'platejs/react';
+
+export function CodeLeaf(props: PlateLeafProps) {
+ return (
+
+ {props.children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/editor-static.tsx b/surfsense_web/components/ui/editor-static.tsx
new file mode 100644
index 000000000..b9592bf35
--- /dev/null
+++ b/surfsense_web/components/ui/editor-static.tsx
@@ -0,0 +1,55 @@
+import * as React from 'react';
+
+import type { VariantProps } from 'class-variance-authority';
+
+import { cva } from 'class-variance-authority';
+import { type PlateStaticProps, PlateStatic } from 'platejs/static';
+
+import { cn } from '@/lib/utils';
+
+export const editorVariants = cva(
+ cn(
+ 'group/editor',
+ 'relative w-full cursor-text select-text overflow-x-hidden whitespace-pre-wrap break-words',
+ 'rounded-md ring-offset-background focus-visible:outline-none',
+ 'placeholder:text-muted-foreground/80 **:data-slate-placeholder:top-[auto_!important] **:data-slate-placeholder:text-muted-foreground/80 **:data-slate-placeholder:opacity-100!',
+ '[&_strong]:font-bold'
+ ),
+ {
+ defaultVariants: {
+ variant: 'none',
+ },
+ variants: {
+ disabled: {
+ true: 'cursor-not-allowed opacity-50',
+ },
+ focused: {
+ true: 'ring-2 ring-ring ring-offset-2',
+ },
+ variant: {
+ ai: 'w-full px-0 text-base md:text-sm',
+ aiChat:
+ 'max-h-[min(70vh,320px)] w-full overflow-y-auto px-5 py-3 text-base md:text-sm',
+ default:
+ 'size-full px-16 pt-4 pb-72 text-base sm:px-[max(64px,calc(50%-350px))]',
+ demo: 'size-full px-16 pt-4 pb-72 text-base sm:px-[max(64px,calc(50%-350px))]',
+ fullWidth: 'size-full px-16 pt-4 pb-72 text-base sm:px-24',
+ none: '',
+ select: 'px-3 py-2 text-base data-readonly:w-fit',
+ },
+ },
+ }
+);
+
+export function EditorStatic({
+ className,
+ variant,
+ ...props
+}: PlateStaticProps & VariantProps) {
+ return (
+
+ );
+}
diff --git a/surfsense_web/components/ui/editor.tsx b/surfsense_web/components/ui/editor.tsx
new file mode 100644
index 000000000..e609fa72c
--- /dev/null
+++ b/surfsense_web/components/ui/editor.tsx
@@ -0,0 +1,132 @@
+'use client';
+
+import * as React from 'react';
+
+import type { VariantProps } from 'class-variance-authority';
+import type { PlateContentProps, PlateViewProps } from 'platejs/react';
+
+import { cva } from 'class-variance-authority';
+import { PlateContainer, PlateContent, PlateView } from 'platejs/react';
+
+import { cn } from '@/lib/utils';
+
+const editorContainerVariants = cva(
+ 'relative w-full cursor-text select-text overflow-y-auto caret-primary selection:bg-brand/25 focus-visible:outline-none [&_.slate-selection-area]:z-50 [&_.slate-selection-area]:border [&_.slate-selection-area]:border-brand/25 [&_.slate-selection-area]:bg-brand/15',
+ {
+ defaultVariants: {
+ variant: 'default',
+ },
+ variants: {
+ variant: {
+ comment: cn(
+ 'flex flex-wrap justify-between gap-1 px-1 py-0.5 text-sm',
+ 'rounded-md border-[1.5px] border-transparent bg-transparent',
+ 'has-[[data-slate-editor]:focus]:border-brand/50 has-[[data-slate-editor]:focus]:ring-2 has-[[data-slate-editor]:focus]:ring-brand/30',
+ 'has-aria-disabled:border-input has-aria-disabled:bg-muted'
+ ),
+ default: 'h-full',
+ demo: 'h-[650px]',
+ select: cn(
+ 'group rounded-md border border-input ring-offset-background focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2',
+ 'has-data-readonly:w-fit has-data-readonly:cursor-default has-data-readonly:border-transparent has-data-readonly:focus-within:[box-shadow:none]'
+ ),
+ },
+ },
+ }
+);
+
+export function EditorContainer({
+ className,
+ variant,
+ ...props
+}: React.ComponentProps<'div'> & VariantProps) {
+ return (
+
+ );
+}
+
+const editorVariants = cva(
+ cn(
+ 'group/editor',
+ 'relative w-full cursor-text select-text overflow-x-hidden whitespace-pre-wrap break-words',
+ 'rounded-md ring-offset-background focus-visible:outline-none',
+ '**:data-slate-placeholder:!top-1/2 **:data-slate-placeholder:-translate-y-1/2 placeholder:text-muted-foreground/80 **:data-slate-placeholder:text-muted-foreground/80 **:data-slate-placeholder:opacity-100!',
+ '[&_strong]:font-bold'
+ ),
+ {
+ defaultVariants: {
+ variant: 'default',
+ },
+ variants: {
+ disabled: {
+ true: 'cursor-not-allowed opacity-50',
+ },
+ focused: {
+ true: 'ring-2 ring-ring ring-offset-2',
+ },
+ variant: {
+ ai: 'w-full px-0 text-base md:text-sm',
+ aiChat:
+ 'max-h-[min(70vh,320px)] w-full overflow-y-auto px-3 py-2 text-base md:text-sm',
+ comment: cn('rounded-none border-none bg-transparent text-sm'),
+ default:
+ 'size-full px-16 pt-4 pb-72 text-base sm:px-[max(64px,calc(50%-350px))]',
+ demo: 'size-full px-16 pt-4 pb-72 text-base sm:px-[max(64px,calc(50%-350px))]',
+ fullWidth: 'size-full px-16 pt-4 pb-72 text-base sm:px-24',
+ none: '',
+ select: 'px-3 py-2 text-base data-readonly:w-fit',
+ },
+ },
+ }
+);
+
+export type EditorProps = PlateContentProps &
+ VariantProps;
+
+export const Editor = ({
+ className,
+ disabled,
+ focused,
+ variant,
+ ref,
+ ...props
+}: EditorProps & { ref?: React.RefObject }) => (
+
+);
+
+Editor.displayName = 'Editor';
+
+export function EditorView({
+ className,
+ variant,
+ ...props
+}: PlateViewProps & VariantProps) {
+ return (
+
+ );
+}
+
+EditorView.displayName = 'EditorView';
diff --git a/surfsense_web/components/ui/equation-node.tsx b/surfsense_web/components/ui/equation-node.tsx
new file mode 100644
index 000000000..66b3bb3d7
--- /dev/null
+++ b/surfsense_web/components/ui/equation-node.tsx
@@ -0,0 +1,183 @@
+'use client';
+
+import * as React from 'react';
+
+import type { TEquationElement } from 'platejs';
+
+import {
+ useEquationElement,
+ useEquationInput,
+} from '@platejs/math/react';
+import { RadicalIcon } from 'lucide-react';
+import { type PlateElementProps, PlateElement, useSelected } from 'platejs/react';
+
+import { cn } from '@/lib/utils';
+
+export function EquationElement({
+ children,
+ ...props
+}: PlateElementProps) {
+ const element = props.element;
+ const selected = useSelected();
+ const katexRef = React.useRef(null);
+ const [isEditing, setIsEditing] = React.useState(false);
+
+ useEquationElement({
+ element,
+ katexRef,
+ options: {
+ displayMode: true,
+ throwOnError: false,
+ },
+ });
+
+ const { props: inputProps, ref: inputRef, onDismiss, onSubmit } = useEquationInput({
+ isInline: false,
+ open: isEditing,
+ onClose: () => setIsEditing(false),
+ });
+
+ return (
+
+ setIsEditing(true)}
+ >
+ {element.texExpression ? (
+
+ ) : (
+
+
+ Add an equation
+
+ )}
+
+
+ {isEditing && (
+
+
+
+
+
+
+
+ )}
+
+ {children}
+
+ );
+}
+
+export function InlineEquationElement({
+ children,
+ ...props
+}: PlateElementProps) {
+ const element = props.element;
+ const selected = useSelected();
+ const katexRef = React.useRef(null);
+ const [isEditing, setIsEditing] = React.useState(false);
+
+ useEquationElement({
+ element,
+ katexRef,
+ options: {
+ displayMode: false,
+ throwOnError: false,
+ },
+ });
+
+ const { props: inputProps, ref: inputRef, onDismiss, onSubmit } = useEquationInput({
+ isInline: true,
+ open: isEditing,
+ onClose: () => setIsEditing(false),
+ });
+
+ return (
+
+ setIsEditing(true)}
+ >
+ {element.texExpression ? (
+
+ ) : (
+
+
+
+ )}
+
+
+ {isEditing && (
+
+
+
+
+
+
+
+ )}
+
+ {children}
+
+ );
+}
+
diff --git a/surfsense_web/components/ui/equation-toolbar-button.tsx b/surfsense_web/components/ui/equation-toolbar-button.tsx
new file mode 100644
index 000000000..66862ea69
--- /dev/null
+++ b/surfsense_web/components/ui/equation-toolbar-button.tsx
@@ -0,0 +1,27 @@
+'use client';
+
+import * as React from 'react';
+
+import { insertInlineEquation } from '@platejs/math';
+import { RadicalIcon } from 'lucide-react';
+import { useEditorRef } from 'platejs/react';
+
+import { ToolbarButton } from './toolbar';
+
+export function InlineEquationToolbarButton(
+ props: React.ComponentProps
+) {
+ const editor = useEditorRef();
+
+ return (
+ {
+ insertInlineEquation(editor);
+ }}
+ tooltip="Mark as equation"
+ >
+
+
+ );
+}
diff --git a/surfsense_web/components/ui/floating-toolbar-buttons.tsx b/surfsense_web/components/ui/floating-toolbar-buttons.tsx
new file mode 100644
index 000000000..525ff5e2f
--- /dev/null
+++ b/surfsense_web/components/ui/floating-toolbar-buttons.tsx
@@ -0,0 +1,65 @@
+'use client';
+
+import * as React from 'react';
+
+import {
+ BoldIcon,
+ Code2Icon,
+ ItalicIcon,
+ StrikethroughIcon,
+ UnderlineIcon,
+} from 'lucide-react';
+import { KEYS } from 'platejs';
+import { useEditorReadOnly } from 'platejs/react';
+
+import { LinkToolbarButton } from './link-toolbar-button';
+import { MarkToolbarButton } from './mark-toolbar-button';
+import { MoreToolbarButton } from './more-toolbar-button';
+import { ToolbarGroup } from './toolbar';
+import { TurnIntoToolbarButton } from './turn-into-toolbar-button';
+
+export function FloatingToolbarButtons() {
+ const readOnly = useEditorReadOnly();
+
+ if (readOnly) return null;
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ >
+ );
+}
diff --git a/surfsense_web/components/ui/floating-toolbar.tsx b/surfsense_web/components/ui/floating-toolbar.tsx
new file mode 100644
index 000000000..6cfd3379b
--- /dev/null
+++ b/surfsense_web/components/ui/floating-toolbar.tsx
@@ -0,0 +1,86 @@
+'use client';
+
+import * as React from 'react';
+
+import {
+ type FloatingToolbarState,
+ flip,
+ offset,
+ useFloatingToolbar,
+ useFloatingToolbarState,
+} from '@platejs/floating';
+import { useComposedRef } from '@udecode/cn';
+import { KEYS } from 'platejs';
+import {
+ useEditorId,
+ useEventEditorValue,
+ usePluginOption,
+} from 'platejs/react';
+
+import { cn } from '@/lib/utils';
+
+import { Toolbar } from './toolbar';
+
+export function FloatingToolbar({
+ children,
+ className,
+ state,
+ ...props
+}: React.ComponentProps & {
+ state?: FloatingToolbarState;
+}) {
+ const editorId = useEditorId();
+ const focusedEditorId = useEventEditorValue('focus');
+ const isFloatingLinkOpen = !!usePluginOption({ key: KEYS.link }, 'mode');
+
+ const floatingToolbarState = useFloatingToolbarState({
+ editorId,
+ focusedEditorId,
+ hideToolbar: isFloatingLinkOpen,
+ ...state,
+ floatingOptions: {
+ middleware: [
+ offset(12),
+ flip({
+ fallbackPlacements: [
+ 'top-start',
+ 'top-end',
+ 'bottom-start',
+ 'bottom-end',
+ ],
+ padding: 12,
+ }),
+ ],
+ placement: 'top',
+ ...state?.floatingOptions,
+ },
+ });
+
+ const {
+ clickOutsideRef,
+ hidden,
+ props: rootProps,
+ ref: floatingRef,
+ } = useFloatingToolbar(floatingToolbarState);
+
+ const ref = useComposedRef(props.ref, floatingRef);
+
+ if (hidden) return null;
+
+ return (
+
+
+ {children}
+
+
+ );
+}
diff --git a/surfsense_web/components/ui/heading-node-static.tsx b/surfsense_web/components/ui/heading-node-static.tsx
new file mode 100644
index 000000000..48db8596d
--- /dev/null
+++ b/surfsense_web/components/ui/heading-node-static.tsx
@@ -0,0 +1,72 @@
+import * as React from 'react';
+
+import type { SlateElementProps } from 'platejs/static';
+
+import { type VariantProps, cva } from 'class-variance-authority';
+import { SlateElement } from 'platejs/static';
+
+const headingVariants = cva('relative mb-1', {
+ variants: {
+ variant: {
+ h1: 'mt-[1.6em] pb-1 font-bold font-heading text-4xl',
+ h2: 'mt-[1.4em] pb-px font-heading font-semibold text-2xl tracking-tight',
+ h3: 'mt-[1em] pb-px font-heading font-semibold text-xl tracking-tight',
+ h4: 'mt-[0.75em] font-heading font-semibold text-lg tracking-tight',
+ h5: 'mt-[0.75em] font-semibold text-lg tracking-tight',
+ h6: 'mt-[0.75em] font-semibold text-base tracking-tight',
+ },
+ },
+});
+
+export function HeadingElementStatic({
+ variant = 'h1',
+ ...props
+}: SlateElementProps & VariantProps) {
+ const id = props.element.id as string | undefined;
+
+ return (
+
+ {/* Bookmark anchor for DOCX TOC internal links */}
+ {id && }
+ {props.children}
+
+ );
+}
+
+export function H1ElementStatic(props: SlateElementProps) {
+ return ;
+}
+
+export function H2ElementStatic(
+ props: React.ComponentProps
+) {
+ return ;
+}
+
+export function H3ElementStatic(
+ props: React.ComponentProps
+) {
+ return ;
+}
+
+export function H4ElementStatic(
+ props: React.ComponentProps
+) {
+ return ;
+}
+
+export function H5ElementStatic(
+ props: React.ComponentProps
+) {
+ return ;
+}
+
+export function H6ElementStatic(
+ props: React.ComponentProps
+) {
+ return ;
+}
diff --git a/surfsense_web/components/ui/heading-node.tsx b/surfsense_web/components/ui/heading-node.tsx
new file mode 100644
index 000000000..3713b6aed
--- /dev/null
+++ b/surfsense_web/components/ui/heading-node.tsx
@@ -0,0 +1,60 @@
+'use client';
+
+import * as React from 'react';
+
+import type { PlateElementProps } from 'platejs/react';
+
+import { type VariantProps, cva } from 'class-variance-authority';
+import { PlateElement } from 'platejs/react';
+
+const headingVariants = cva('relative mb-1', {
+ variants: {
+ variant: {
+ h1: 'mt-[1.6em] pb-1 font-bold font-heading text-4xl',
+ h2: 'mt-[1.4em] pb-px font-heading font-semibold text-2xl tracking-tight',
+ h3: 'mt-[1em] pb-px font-heading font-semibold text-xl tracking-tight',
+ h4: 'mt-[0.75em] font-heading font-semibold text-lg tracking-tight',
+ h5: 'mt-[0.75em] font-semibold text-lg tracking-tight',
+ h6: 'mt-[0.75em] font-semibold text-base tracking-tight',
+ },
+ },
+});
+
+export function HeadingElement({
+ variant = 'h1',
+ ...props
+}: PlateElementProps & VariantProps) {
+ return (
+
+ {props.children}
+
+ );
+}
+
+export function H1Element(props: PlateElementProps) {
+ return ;
+}
+
+export function H2Element(props: PlateElementProps) {
+ return ;
+}
+
+export function H3Element(props: PlateElementProps) {
+ return ;
+}
+
+export function H4Element(props: PlateElementProps) {
+ return ;
+}
+
+export function H5Element(props: PlateElementProps) {
+ return ;
+}
+
+export function H6Element(props: PlateElementProps) {
+ return ;
+}
diff --git a/surfsense_web/components/ui/highlight-node-static.tsx b/surfsense_web/components/ui/highlight-node-static.tsx
new file mode 100644
index 000000000..32b67be17
--- /dev/null
+++ b/surfsense_web/components/ui/highlight-node-static.tsx
@@ -0,0 +1,13 @@
+import * as React from 'react';
+
+import type { SlateLeafProps } from 'platejs/static';
+
+import { SlateLeaf } from 'platejs/static';
+
+export function HighlightLeafStatic(props: SlateLeafProps) {
+ return (
+
+ {props.children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/highlight-node.tsx b/surfsense_web/components/ui/highlight-node.tsx
new file mode 100644
index 000000000..536e89abf
--- /dev/null
+++ b/surfsense_web/components/ui/highlight-node.tsx
@@ -0,0 +1,15 @@
+'use client';
+
+import * as React from 'react';
+
+import type { PlateLeafProps } from 'platejs/react';
+
+import { PlateLeaf } from 'platejs/react';
+
+export function HighlightLeaf(props: PlateLeafProps) {
+ return (
+
+ {props.children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/hr-node-static.tsx b/surfsense_web/components/ui/hr-node-static.tsx
new file mode 100644
index 000000000..c449fbfb6
--- /dev/null
+++ b/surfsense_web/components/ui/hr-node-static.tsx
@@ -0,0 +1,22 @@
+import * as React from 'react';
+
+import type { SlateElementProps } from 'platejs/static';
+
+import { SlateElement } from 'platejs/static';
+
+import { cn } from '@/lib/utils';
+
+export function HrElementStatic(props: SlateElementProps) {
+ return (
+
+
+
+
+ {props.children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/hr-node.tsx b/surfsense_web/components/ui/hr-node.tsx
new file mode 100644
index 000000000..3e86f1ab9
--- /dev/null
+++ b/surfsense_web/components/ui/hr-node.tsx
@@ -0,0 +1,35 @@
+'use client';
+
+import * as React from 'react';
+
+import type { PlateElementProps } from 'platejs/react';
+
+import {
+ PlateElement,
+ useFocused,
+ useReadOnly,
+ useSelected,
+} from 'platejs/react';
+
+import { cn } from '@/lib/utils';
+
+export function HrElement(props: PlateElementProps) {
+ const readOnly = useReadOnly();
+ const selected = useSelected();
+ const focused = useFocused();
+
+ return (
+
+
+
+
+ {props.children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/kbd-node-static.tsx b/surfsense_web/components/ui/kbd-node-static.tsx
new file mode 100644
index 000000000..5dd19ccbf
--- /dev/null
+++ b/surfsense_web/components/ui/kbd-node-static.tsx
@@ -0,0 +1,17 @@
+import * as React from 'react';
+
+import type { SlateLeafProps } from 'platejs/static';
+
+import { SlateLeaf } from 'platejs/static';
+
+export function KbdLeafStatic(props: SlateLeafProps) {
+ return (
+
+ {props.children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/kbd-node.tsx b/surfsense_web/components/ui/kbd-node.tsx
new file mode 100644
index 000000000..65ca86d34
--- /dev/null
+++ b/surfsense_web/components/ui/kbd-node.tsx
@@ -0,0 +1,19 @@
+'use client';
+
+import * as React from 'react';
+
+import type { PlateLeafProps } from 'platejs/react';
+
+import { PlateLeaf } from 'platejs/react';
+
+export function KbdLeaf(props: PlateLeafProps) {
+ return (
+
+ {props.children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/link-node-static.tsx b/surfsense_web/components/ui/link-node-static.tsx
new file mode 100644
index 000000000..1c2f32d19
--- /dev/null
+++ b/surfsense_web/components/ui/link-node-static.tsx
@@ -0,0 +1,23 @@
+import * as React from 'react';
+
+import type { TLinkElement } from 'platejs';
+import type { SlateElementProps } from 'platejs/static';
+
+import { getLinkAttributes } from '@platejs/link';
+import { SlateElement } from 'platejs/static';
+
+export function LinkElementStatic(props: SlateElementProps) {
+ return (
+
+ {props.children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/link-node.tsx b/surfsense_web/components/ui/link-node.tsx
new file mode 100644
index 000000000..0fddec3b3
--- /dev/null
+++ b/surfsense_web/components/ui/link-node.tsx
@@ -0,0 +1,32 @@
+'use client';
+
+import * as React from 'react';
+
+import type { TLinkElement } from 'platejs';
+import type { PlateElementProps } from 'platejs/react';
+
+import { getLinkAttributes } from '@platejs/link';
+import { PlateElement } from 'platejs/react';
+
+import { cn } from '@/lib/utils';
+
+export function LinkElement(props: PlateElementProps) {
+ return (
+ {
+ e.stopPropagation();
+ },
+ }}
+ >
+ {props.children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/link-toolbar-button.tsx b/surfsense_web/components/ui/link-toolbar-button.tsx
new file mode 100644
index 000000000..1e655e7f7
--- /dev/null
+++ b/surfsense_web/components/ui/link-toolbar-button.tsx
@@ -0,0 +1,24 @@
+'use client';
+
+import * as React from 'react';
+
+import {
+ useLinkToolbarButton,
+ useLinkToolbarButtonState,
+} from '@platejs/link/react';
+import { Link } from 'lucide-react';
+
+import { ToolbarButton } from './toolbar';
+
+export function LinkToolbarButton(
+ props: React.ComponentProps
+) {
+ const state = useLinkToolbarButtonState();
+ const { props: buttonProps } = useLinkToolbarButton(state);
+
+ return (
+
+
+
+ );
+}
diff --git a/surfsense_web/components/ui/link-toolbar.tsx b/surfsense_web/components/ui/link-toolbar.tsx
new file mode 100644
index 000000000..ba9611fa4
--- /dev/null
+++ b/surfsense_web/components/ui/link-toolbar.tsx
@@ -0,0 +1,208 @@
+'use client';
+
+import * as React from 'react';
+
+import type { TLinkElement } from 'platejs';
+
+import {
+ type UseVirtualFloatingOptions,
+ flip,
+ offset,
+} from '@platejs/floating';
+import { getLinkAttributes } from '@platejs/link';
+import {
+ type LinkFloatingToolbarState,
+ FloatingLinkUrlInput,
+ useFloatingLinkEdit,
+ useFloatingLinkEditState,
+ useFloatingLinkInsert,
+ useFloatingLinkInsertState,
+} from '@platejs/link/react';
+import { cva } from 'class-variance-authority';
+import { ExternalLink, Link, Text, Unlink } from 'lucide-react';
+import { KEYS } from 'platejs';
+import {
+ useEditorRef,
+ useEditorSelection,
+ useFormInputProps,
+ usePluginOption,
+} from 'platejs/react';
+
+import { buttonVariants } from '@/components/ui/button';
+import { Separator } from '@/components/ui/separator';
+
+const popoverVariants = cva(
+ 'z-50 w-auto rounded-md border bg-popover p-1 text-popover-foreground shadow-md outline-hidden'
+);
+
+const inputVariants = cva(
+ 'flex h-[28px] w-full rounded-md border-none bg-transparent px-1.5 py-1 text-base placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-transparent md:text-sm'
+);
+
+export function LinkFloatingToolbar({
+ state,
+}: {
+ state?: LinkFloatingToolbarState;
+}) {
+ const activeCommentId = usePluginOption({ key: KEYS.comment }, 'activeId');
+ const activeSuggestionId = usePluginOption(
+ { key: KEYS.suggestion },
+ 'activeId'
+ );
+
+ const floatingOptions: UseVirtualFloatingOptions = React.useMemo(
+ () => ({
+ middleware: [
+ offset(8),
+ flip({
+ fallbackPlacements: ['bottom-end', 'top-start', 'top-end'],
+ padding: 12,
+ }),
+ ],
+ placement:
+ activeSuggestionId || activeCommentId ? 'top-start' : 'bottom-start',
+ }),
+ [activeCommentId, activeSuggestionId]
+ );
+
+ const insertState = useFloatingLinkInsertState({
+ ...state,
+ floatingOptions: {
+ ...floatingOptions,
+ ...state?.floatingOptions,
+ },
+ });
+ const {
+ hidden,
+ props: insertProps,
+ ref: insertRef,
+ textInputProps,
+ } = useFloatingLinkInsert(insertState);
+
+ const editState = useFloatingLinkEditState({
+ ...state,
+ floatingOptions: {
+ ...floatingOptions,
+ ...state?.floatingOptions,
+ },
+ });
+ const {
+ editButtonProps,
+ props: editProps,
+ ref: editRef,
+ unlinkButtonProps,
+ } = useFloatingLinkEdit(editState);
+ const inputProps = useFormInputProps({
+ preventDefaultOnEnterKeydown: true,
+ });
+
+ if (hidden) return null;
+
+ const input = (
+
+ );
+
+ const editContent = editState.isEditing ? (
+ input
+ ) : (
+
+
+
+
+
+
+
+
+
+
+
+ );
+
+ return (
+ <>
+
+ {input}
+
+
+
+ {editContent}
+
+ >
+ );
+}
+
+function LinkOpenButton() {
+ const editor = useEditorRef();
+ const selection = useEditorSelection();
+
+ const attributes = React.useMemo(
+ () => {
+ const entry = editor.api.node({
+ match: { type: editor.getType(KEYS.link) },
+ });
+ if (!entry) {
+ return {};
+ }
+ const [element] = entry;
+ return getLinkAttributes(editor, element);
+ },
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ [editor, selection]
+ );
+
+ return (
+ {
+ e.stopPropagation();
+ }}
+ aria-label="Open link in a new tab"
+ target="_blank"
+ >
+
+
+ );
+}
diff --git a/surfsense_web/components/ui/list-classic-node.tsx b/surfsense_web/components/ui/list-classic-node.tsx
new file mode 100644
index 000000000..2146c6b5d
--- /dev/null
+++ b/surfsense_web/components/ui/list-classic-node.tsx
@@ -0,0 +1,105 @@
+'use client';
+
+import * as React from 'react';
+
+import type { PlateElementProps } from 'platejs/react';
+
+import {
+ useTodoListElement,
+ useTodoListElementState,
+} from '@platejs/list-classic/react';
+import { type VariantProps, cva } from 'class-variance-authority';
+import { PlateElement } from 'platejs/react';
+
+import { Checkbox } from '@/components/ui/checkbox';
+import { cn } from '@/lib/utils';
+
+const listVariants = cva('m-0 py-1 ps-6', {
+ variants: {
+ variant: {
+ ol: 'list-decimal',
+ ul: 'list-disc [&_ul]:list-[circle] [&_ul_ul]:list-[square]',
+ },
+ },
+});
+
+export function ListElement({
+ variant,
+ ...props
+}: PlateElementProps & VariantProps) {
+ return (
+
+ {props.children}
+
+ );
+}
+
+export function BulletedListElement(props: PlateElementProps) {
+ return ;
+}
+
+export function NumberedListElement(props: PlateElementProps) {
+ return ;
+}
+
+export function TaskListElement(props: PlateElementProps) {
+ return (
+
+ {props.children}
+
+ );
+}
+
+export function ListItemElement(props: PlateElementProps) {
+ const isTaskList = 'checked' in props.element;
+
+ if (isTaskList) {
+ return ;
+ }
+
+ return ;
+}
+
+export function BaseListItemElement(props: PlateElementProps) {
+ return (
+
+ {props.children}
+
+ );
+}
+
+export function TaskListItemElement(props: PlateElementProps) {
+ const { element } = props;
+ const state = useTodoListElementState({ element });
+ const { checkboxProps } = useTodoListElement(state);
+ const [firstChild, ...otherChildren] = React.Children.toArray(props.children);
+
+ return (
+
+
+
+ {otherChildren}
+
+ );
+}
diff --git a/surfsense_web/components/ui/list-classic-toolbar-button.tsx b/surfsense_web/components/ui/list-classic-toolbar-button.tsx
new file mode 100644
index 000000000..780047c7b
--- /dev/null
+++ b/surfsense_web/components/ui/list-classic-toolbar-button.tsx
@@ -0,0 +1,69 @@
+'use client';
+
+import * as React from 'react';
+
+import { indentListItems, unindentListItems } from '@platejs/list-classic';
+import {
+ useListToolbarButton,
+ useListToolbarButtonState,
+} from '@platejs/list-classic/react';
+import {
+ IndentIcon,
+ List,
+ ListOrdered,
+ ListTodo,
+ OutdentIcon,
+} from 'lucide-react';
+import { KEYS } from 'platejs';
+import { useEditorRef } from 'platejs/react';
+
+import { ToolbarButton } from './toolbar';
+
+const nodeTypeMap: Record =
+ {
+ [KEYS.olClassic]: { icon: , label: 'Numbered List' },
+ [KEYS.taskList]: { icon: , label: 'Task List' },
+ [KEYS.ulClassic]: { icon:
, label: 'Bulleted List' },
+ };
+
+export function ListToolbarButton({
+ nodeType = KEYS.ulClassic,
+ ...props
+}: React.ComponentProps & {
+ nodeType?: string;
+}) {
+ const state = useListToolbarButtonState({ nodeType });
+ const { props: buttonProps } = useListToolbarButton(state);
+ const { icon, label } = nodeTypeMap[nodeType] ?? nodeTypeMap[KEYS.ulClassic];
+
+ return (
+
+ {icon}
+
+ );
+}
+
+export function IndentToolbarButton({
+ reverse = false,
+ ...props
+}: React.ComponentProps & {
+ reverse?: boolean;
+}) {
+ const editor = useEditorRef();
+
+ return (
+ {
+ if (reverse) {
+ unindentListItems(editor);
+ } else {
+ indentListItems(editor);
+ }
+ }}
+ tooltip={reverse ? 'Outdent' : 'Indent'}
+ >
+ {reverse ? : }
+
+ );
+}
diff --git a/surfsense_web/components/ui/mark-toolbar-button.tsx b/surfsense_web/components/ui/mark-toolbar-button.tsx
new file mode 100644
index 000000000..1f9405756
--- /dev/null
+++ b/surfsense_web/components/ui/mark-toolbar-button.tsx
@@ -0,0 +1,21 @@
+'use client';
+
+import * as React from 'react';
+
+import { useMarkToolbarButton, useMarkToolbarButtonState } from 'platejs/react';
+
+import { ToolbarButton } from './toolbar';
+
+export function MarkToolbarButton({
+ clear,
+ nodeType,
+ ...props
+}: React.ComponentProps & {
+ nodeType: string;
+ clear?: string[] | string;
+}) {
+ const state = useMarkToolbarButtonState({ clear, nodeType });
+ const { props: buttonProps } = useMarkToolbarButton(state);
+
+ return ;
+}
diff --git a/surfsense_web/components/ui/more-toolbar-button.tsx b/surfsense_web/components/ui/more-toolbar-button.tsx
new file mode 100644
index 000000000..c24a242d7
--- /dev/null
+++ b/surfsense_web/components/ui/more-toolbar-button.tsx
@@ -0,0 +1,108 @@
+'use client';
+
+import * as React from 'react';
+
+import type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';
+
+import { insertInlineEquation } from '@platejs/math';
+import {
+ InfoIcon,
+ KeyboardIcon,
+ MoreHorizontalIcon,
+ RadicalIcon,
+ SubscriptIcon,
+ SuperscriptIcon,
+} from 'lucide-react';
+import { KEYS } from 'platejs';
+import { useEditorRef } from 'platejs/react';
+
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from '@/components/ui/dropdown-menu';
+
+import { ToolbarButton } from './toolbar';
+
+export function MoreToolbarButton(props: DropdownMenuProps) {
+ const editor = useEditorRef();
+ const [open, setOpen] = React.useState(false);
+
+ return (
+
+
+
+
+
+
+
+
+
+ {
+ editor.tf.toggleMark(KEYS.kbd);
+ editor.tf.collapse({ edge: 'end' });
+ editor.tf.focus();
+ }}
+ >
+
+ Keyboard input
+
+
+ {
+ editor.tf.toggleMark(KEYS.sup, {
+ remove: KEYS.sub,
+ });
+ editor.tf.focus();
+ }}
+ >
+
+ Superscript
+ {/* (⌘+,) */}
+
+ {
+ editor.tf.toggleMark(KEYS.sub, {
+ remove: KEYS.sup,
+ });
+ editor.tf.focus();
+ }}
+ >
+
+ Subscript
+ {/* (⌘+.) */}
+
+
+ {
+ insertInlineEquation(editor);
+ editor.tf.focus();
+ }}
+ >
+
+ Equation
+
+
+ {
+ editor.tf.insertNodes(
+ editor.api.create.block({ type: KEYS.callout }),
+ { select: true }
+ );
+ editor.tf.focus();
+ }}
+ >
+
+ Callout
+
+
+
+
+ );
+}
diff --git a/surfsense_web/components/ui/paragraph-node-static.tsx b/surfsense_web/components/ui/paragraph-node-static.tsx
new file mode 100644
index 000000000..c5a6cf85c
--- /dev/null
+++ b/surfsense_web/components/ui/paragraph-node-static.tsx
@@ -0,0 +1,15 @@
+import * as React from 'react';
+
+import type { SlateElementProps } from 'platejs/static';
+
+import { SlateElement } from 'platejs/static';
+
+import { cn } from '@/lib/utils';
+
+export function ParagraphElementStatic(props: SlateElementProps) {
+ return (
+
+ {props.children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/paragraph-node.tsx b/surfsense_web/components/ui/paragraph-node.tsx
new file mode 100644
index 000000000..e4004049f
--- /dev/null
+++ b/surfsense_web/components/ui/paragraph-node.tsx
@@ -0,0 +1,17 @@
+'use client';
+
+import * as React from 'react';
+
+import type { PlateElementProps } from 'platejs/react';
+
+import { PlateElement } from 'platejs/react';
+
+import { cn } from '@/lib/utils';
+
+export function ParagraphElement(props: PlateElementProps) {
+ return (
+
+ {props.children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/resize-handle.tsx b/surfsense_web/components/ui/resize-handle.tsx
new file mode 100644
index 000000000..73f42a1b5
--- /dev/null
+++ b/surfsense_web/components/ui/resize-handle.tsx
@@ -0,0 +1,89 @@
+'use client';
+
+import * as React from 'react';
+
+import type { VariantProps } from 'class-variance-authority';
+
+import {
+ type ResizeHandle as ResizeHandlePrimitive,
+ Resizable as ResizablePrimitive,
+ useResizeHandle,
+ useResizeHandleState,
+} from '@platejs/resizable';
+import { cva } from 'class-variance-authority';
+
+import { cn } from '@/lib/utils';
+
+export const mediaResizeHandleVariants = cva(
+ cn(
+ 'top-0 flex w-6 select-none flex-col justify-center',
+ "after:flex after:h-16 after:w-[3px] after:rounded-[6px] after:bg-ring after:opacity-0 after:content-['_'] group-hover:after:opacity-100"
+ ),
+ {
+ variants: {
+ direction: {
+ left: '-left-3 -ml-3 pl-3',
+ right: '-right-3 -mr-3 items-end pr-3',
+ },
+ },
+ }
+);
+
+const resizeHandleVariants = cva('absolute z-40', {
+ variants: {
+ direction: {
+ bottom: 'w-full cursor-row-resize',
+ left: 'h-full cursor-col-resize',
+ right: 'h-full cursor-col-resize',
+ top: 'w-full cursor-row-resize',
+ },
+ },
+});
+
+export function ResizeHandle({
+ className,
+ options,
+ ...props
+}: React.ComponentProps &
+ VariantProps) {
+ const state = useResizeHandleState(options ?? {});
+ const resizeHandle = useResizeHandle(state);
+
+ if (state.readOnly) return null;
+
+ return (
+
+ );
+}
+
+const resizableVariants = cva('', {
+ variants: {
+ align: {
+ center: 'mx-auto',
+ left: 'mr-auto',
+ right: 'ml-auto',
+ },
+ },
+});
+
+export function Resizable({
+ align,
+ className,
+ ...props
+}: React.ComponentProps &
+ VariantProps) {
+ return (
+
+ );
+}
diff --git a/surfsense_web/components/ui/slash-node.tsx b/surfsense_web/components/ui/slash-node.tsx
new file mode 100644
index 000000000..b04118907
--- /dev/null
+++ b/surfsense_web/components/ui/slash-node.tsx
@@ -0,0 +1,211 @@
+'use client';
+
+import * as React from 'react';
+
+import type { PlateElementProps } from 'platejs/react';
+
+import { SlashInputPlugin } from '@platejs/slash-command/react';
+import {
+ ChevronRightIcon,
+ Code2Icon,
+ Columns2Icon,
+ FileCodeIcon,
+ Heading1Icon,
+ Heading2Icon,
+ Heading3Icon,
+ InfoIcon,
+ ListIcon,
+ ListOrderedIcon,
+ MinusIcon,
+ PilcrowIcon,
+ QuoteIcon,
+ RadicalIcon,
+ SquareIcon,
+ TableIcon,
+} from 'lucide-react';
+import { KEYS } from 'platejs';
+import { PlateElement, useEditorPlugin, useEditorRef } from 'platejs/react';
+
+import {
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList,
+} from '@/components/ui/command';
+import { insertBlock, insertInlineElement } from '@/components/editor/transforms';
+
+interface SlashCommandItem {
+ icon: React.ReactNode;
+ keywords: string[];
+ label: string;
+ onSelect: (editor: any) => void;
+}
+
+const slashCommandGroups: { heading: string; items: SlashCommandItem[] }[] = [
+ {
+ heading: 'Basic Blocks',
+ items: [
+ {
+ icon: ,
+ keywords: ['paragraph', 'text', 'plain'],
+ label: 'Text',
+ onSelect: (editor) => insertBlock(editor, KEYS.p),
+ },
+ {
+ icon: ,
+ keywords: ['title', 'h1', 'heading'],
+ label: 'Heading 1',
+ onSelect: (editor) => insertBlock(editor, 'h1'),
+ },
+ {
+ icon: ,
+ keywords: ['subtitle', 'h2', 'heading'],
+ label: 'Heading 2',
+ onSelect: (editor) => insertBlock(editor, 'h2'),
+ },
+ {
+ icon: ,
+ keywords: ['subtitle', 'h3', 'heading'],
+ label: 'Heading 3',
+ onSelect: (editor) => insertBlock(editor, 'h3'),
+ },
+ {
+ icon: ,
+ keywords: ['citation', 'blockquote'],
+ label: 'Quote',
+ onSelect: (editor) => insertBlock(editor, KEYS.blockquote),
+ },
+ {
+ icon: ,
+ keywords: ['divider', 'separator', 'line'],
+ label: 'Divider',
+ onSelect: (editor) => insertBlock(editor, KEYS.hr),
+ },
+ ],
+ },
+ {
+ heading: 'Lists',
+ items: [
+ {
+ icon: ,
+ keywords: ['unordered', 'ul', 'bullet'],
+ label: 'Bulleted list',
+ onSelect: (editor) => insertBlock(editor, KEYS.ul),
+ },
+ {
+ icon: ,
+ keywords: ['ordered', 'ol', 'numbered'],
+ label: 'Numbered list',
+ onSelect: (editor) => insertBlock(editor, KEYS.ol),
+ },
+ {
+ icon: ,
+ keywords: ['checklist', 'task', 'checkbox', 'todo'],
+ label: 'To-do list',
+ onSelect: (editor) => insertBlock(editor, KEYS.listTodo),
+ },
+ ],
+ },
+ {
+ heading: 'Advanced',
+ items: [
+ {
+ icon: ,
+ keywords: ['table', 'grid'],
+ label: 'Table',
+ onSelect: (editor) => insertBlock(editor, KEYS.table),
+ },
+ {
+ icon: ,
+ keywords: ['code', 'codeblock', 'snippet'],
+ label: 'Code block',
+ onSelect: (editor) => insertBlock(editor, KEYS.codeBlock),
+ },
+ {
+ icon: ,
+ keywords: ['callout', 'note', 'info', 'warning', 'tip'],
+ label: 'Callout',
+ onSelect: (editor) => insertBlock(editor, KEYS.callout),
+ },
+ {
+ icon: ,
+ keywords: ['toggle', 'collapsible', 'expand'],
+ label: 'Toggle',
+ onSelect: (editor) => insertBlock(editor, KEYS.toggle),
+ },
+ {
+ icon: ,
+ keywords: ['equation', 'math', 'formula', 'latex'],
+ label: 'Equation',
+ onSelect: (editor) => insertInlineElement(editor, KEYS.equation),
+ },
+ ],
+ },
+ {
+ heading: 'Inline',
+ items: [
+ {
+ icon: ,
+ keywords: ['link', 'url', 'href'],
+ label: 'Link',
+ onSelect: (editor) => insertInlineElement(editor, KEYS.link),
+ },
+ ],
+ },
+];
+
+export function SlashInputElement({
+ children,
+ ...props
+}: PlateElementProps) {
+ const { editor, setOption } = useEditorPlugin(SlashInputPlugin);
+
+ return (
+
+
+ {
+ // The value is managed by the slash input plugin
+ }}
+ autoFocus
+ />
+
+ No results found.
+ {slashCommandGroups.map(({ heading, items }) => (
+
+ {items.map(({ icon, keywords, label, onSelect }) => (
+ {
+ editor.tf.removeNodes({
+ match: (n) => (n as any).type === SlashInputPlugin.key,
+ });
+ onSelect(editor);
+ editor.tf.focus();
+ }}
+ >
+
+ {icon}
+
+ {label}
+
+ ))}
+
+ ))}
+
+
+ {children}
+
+ );
+}
+
diff --git a/surfsense_web/components/ui/table-icons.tsx b/surfsense_web/components/ui/table-icons.tsx
new file mode 100644
index 000000000..e08578912
--- /dev/null
+++ b/surfsense_web/components/ui/table-icons.tsx
@@ -0,0 +1,862 @@
+'use client';
+
+import type { LucideProps } from 'lucide-react';
+
+export function BorderAllIcon(props: LucideProps) {
+ return (
+
+ );
+}
+
+export function BorderBottomIcon(props: LucideProps) {
+ return (
+
+ );
+}
+
+export function BorderLeftIcon(props: LucideProps) {
+ return (
+
+ );
+}
+
+export function BorderNoneIcon(props: LucideProps) {
+ return (
+
+ );
+}
+
+export function BorderRightIcon(props: LucideProps) {
+ return (
+
+ );
+}
+
+export function BorderTopIcon(props: LucideProps) {
+ return (
+
+ );
+}
diff --git a/surfsense_web/components/ui/table-node-static.tsx b/surfsense_web/components/ui/table-node-static.tsx
new file mode 100644
index 000000000..c794b07b2
--- /dev/null
+++ b/surfsense_web/components/ui/table-node-static.tsx
@@ -0,0 +1,101 @@
+import * as React from 'react';
+
+import type { TTableCellElement, TTableElement } from 'platejs';
+import type { SlateElementProps } from 'platejs/static';
+
+import { BaseTablePlugin } from '@platejs/table';
+import { SlateElement } from 'platejs/static';
+
+import { cn } from '@/lib/utils';
+
+export function TableElementStatic({
+ children,
+ ...props
+}: SlateElementProps) {
+ const { disableMarginLeft } = props.editor.getOptions(BaseTablePlugin);
+ const marginLeft = disableMarginLeft ? 0 : props.element.marginLeft;
+
+ return (
+
+
+
+ );
+}
+
+export function TableRowElementStatic(props: SlateElementProps) {
+ return (
+
+ {props.children}
+
+ );
+}
+
+export function TableCellElementStatic({
+ isHeader,
+ ...props
+}: SlateElementProps & {
+ isHeader?: boolean;
+}) {
+ const { editor, element } = props;
+ const { api } = editor.getPlugin(BaseTablePlugin);
+
+ const { minHeight, width } = api.table.getCellSize({ element });
+ const borders = api.table.getCellBorders({ element });
+
+ return (
+
+
+ {props.children}
+
+
+ );
+}
+
+export function TableCellHeaderElementStatic(
+ props: SlateElementProps
+) {
+ return ;
+}
diff --git a/surfsense_web/components/ui/table-node.tsx b/surfsense_web/components/ui/table-node.tsx
new file mode 100644
index 000000000..dd6b4c25e
--- /dev/null
+++ b/surfsense_web/components/ui/table-node.tsx
@@ -0,0 +1,657 @@
+'use client';
+
+import * as React from 'react';
+
+import type * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
+
+import { useDraggable, useDropLine } from '@platejs/dnd';
+import {
+ BlockSelectionPlugin,
+ useBlockSelected,
+} from '@platejs/selection/react';
+import { setCellBackground } from '@platejs/table';
+import {
+ TablePlugin,
+ TableProvider,
+ useTableBordersDropdownMenuContentState,
+ useTableCellElement,
+ useTableCellElementResizable,
+ useTableElement,
+ useTableMergeState,
+} from '@platejs/table/react';
+import { PopoverAnchor } from '@radix-ui/react-popover';
+import { cva } from 'class-variance-authority';
+import {
+ ArrowDown,
+ ArrowLeft,
+ ArrowRight,
+ ArrowUp,
+ CombineIcon,
+ EraserIcon,
+ Grid2X2Icon,
+ GripVertical,
+ PaintBucketIcon,
+ SquareSplitHorizontalIcon,
+ Trash2Icon,
+ XIcon,
+} from 'lucide-react';
+import {
+ type TElement,
+ type TTableCellElement,
+ type TTableElement,
+ type TTableRowElement,
+ KEYS,
+ PathApi,
+} from 'platejs';
+import {
+ type PlateElementProps,
+ PlateElement,
+ useComposedRef,
+ useEditorPlugin,
+ useEditorRef,
+ useEditorSelector,
+ useElement,
+ useFocusedLast,
+ usePluginOption,
+ useReadOnly,
+ useRemoveNodeButton,
+ useSelected,
+ withHOC,
+} from 'platejs/react';
+import { useElementSelector } from 'platejs/react';
+
+import { Button } from '@/components/ui/button';
+import {
+ DropdownMenu,
+ DropdownMenuCheckboxItem,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuItem,
+ DropdownMenuPortal,
+ DropdownMenuTrigger,
+} from '@/components/ui/dropdown-menu';
+import { Popover, PopoverContent } from '@/components/ui/popover';
+import { cn } from '@/lib/utils';
+
+import { blockSelectionVariants } from './block-selection';
+import {
+ ColorDropdownMenuItems,
+ DEFAULT_COLORS,
+} from './font-color-toolbar-button';
+import { ResizeHandle } from './resize-handle';
+import {
+ BorderAllIcon,
+ BorderBottomIcon,
+ BorderLeftIcon,
+ BorderNoneIcon,
+ BorderRightIcon,
+ BorderTopIcon,
+} from './table-icons';
+import {
+ Toolbar,
+ ToolbarButton,
+ ToolbarGroup,
+ ToolbarMenuGroup,
+} from './toolbar';
+export const TableElement = withHOC(
+ TableProvider,
+ function TableElement({
+ children,
+ ...props
+ }: PlateElementProps) {
+ const readOnly = useReadOnly();
+ const isSelectionAreaVisible = usePluginOption(
+ BlockSelectionPlugin,
+ 'isSelectionAreaVisible'
+ );
+ const hasControls = !readOnly && !isSelectionAreaVisible;
+ const {
+ isSelectingCell,
+ marginLeft,
+ props: tableProps,
+ } = useTableElement();
+
+ const isSelectingTable = useBlockSelected(props.element.id as string);
+
+ const content = (
+
+
+
+
+ {isSelectingTable && (
+
+ )}
+
+
+ );
+
+ if (readOnly) {
+ return content;
+ }
+
+ return {content};
+ }
+);
+
+function TableFloatingToolbar({
+ children,
+ ...props
+}: React.ComponentProps) {
+ const { tf } = useEditorPlugin(TablePlugin);
+ const selected = useSelected();
+ const element = useElement();
+ const { props: buttonProps } = useRemoveNodeButton({ element });
+ const collapsedInside = useEditorSelector(
+ (editor) => selected && editor.api.isCollapsed(),
+ [selected]
+ );
+ const isFocusedLast = useFocusedLast();
+
+ const { canMerge, canSplit } = useTableMergeState();
+
+ return (
+
+ {children}
+ e.preventDefault()}
+ contentEditable={false}
+ {...props}
+ >
+
+
+
+
+
+ {canMerge && (
+ tf.table.merge()}
+ onMouseDown={(e) => e.preventDefault()}
+ tooltip="Merge cells"
+ >
+
+
+ )}
+ {canSplit && (
+ tf.table.split()}
+ onMouseDown={(e) => e.preventDefault()}
+ tooltip="Split cell"
+ >
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {collapsedInside && (
+
+
+
+
+
+ )}
+
+
+ {collapsedInside && (
+
+ {
+ tf.insert.tableRow({ before: true });
+ }}
+ onMouseDown={(e) => e.preventDefault()}
+ tooltip="Insert row before"
+ >
+
+
+ {
+ tf.insert.tableRow();
+ }}
+ onMouseDown={(e) => e.preventDefault()}
+ tooltip="Insert row after"
+ >
+
+
+ {
+ tf.remove.tableRow();
+ }}
+ onMouseDown={(e) => e.preventDefault()}
+ tooltip="Delete row"
+ >
+
+
+
+ )}
+
+ {collapsedInside && (
+
+ {
+ tf.insert.tableColumn({ before: true });
+ }}
+ onMouseDown={(e) => e.preventDefault()}
+ tooltip="Insert column before"
+ >
+
+
+ {
+ tf.insert.tableColumn();
+ }}
+ onMouseDown={(e) => e.preventDefault()}
+ tooltip="Insert column after"
+ >
+
+
+ {
+ tf.remove.tableColumn();
+ }}
+ onMouseDown={(e) => e.preventDefault()}
+ tooltip="Delete column"
+ >
+
+
+
+ )}
+
+
+
+ );
+}
+
+function TableBordersDropdownMenuContent(
+ props: React.ComponentProps
+) {
+ const editor = useEditorRef();
+ const {
+ getOnSelectTableBorder,
+ hasBottomBorder,
+ hasLeftBorder,
+ hasNoBorders,
+ hasOuterBorders,
+ hasRightBorder,
+ hasTopBorder,
+ } = useTableBordersDropdownMenuContentState();
+
+ return (
+ {
+ e.preventDefault();
+ editor.tf.focus();
+ }}
+ align="start"
+ side="right"
+ sideOffset={0}
+ {...props}
+ >
+
+
+
+ Top Border
+
+
+
+ Right Border
+
+
+
+ Bottom Border
+
+
+
+ Left Border
+
+
+
+
+
+
+ No Border
+
+
+
+ Outside Borders
+
+
+
+ );
+}
+
+function ColorDropdownMenu({
+ children,
+ tooltip,
+}: {
+ children: React.ReactNode;
+ tooltip: string;
+}) {
+ const [open, setOpen] = React.useState(false);
+
+ const editor = useEditorRef();
+ const selectedCells = usePluginOption(TablePlugin, 'selectedCells');
+
+ const onUpdateColor = React.useCallback(
+ (color: string) => {
+ setOpen(false);
+ setCellBackground(editor, { color, selectedCells: selectedCells ?? [] });
+ },
+ [selectedCells, editor]
+ );
+
+ const onClearColor = React.useCallback(() => {
+ setOpen(false);
+ setCellBackground(editor, {
+ color: null,
+ selectedCells: selectedCells ?? [],
+ });
+ }, [selectedCells, editor]);
+
+ return (
+
+
+ {children}
+
+
+
+
+
+
+
+
+
+ Clear
+
+
+
+
+ );
+}
+
+export function TableRowElement({
+ children,
+ ...props
+}: PlateElementProps) {
+ const { element } = props;
+ const readOnly = useReadOnly();
+ const selected = useSelected();
+ const editor = useEditorRef();
+ const isSelectionAreaVisible = usePluginOption(
+ BlockSelectionPlugin,
+ 'isSelectionAreaVisible'
+ );
+ const hasControls = !readOnly && !isSelectionAreaVisible;
+
+ const { isDragging, nodeRef, previewRef, handleRef } = useDraggable({
+ element,
+ type: element.type,
+ canDropNode: ({ dragEntry, dropEntry }) =>
+ PathApi.equals(
+ PathApi.parent(dragEntry[1]),
+ PathApi.parent(dropEntry[1])
+ ),
+ onDropHandler: (_, { dragItem }) => {
+ const dragElement = (dragItem as { element: TElement }).element;
+
+ if (dragElement) {
+ editor.tf.select(dragElement);
+ }
+ },
+ });
+
+ return (
+
+ {hasControls && (
+
+
+
+ |
+ )}
+
+ {children}
+
+ );
+}
+
+function RowDragHandle({ dragRef }: { dragRef: React.Ref }) {
+ const editor = useEditorRef();
+ const element = useElement();
+
+ return (
+
+ );
+}
+
+function RowDropLine() {
+ const { dropLine } = useDropLine();
+
+ if (!dropLine) return null;
+
+ return (
+
+ );
+}
+
+export function TableCellElement({
+ isHeader,
+ ...props
+}: PlateElementProps & {
+ isHeader?: boolean;
+}) {
+ const { api } = useEditorPlugin(TablePlugin);
+ const readOnly = useReadOnly();
+ const element = props.element;
+
+ const tableId = useElementSelector(([node]) => node.id as string, [], {
+ key: KEYS.table,
+ });
+ const rowId = useElementSelector(([node]) => node.id as string, [], {
+ key: KEYS.tr,
+ });
+ const isSelectingTable = useBlockSelected(tableId);
+ const isSelectingRow = useBlockSelected(rowId) || isSelectingTable;
+ const isSelectionAreaVisible = usePluginOption(
+ BlockSelectionPlugin,
+ 'isSelectionAreaVisible'
+ );
+
+ const { borders, colIndex, colSpan, minHeight, rowIndex, selected, width } =
+ useTableCellElement();
+
+ const { bottomProps, hiddenLeft, leftProps, rightProps } =
+ useTableCellElementResizable({
+ colIndex,
+ colSpan,
+ rowIndex,
+ });
+
+ return (
+
+
+ {props.children}
+
+
+ {!isSelectionAreaVisible && (
+
+ {!readOnly && (
+ <>
+
+
+ {!hiddenLeft && (
+
+ )}
+
+
+ {colIndex === 0 && (
+
+ )}
+ >
+ )}
+
+ )}
+
+ {isSelectingRow && (
+
+ )}
+
+ );
+}
+
+export function TableCellHeaderElement(
+ props: React.ComponentProps
+) {
+ return ;
+}
+
+const columnResizeVariants = cva('fade-in hidden animate-in', {
+ variants: {
+ colIndex: {
+ 0: 'group-has-[[data-col="0"]:hover]/table:block group-has-[[data-col="0"][data-resizing="true"]]/table:block',
+ 1: 'group-has-[[data-col="1"]:hover]/table:block group-has-[[data-col="1"][data-resizing="true"]]/table:block',
+ 2: 'group-has-[[data-col="2"]:hover]/table:block group-has-[[data-col="2"][data-resizing="true"]]/table:block',
+ 3: 'group-has-[[data-col="3"]:hover]/table:block group-has-[[data-col="3"][data-resizing="true"]]/table:block',
+ 4: 'group-has-[[data-col="4"]:hover]/table:block group-has-[[data-col="4"][data-resizing="true"]]/table:block',
+ 5: 'group-has-[[data-col="5"]:hover]/table:block group-has-[[data-col="5"][data-resizing="true"]]/table:block',
+ 6: 'group-has-[[data-col="6"]:hover]/table:block group-has-[[data-col="6"][data-resizing="true"]]/table:block',
+ 7: 'group-has-[[data-col="7"]:hover]/table:block group-has-[[data-col="7"][data-resizing="true"]]/table:block',
+ 8: 'group-has-[[data-col="8"]:hover]/table:block group-has-[[data-col="8"][data-resizing="true"]]/table:block',
+ 9: 'group-has-[[data-col="9"]:hover]/table:block group-has-[[data-col="9"][data-resizing="true"]]/table:block',
+ 10: 'group-has-[[data-col="10"]:hover]/table:block group-has-[[data-col="10"][data-resizing="true"]]/table:block',
+ },
+ },
+});
diff --git a/surfsense_web/components/ui/table-toolbar-button.tsx b/surfsense_web/components/ui/table-toolbar-button.tsx
new file mode 100644
index 000000000..37794f1f6
--- /dev/null
+++ b/surfsense_web/components/ui/table-toolbar-button.tsx
@@ -0,0 +1,266 @@
+'use client';
+
+import * as React from 'react';
+
+import type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';
+
+import { TablePlugin, useTableMergeState } from '@platejs/table/react';
+import {
+ ArrowDown,
+ ArrowLeft,
+ ArrowRight,
+ ArrowUp,
+ Combine,
+ Grid3x3Icon,
+ Table,
+ Trash2Icon,
+ Ungroup,
+ XIcon,
+} from 'lucide-react';
+import { KEYS } from 'platejs';
+import { useEditorPlugin, useEditorSelector } from 'platejs/react';
+
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuGroup,
+ DropdownMenuItem,
+ DropdownMenuSub,
+ DropdownMenuSubContent,
+ DropdownMenuSubTrigger,
+ DropdownMenuTrigger,
+} from '@/components/ui/dropdown-menu';
+import { cn } from '@/lib/utils';
+
+import { ToolbarButton } from './toolbar';
+
+export function TableToolbarButton(props: DropdownMenuProps) {
+ const tableSelected = useEditorSelector(
+ (editor) => editor.api.some({ match: { type: KEYS.table } }),
+ []
+ );
+
+ const { editor, tf } = useEditorPlugin(TablePlugin);
+ const [open, setOpen] = React.useState(false);
+ const mergeState = useTableMergeState();
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ Table
+
+
+
+
+
+
+
+
+
+ Cell
+
+
+ {
+ tf.table.merge();
+ editor.tf.focus();
+ }}
+ >
+
+ Merge cells
+
+ {
+ tf.table.split();
+ editor.tf.focus();
+ }}
+ >
+
+ Split cell
+
+
+
+
+
+
+
+ Row
+
+
+ {
+ tf.insert.tableRow({ before: true });
+ editor.tf.focus();
+ }}
+ >
+
+ Insert row before
+
+ {
+ tf.insert.tableRow();
+ editor.tf.focus();
+ }}
+ >
+
+ Insert row after
+
+ {
+ tf.remove.tableRow();
+ editor.tf.focus();
+ }}
+ >
+
+ Delete row
+
+
+
+
+
+
+
+ Column
+
+
+ {
+ tf.insert.tableColumn({ before: true });
+ editor.tf.focus();
+ }}
+ >
+
+ Insert column before
+
+ {
+ tf.insert.tableColumn();
+ editor.tf.focus();
+ }}
+ >
+
+ Insert column after
+
+ {
+ tf.remove.tableColumn();
+ editor.tf.focus();
+ }}
+ >
+
+ Delete column
+
+
+
+
+ {
+ tf.remove.table();
+ editor.tf.focus();
+ }}
+ >
+
+ Delete table
+
+
+
+
+ );
+}
+
+function TablePicker() {
+ const { editor, tf } = useEditorPlugin(TablePlugin);
+
+ const [tablePicker, setTablePicker] = React.useState({
+ grid: Array.from({ length: 8 }, () => Array.from({ length: 8 }).fill(0)),
+ size: { colCount: 0, rowCount: 0 },
+ });
+
+ const onCellMove = (rowIndex: number, colIndex: number) => {
+ const newGrid = [...tablePicker.grid];
+
+ for (let i = 0; i < newGrid.length; i++) {
+ for (let j = 0; j < newGrid[i].length; j++) {
+ newGrid[i][j] =
+ i >= 0 && i <= rowIndex && j >= 0 && j <= colIndex ? 1 : 0;
+ }
+ }
+
+ setTablePicker({
+ grid: newGrid,
+ size: { colCount: colIndex + 1, rowCount: rowIndex + 1 },
+ });
+ };
+
+ return (
+ {
+ tf.insert.table(tablePicker.size, { select: true });
+ editor.tf.focus();
+ }}
+ role="button"
+ >
+
+ {tablePicker.grid.map((rows, rowIndex) =>
+ rows.map((value, columIndex) => (
+
{
+ onCellMove(rowIndex, columIndex);
+ }}
+ />
+ ))
+ )}
+
+
+
+ {tablePicker.size.rowCount} x {tablePicker.size.colCount}
+
+
+ );
+}
diff --git a/surfsense_web/components/ui/toggle-node.tsx b/surfsense_web/components/ui/toggle-node.tsx
new file mode 100644
index 000000000..0c23563aa
--- /dev/null
+++ b/surfsense_web/components/ui/toggle-node.tsx
@@ -0,0 +1,39 @@
+'use client';
+
+import * as React from 'react';
+
+import { useToggleButton, useToggleButtonState } from '@platejs/toggle/react';
+import { ChevronRightIcon } from 'lucide-react';
+import { type PlateElementProps, PlateElement } from 'platejs/react';
+
+import { cn } from '@/lib/utils';
+
+export function ToggleElement({
+ children,
+ ...props
+}: PlateElementProps) {
+ const element = props.element;
+ const state = useToggleButtonState(element.id as string);
+ const { buttonProps, open } = useToggleButton(state);
+
+ return (
+
+
+ {children}
+
+ );
+}
diff --git a/surfsense_web/components/ui/toolbar.tsx b/surfsense_web/components/ui/toolbar.tsx
new file mode 100644
index 000000000..80610e5c7
--- /dev/null
+++ b/surfsense_web/components/ui/toolbar.tsx
@@ -0,0 +1,389 @@
+'use client';
+
+import * as React from 'react';
+
+import * as ToolbarPrimitive from '@radix-ui/react-toolbar';
+import * as TooltipPrimitive from '@radix-ui/react-tooltip';
+import { type VariantProps, cva } from 'class-variance-authority';
+import { ChevronDown } from 'lucide-react';
+
+import {
+ DropdownMenuLabel,
+ DropdownMenuRadioGroup,
+ DropdownMenuSeparator,
+} from '@/components/ui/dropdown-menu';
+import { Separator } from '@/components/ui/separator';
+import { Tooltip, TooltipTrigger } from '@/components/ui/tooltip';
+import { cn } from '@/lib/utils';
+
+export function Toolbar({
+ className,
+ ...props
+}: React.ComponentProps
) {
+ return (
+
+ );
+}
+
+export function ToolbarToggleGroup({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ );
+}
+
+export function ToolbarLink({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ );
+}
+
+export function ToolbarSeparator({
+ className,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+ );
+}
+
+// From toggleVariants
+const toolbarButtonVariants = cva(
+ "inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md font-medium text-sm outline-none transition-[color,box-shadow] hover:bg-muted hover:text-muted-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-checked:bg-accent aria-checked:text-accent-foreground aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
+ {
+ defaultVariants: {
+ size: 'default',
+ variant: 'default',
+ },
+ variants: {
+ size: {
+ default: 'h-9 min-w-9 px-2',
+ lg: 'h-10 min-w-10 px-2.5',
+ sm: 'h-8 min-w-8 px-1.5',
+ },
+ variant: {
+ default: 'bg-transparent',
+ outline:
+ 'border border-input bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground',
+ },
+ },
+ }
+);
+
+const dropdownArrowVariants = cva(
+ cn(
+ 'inline-flex items-center justify-center rounded-r-md font-medium text-foreground text-sm transition-colors disabled:pointer-events-none disabled:opacity-50'
+ ),
+ {
+ defaultVariants: {
+ size: 'sm',
+ variant: 'default',
+ },
+ variants: {
+ size: {
+ default: 'h-9 w-6',
+ lg: 'h-10 w-8',
+ sm: 'h-8 w-4',
+ },
+ variant: {
+ default:
+ 'bg-transparent hover:bg-muted hover:text-muted-foreground aria-checked:bg-accent aria-checked:text-accent-foreground',
+ outline:
+ 'border border-input border-l-0 bg-transparent hover:bg-accent hover:text-accent-foreground',
+ },
+ },
+ }
+);
+
+type ToolbarButtonProps = {
+ isDropdown?: boolean;
+ pressed?: boolean;
+} & Omit<
+ React.ComponentPropsWithoutRef,
+ 'asChild' | 'value'
+> &
+ VariantProps;
+
+export const ToolbarButton = withTooltip(function ToolbarButton({
+ children,
+ className,
+ isDropdown,
+ pressed,
+ size = 'sm',
+ variant,
+ ...props
+}: ToolbarButtonProps) {
+ return typeof pressed === 'boolean' ? (
+
+
+ {isDropdown ? (
+ <>
+
+ {children}
+
+
+
+
+ >
+ ) : (
+ children
+ )}
+
+
+ ) : (
+
+ {children}
+
+ );
+});
+
+export function ToolbarSplitButton({
+ className,
+ ...props
+}: React.ComponentPropsWithoutRef) {
+ return (
+
+ );
+}
+
+type ToolbarSplitButtonPrimaryProps = Omit<
+ React.ComponentPropsWithoutRef,
+ 'value'
+> &
+ VariantProps;
+
+export function ToolbarSplitButtonPrimary({
+ children,
+ className,
+ size = 'sm',
+ variant,
+ ...props
+}: ToolbarSplitButtonPrimaryProps) {
+ return (
+
+ {children}
+
+ );
+}
+
+export function ToolbarSplitButtonSecondary({
+ className,
+ size,
+ variant,
+ ...props
+}: React.ComponentPropsWithoutRef<'span'> &
+ VariantProps) {
+ return (
+ e.stopPropagation()}
+ role="button"
+ {...props}
+ >
+
+
+ );
+}
+
+export function ToolbarToggleItem({
+ className,
+ size = 'sm',
+ variant,
+ ...props
+}: React.ComponentProps &
+ VariantProps) {
+ return (
+
+ );
+}
+
+export function ToolbarGroup({
+ children,
+ className,
+}: React.ComponentProps<'div'>) {
+ return (
+
+ );
+}
+
+type TooltipProps = {
+ tooltip?: React.ReactNode;
+ tooltipContentProps?: Omit<
+ React.ComponentPropsWithoutRef,
+ 'children'
+ >;
+ tooltipProps?: Omit<
+ React.ComponentPropsWithoutRef,
+ 'children'
+ >;
+ tooltipTriggerProps?: React.ComponentPropsWithoutRef;
+} & React.ComponentProps;
+
+function withTooltip(Component: T) {
+ return function ExtendComponent({
+ tooltip,
+ tooltipContentProps,
+ tooltipProps,
+ tooltipTriggerProps,
+ ...props
+ }: TooltipProps) {
+ const [mounted, setMounted] = React.useState(false);
+
+ React.useEffect(() => {
+ setMounted(true);
+ }, []);
+
+ const component = )} />;
+
+ if (tooltip && mounted) {
+ return (
+
+
+ {component}
+
+
+ {tooltip}
+
+ );
+ }
+
+ return component;
+ };
+}
+
+function TooltipContent({
+ children,
+ className,
+ // CHANGE
+ sideOffset = 4,
+ ...props
+}: React.ComponentProps) {
+ return (
+
+
+ {children}
+ {/* CHANGE */}
+ {/* */}
+
+
+ );
+}
+
+export function ToolbarMenuGroup({
+ children,
+ className,
+ label,
+ ...props
+}: React.ComponentProps & { label?: string }) {
+ return (
+ <>
+
+
+
+ {label && (
+
+ {label}
+
+ )}
+ {children}
+
+ >
+ );
+}
diff --git a/surfsense_web/components/ui/turn-into-toolbar-button.tsx b/surfsense_web/components/ui/turn-into-toolbar-button.tsx
new file mode 100644
index 000000000..f5aaa9dd4
--- /dev/null
+++ b/surfsense_web/components/ui/turn-into-toolbar-button.tsx
@@ -0,0 +1,191 @@
+'use client';
+
+import * as React from 'react';
+
+import type { DropdownMenuProps } from '@radix-ui/react-dropdown-menu';
+import type { TElement } from 'platejs';
+
+import { DropdownMenuItemIndicator } from '@radix-ui/react-dropdown-menu';
+import {
+ CheckIcon,
+ ChevronRightIcon,
+ FileCodeIcon,
+ Heading1Icon,
+ Heading2Icon,
+ Heading3Icon,
+ Heading4Icon,
+ Heading5Icon,
+ Heading6Icon,
+ InfoIcon,
+ ListIcon,
+ ListOrderedIcon,
+ PilcrowIcon,
+ QuoteIcon,
+ SquareIcon,
+} from 'lucide-react';
+import { KEYS } from 'platejs';
+import { useEditorRef, useSelectionFragmentProp } from 'platejs/react';
+
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuRadioItem,
+ DropdownMenuTrigger,
+} from '@/components/ui/dropdown-menu';
+import {
+ getBlockType,
+ setBlockType,
+} from '@/components/editor/transforms';
+
+import { ToolbarButton, ToolbarMenuGroup } from './toolbar';
+
+export const turnIntoItems = [
+ {
+ icon: ,
+ keywords: ['paragraph'],
+ label: 'Text',
+ value: KEYS.p,
+ },
+ {
+ icon: ,
+ keywords: ['title', 'h1'],
+ label: 'Heading 1',
+ value: 'h1',
+ },
+ {
+ icon: ,
+ keywords: ['subtitle', 'h2'],
+ label: 'Heading 2',
+ value: 'h2',
+ },
+ {
+ icon: ,
+ keywords: ['subtitle', 'h3'],
+ label: 'Heading 3',
+ value: 'h3',
+ },
+ {
+ icon: ,
+ keywords: ['subtitle', 'h4'],
+ label: 'Heading 4',
+ value: 'h4',
+ },
+ {
+ icon: ,
+ keywords: ['subtitle', 'h5'],
+ label: 'Heading 5',
+ value: 'h5',
+ },
+ {
+ icon: ,
+ keywords: ['subtitle', 'h6'],
+ label: 'Heading 6',
+ value: 'h6',
+ },
+ {
+ icon: ,
+ keywords: ['unordered', 'ul', '-'],
+ label: 'Bulleted list',
+ value: KEYS.ul,
+ },
+ {
+ icon: ,
+ keywords: ['ordered', 'ol', '1'],
+ label: 'Numbered list',
+ value: KEYS.ol,
+ },
+ {
+ icon: ,
+ keywords: ['checklist', 'task', 'checkbox', '[]'],
+ label: 'To-do list',
+ value: KEYS.listTodo,
+ },
+ {
+ icon: ,
+ keywords: ['```'],
+ label: 'Code',
+ value: KEYS.codeBlock,
+ },
+ {
+ icon: ,
+ keywords: ['citation', 'blockquote', '>'],
+ label: 'Quote',
+ value: KEYS.blockquote,
+ },
+ {
+ icon: ,
+ keywords: ['callout', 'note', 'info', 'warning', 'tip'],
+ label: 'Callout',
+ value: KEYS.callout,
+ },
+ {
+ icon: ,
+ keywords: ['toggle', 'collapsible', 'expand'],
+ label: 'Toggle',
+ value: KEYS.toggle,
+ },
+];
+
+export function TurnIntoToolbarButton(props: DropdownMenuProps) {
+ const editor = useEditorRef();
+ const [open, setOpen] = React.useState(false);
+
+ const value = useSelectionFragmentProp({
+ defaultValue: KEYS.p,
+ getProp: (node) => getBlockType(node as TElement),
+ });
+ const selectedItem = React.useMemo(
+ () =>
+ turnIntoItems.find((item) => item.value === (value ?? KEYS.p)) ??
+ turnIntoItems[0],
+ [value]
+ );
+
+ return (
+
+
+
+ {selectedItem.label}
+
+
+
+ {
+ e.preventDefault();
+ editor.tf.focus();
+ }}
+ align="start"
+ >
+ {
+ setBlockType(editor, type);
+ }}
+ label="Turn into"
+ >
+ {turnIntoItems.map(({ icon, label, value: itemValue }) => (
+
+
+
+
+
+
+ {icon}
+ {label}
+
+ ))}
+
+
+
+ );
+}
diff --git a/surfsense_web/hooks/use-debounce.ts b/surfsense_web/hooks/use-debounce.ts
new file mode 100644
index 000000000..fd60d32a7
--- /dev/null
+++ b/surfsense_web/hooks/use-debounce.ts
@@ -0,0 +1,18 @@
+import * as React from 'react';
+
+export const useDebounce = (value: T, delay = 500) => {
+ const [debouncedValue, setDebouncedValue] = React.useState(value);
+
+ React.useEffect(() => {
+ const handler: NodeJS.Timeout = setTimeout(() => {
+ setDebouncedValue(value);
+ }, delay);
+
+ // Cancel the timeout if value changes (also on delay change or unmount)
+ return () => {
+ clearTimeout(handler);
+ };
+ }, [value, delay]);
+
+ return debouncedValue;
+};
diff --git a/surfsense_web/hooks/use-mounted.ts b/surfsense_web/hooks/use-mounted.ts
new file mode 100644
index 000000000..1bc7bde21
--- /dev/null
+++ b/surfsense_web/hooks/use-mounted.ts
@@ -0,0 +1,11 @@
+import * as React from 'react';
+
+export function useMounted() {
+ const [mounted, setMounted] = React.useState(false);
+
+ React.useEffect(() => {
+ setMounted(true);
+ }, []);
+
+ return mounted;
+}
diff --git a/surfsense_web/package.json b/surfsense_web/package.json
index 9a10bff02..fe42c1fbf 100644
--- a/surfsense_web/package.json
+++ b/surfsense_web/package.json
@@ -35,6 +35,23 @@
"@electric-sql/react": "^1.0.26",
"@hookform/resolvers": "^5.2.2",
"@number-flow/react": "^0.5.10",
+ "@platejs/autoformat": "^52.0.11",
+ "@platejs/basic-nodes": "^52.0.11",
+ "@platejs/callout": "^52.0.11",
+ "@platejs/code-block": "^52.0.11",
+ "@platejs/dnd": "^52.0.11",
+ "@platejs/floating": "^52.0.11",
+ "@platejs/indent": "^52.0.11",
+ "@platejs/layout": "^52.0.11",
+ "@platejs/link": "^52.0.11",
+ "@platejs/list-classic": "^52.0.11",
+ "@platejs/markdown": "^52.1.0",
+ "@platejs/math": "^52.0.11",
+ "@platejs/resizable": "^52.0.11",
+ "@platejs/selection": "^52.0.16",
+ "@platejs/slash-command": "^52.0.15",
+ "@platejs/table": "^52.0.11",
+ "@platejs/toggle": "^52.0.11",
"@posthog/react": "^1.7.0",
"@radix-ui/react-accordion": "^1.2.11",
"@radix-ui/react-alert-dialog": "^1.1.14",
@@ -56,6 +73,7 @@
"@radix-ui/react-tabs": "^1.1.12",
"@radix-ui/react-toggle": "^1.1.9",
"@radix-ui/react-toggle-group": "^1.1.10",
+ "@radix-ui/react-toolbar": "^1.1.11",
"@radix-ui/react-tooltip": "^1.2.7",
"@streamdown/code": "^1.0.2",
"@streamdown/math": "^1.0.2",
@@ -66,6 +84,7 @@
"@tanstack/react-table": "^8.21.3",
"@types/mdx": "^2.0.13",
"@types/react-syntax-highlighter": "^15.5.13",
+ "@udecode/cn": "^52.0.11",
"ai": "^4.3.19",
"canvas-confetti": "^1.9.3",
"class-variance-authority": "^0.7.1",
@@ -82,17 +101,21 @@
"jotai": "^2.15.1",
"jotai-tanstack-query": "^0.11.0",
"katex": "^0.16.28",
+ "lodash": "^4.17.23",
+ "lowlight": "^3.3.0",
"lucide-react": "^0.477.0",
"motion": "^12.23.22",
"next": "^16.1.0",
"next-intl": "^4.6.1",
"next-themes": "^0.4.6",
"pg": "^8.16.3",
+ "platejs": "^52.0.17",
"postgres": "^3.4.7",
"posthog-js": "^1.336.1",
"posthog-node": "^5.24.4",
+ "radix-ui": "^1.4.3",
"react": "^19.2.3",
- "react-day-picker": "^9.8.1",
+ "react-day-picker": "^9.13.2",
"react-dom": "^19.2.3",
"react-dropzone": "^14.3.8",
"react-hook-form": "^7.61.1",
@@ -108,6 +131,7 @@
"sonner": "^2.0.6",
"streamdown": "^2.2.0",
"tailwind-merge": "^3.3.1",
+ "tailwind-scrollbar-hide": "^4.0.0",
"tailwindcss-animate": "^1.0.7",
"unist-util-visit": "^5.0.0",
"vaul": "^1.1.2",
diff --git a/surfsense_web/pnpm-lock.yaml b/surfsense_web/pnpm-lock.yaml
index fc6b3ca9f..a4f15ad51 100644
--- a/surfsense_web/pnpm-lock.yaml
+++ b/surfsense_web/pnpm-lock.yaml
@@ -13,25 +13,25 @@ importers:
version: 1.2.12(react@19.2.3)(zod@4.2.1)
'@assistant-ui/react':
specifier: ^0.11.53
- version: 0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
+ version: 0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
'@assistant-ui/react-ai-sdk':
specifier: ^1.1.20
- version: 1.1.20(@assistant-ui/react@0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)))(@types/react@19.2.7)(assistant-cloud@0.1.12)(react@19.2.3)
+ version: 1.1.20(@assistant-ui/react@0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)))(@types/react@19.2.7)(assistant-cloud@0.1.12)(react@19.2.3)
'@assistant-ui/react-markdown':
specifier: ^0.11.9
- version: 0.11.9(@assistant-ui/react@0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)))(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ version: 0.11.9(@assistant-ui/react@0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)))(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@blocknote/core':
specifier: ^0.45.0
- version: 0.45.0(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(highlight.js@11.11.1)
+ version: 0.45.0(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0)
'@blocknote/mantine':
specifier: ^0.45.0
- version: 0.45.0(@floating-ui/dom@1.7.5)(@mantine/core@8.3.10(@mantine/hooks@8.3.10(react@19.2.3))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@mantine/hooks@8.3.10(react@19.2.3))(@mantine/utils@6.0.22(react@19.2.3))(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ version: 0.45.0(@floating-ui/dom@1.7.5)(@mantine/core@8.3.10(@mantine/hooks@8.3.10(react@19.2.3))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@mantine/hooks@8.3.10(react@19.2.3))(@mantine/utils@6.0.22(react@19.2.3))(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@blocknote/react':
specifier: ^0.45.0
- version: 0.45.0(@floating-ui/dom@1.7.5)(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ version: 0.45.0(@floating-ui/dom@1.7.5)(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@blocknote/server-util':
specifier: ^0.45.0
- version: 0.45.0(@floating-ui/dom@1.7.5)(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ version: 0.45.0(@floating-ui/dom@1.7.5)(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(lowlight@3.3.0)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@electric-sql/client':
specifier: ^1.4.0
version: 1.4.0
@@ -50,6 +50,57 @@ importers:
'@number-flow/react':
specifier: ^0.5.10
version: 0.5.10(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/autoformat':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/basic-nodes':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/callout':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/code-block':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/dnd':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dnd-html5-backend@16.0.1)(react-dnd@16.0.1(@types/node@20.19.27)(@types/react@19.2.7)(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/floating':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/indent':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/layout':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/link':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/list-classic':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/markdown':
+ specifier: ^52.1.0
+ version: 52.1.0(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)
+ '@platejs/math':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/resizable':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/selection':
+ specifier: ^52.0.16
+ version: 52.0.16(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/slash-command':
+ specifier: ^52.0.15
+ version: 52.0.15(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/table':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@platejs/toggle':
+ specifier: ^52.0.11
+ version: 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@posthog/react':
specifier: ^1.7.0
version: 1.7.0(@types/react@19.2.7)(posthog-js@1.336.1)(react@19.2.3)
@@ -113,6 +164,9 @@ importers:
'@radix-ui/react-toggle-group':
specifier: ^1.1.10
version: 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-toolbar':
+ specifier: ^1.1.11
+ version: 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@radix-ui/react-tooltip':
specifier: ^1.2.7
version: 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -143,6 +197,9 @@ importers:
'@types/react-syntax-highlighter':
specifier: ^15.5.13
version: 15.5.13
+ '@udecode/cn':
+ specifier: ^52.0.11
+ version: 52.0.11(@types/react@19.2.7)(class-variance-authority@0.7.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(tailwind-merge@3.4.0)
ai:
specifier: ^4.3.19
version: 4.3.19(react@19.2.3)(zod@4.2.1)
@@ -191,6 +248,12 @@ importers:
katex:
specifier: ^0.16.28
version: 0.16.28
+ lodash:
+ specifier: ^4.17.23
+ version: 4.17.23
+ lowlight:
+ specifier: ^3.3.0
+ version: 3.3.0
lucide-react:
specifier: ^0.477.0
version: 0.477.0(react@19.2.3)
@@ -209,6 +272,9 @@ importers:
pg:
specifier: ^8.16.3
version: 8.16.3
+ platejs:
+ specifier: ^52.0.17
+ version: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
postgres:
specifier: ^3.4.7
version: 3.4.7
@@ -218,12 +284,15 @@ importers:
posthog-node:
specifier: ^5.24.4
version: 5.24.4
+ radix-ui:
+ specifier: ^1.4.3
+ version: 1.4.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
react:
specifier: ^19.2.3
version: 19.2.3
react-day-picker:
- specifier: ^9.8.1
- version: 9.13.0(react@19.2.3)
+ specifier: ^9.13.2
+ version: 9.13.2(react@19.2.3)
react-dom:
specifier: ^19.2.3
version: 19.2.3(react@19.2.3)
@@ -269,6 +338,9 @@ importers:
tailwind-merge:
specifier: ^3.3.1
version: 3.4.0
+ tailwind-scrollbar-hide:
+ specifier: ^4.0.0
+ version: 4.0.0(tailwindcss@4.1.18)
tailwindcss-animate:
specifier: ^1.0.7
version: 1.0.7(tailwindcss@4.1.18)
@@ -283,7 +355,7 @@ importers:
version: 4.2.1
zustand:
specifier: ^5.0.9
- version: 5.0.9(@types/react@19.2.7)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
+ version: 5.0.9(@types/react@19.2.7)(immer@10.2.0)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
devDependencies:
'@biomejs/biome':
specifier: 2.1.2
@@ -1902,6 +1974,9 @@ packages:
'@jridgewell/trace-mapping@0.3.31':
resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==}
+ '@juggle/resize-observer@3.4.0':
+ resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==}
+
'@mantine/core@8.3.10':
resolution: {integrity: sha512-aKQFETN14v6GtM07b/G5yJneMM1yrgf9mNrTah6GVy5DvQM0AeutITT7toHqh5gxxwzdg/DoY+HQsv5zhqnc5g==}
peerDependencies:
@@ -2162,6 +2237,149 @@ packages:
resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==}
engines: {node: '>= 10.0.0'}
+ '@platejs/autoformat@52.0.11':
+ resolution: {integrity: sha512-5/pLa0uAOrN/jfwpEWEhk/5G9wmSD12EnBnVDP0lB2tuosOzyMCH0rNylMYwgLFACNO7goLw7ka6tvjJ1ErxtQ==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/basic-nodes@52.0.11':
+ resolution: {integrity: sha512-vvjSybGRdY/dZoQKUItX7Jou0W0VdLYA7C9OtqTKL9DD5DuRTp4+/7WZTFgS255ZH4lodxfUCsFNRkeIzzm8EQ==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/callout@52.0.11':
+ resolution: {integrity: sha512-9JmQGWPLf/xBCoW90jltjGJU/ni2ePPp4wMxlHPjdklLr1g5MB5RswLmUjtZ839G5PqKojHFDL40JddIOyqeig==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/code-block@52.0.11':
+ resolution: {integrity: sha512-+MvKTvGhGQYNgEdExwnYXZZ58AmKYVOK6fIRX1JF8s6AHh8vUGuemOci8K65VhHSlMSChhVSVvOiAqkcgt3Z7w==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/combobox@52.0.15':
+ resolution: {integrity: sha512-ib5sdP91GA8BhmfyK7Pi57OGDRK/Kjxv399kCNRt/qxk0nLG7b15MUM/Apauf/pm/mvUJNmA7LwWHCZCuEuChw==}
+ peerDependencies:
+ platejs: '>=52.0.15'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/core@52.0.17':
+ resolution: {integrity: sha512-AXwt/GfotU/+0WsCxVOI3tCR7svIX2eT+yGTCHriSDAPJYrRq6qxGUBzDJWV7M16Zh3ihMPHpE+sfOhnCfdYeg==}
+ peerDependencies:
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/dnd@52.0.11':
+ resolution: {integrity: sha512-iXWDHCzD0JE55E9AZGeWN+ZZkgaaxYNg4llRFryV2FVbMbFj2u7rca3Qv/YTvAinqbI8nswO4EhuP5JHSUNdMQ==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dnd: '>=14.0.0'
+ react-dnd-html5-backend: '>=14.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/floating@52.0.11':
+ resolution: {integrity: sha512-ApNpw4KWml+kuK+XTTpji+f/7GxTR4nRzlnfJMvGBrJpLPQ4elS5MABm3oUi81DZn+aub5HvsyH7UqCw7F76IA==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/indent@52.0.11':
+ resolution: {integrity: sha512-CZYFOZObce4yzQal/coKtPzp2+N+DiLetLiYR2U8z4Tgc9da/Fsj11DNR7CorVcdNmBPWkr3vwbTwuSayNOYgQ==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/layout@52.0.11':
+ resolution: {integrity: sha512-qd/1RLqxFy67kIGc9WpfHA2JMMriW6PaXUibtN9/jmOYi5muSRq314pSvfnB2jq3CB1NYLrseL8qSynEb4liCg==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/link@52.0.11':
+ resolution: {integrity: sha512-ykfTL1NtvDJYGbp+QZiZU+N1WNo5xLiInuBl/Gb/EVeI/PU8He1PLR1ub/zhIuJiiT487u07QT5b4jltvnd86g==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/list-classic@52.0.11':
+ resolution: {integrity: sha512-cuR0UJcfT7X45dvptofbozEznx604Y263pjlK7vLFerI2k7cUBuXRKOxtUuwVD4VaWE5aHCr8cO+nb+jhdGHSQ==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/markdown@52.1.0':
+ resolution: {integrity: sha512-4443H09CJ4AH1449TERm7ot5aFji4rKt+iHIZdB7FiIBz9Coki5+JkKcRn9gEq7lpjMQ9E/MD2J9ejnmglc1/A==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/math@52.0.11':
+ resolution: {integrity: sha512-V57pa/fuXgA0g94R+wY8ka+TFYJY2o7Si1AK45heCGy8rGc0bCNjImtyscabHHoI+NvM6gyFDvwL58SrbIZGyQ==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/resizable@52.0.11':
+ resolution: {integrity: sha512-x2tvjr3XIonbuYseG9M5EqYwXoj+V69xdKIt+n8v2ltgsn7W1wJgzLO8tdBJCnKQPEGAvCFXUTlQAUNeQ1OYQA==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/selection@52.0.16':
+ resolution: {integrity: sha512-AzY8FMyBX8exWA4HHPV5TDVCCu1eDhmM5dBpyfi5O95PmxT3EQ4Bd31nT6j6grn/ei2EiNIdHTDxqae9y9d+nw==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/slash-command@52.0.15':
+ resolution: {integrity: sha512-6hqR+hnnB+RVyDRk/pj2iUXBTJm5GYSNoIG1gKHHQmnuULjU0tAF8YctoXAhZB8Cbi1I/56L9+rvQWxDOqjS3Q==}
+ peerDependencies:
+ platejs: '>=52.0.15'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/slate@52.0.10':
+ resolution: {integrity: sha512-15YwlCLkoWMFq02LCFBRRkYgv19iCGLiGCTGuWGwhhB2qZ4sWSklkQbJjFuwZIKG6k+EFPhzmAcJdNw3BrbSVw==}
+
+ '@platejs/table@52.0.11':
+ resolution: {integrity: sha512-hOf4Ije8KBZtYcIKsbBONSrr9oDO5BqQntf6F1H3gGFgKZqkumjUPcaK2+WZ0PS1aMx5IKqQMzgR/woYhmQ11Q==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/toggle@52.0.11':
+ resolution: {integrity: sha512-wqOl9btEtthfSps8fnWf+dt62szd0LTHAj/NnS+5bB4y89qe/MRoUX3RphPz+JKSbi99AqH8vdm3e8I1I5QRoQ==}
+ peerDependencies:
+ platejs: '>=52.0.11'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@platejs/utils@52.0.17':
+ resolution: {integrity: sha512-9YvYnic+qo4bPJAPvFwWQLeG5zQ/OWe6hyA7b3sFhmSyuiLWQZklkHrE96iyHu4Jn31h3FndbG9AH7e36HFa1w==}
+ peerDependencies:
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
'@posthog/core@1.15.0':
resolution: {integrity: sha512-n2/Yy0+qc8xhmlcOFiYqTcGHBZuuaQjVolfFXk7yTCynzdMe8Fx1zYvPPUrbdQK5tWwXyilkzybpqhK6I7aV4Q==}
@@ -2232,6 +2450,19 @@ packages:
'@radix-ui/primitive@1.1.3':
resolution: {integrity: sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==}
+ '@radix-ui/react-accessible-icon@1.1.7':
+ resolution: {integrity: sha512-XM+E4WXl0OqUJFovy6GjmxxFyx9opfCAIUku4dlKRd5YEPqt4kALOkQOp0Of6reHuUkJuiPBEc5k0o4z4lTC8A==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-accordion@1.2.12':
resolution: {integrity: sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==}
peerDependencies:
@@ -2271,6 +2502,32 @@ packages:
'@types/react-dom':
optional: true
+ '@radix-ui/react-aspect-ratio@1.1.7':
+ resolution: {integrity: sha512-Yq6lvO9HQyPwev1onK1daHCHqXVLzPhSVjmsNjCa2Zcxy2f7uJD2itDtxknv6FzAKCwD1qQkeVDmX/cev13n/g==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-avatar@1.1.10':
+ resolution: {integrity: sha512-V8piFfWapM5OmNCXTzVQY+E1rDa53zY+MQ4Y7356v4fFz6vqCyUtIz2rUD44ZEdwg78/jKmMJHj07+C/Z/rcog==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-avatar@1.1.11':
resolution: {integrity: sha512-0Qk603AHGV28BOBO34p7IgD5m+V5Sg/YovfayABkoDDBM5d3NCx0Mp4gGrjzLGes1jV5eNOE1r3itqOR33VC6Q==}
peerDependencies:
@@ -2532,6 +2789,32 @@ packages:
'@types/react-dom':
optional: true
+ '@radix-ui/react-form@0.1.8':
+ resolution: {integrity: sha512-QM70k4Zwjttifr5a4sZFts9fn8FzHYvQ5PiB19O2HsYibaHSVt9fH9rzB0XZo/YcM+b7t/p7lYCT/F5eOeF5yQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-hover-card@1.1.15':
+ resolution: {integrity: sha512-qgTkjNT1CfKMoP0rcasmlH2r1DAiYicWsDsufxl940sT2wHNEWWv6FMWIQXWhVdmC1d/HYfbhQx60KYyAtKxjg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-id@1.0.0':
resolution: {integrity: sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==}
peerDependencies:
@@ -2555,6 +2838,19 @@ packages:
'@types/react':
optional: true
+ '@radix-ui/react-label@2.1.7':
+ resolution: {integrity: sha512-YT1GqPSL8kJn20djelMX7/cTRp/Y9w5IZHvfxQTVHrOqa2yMl7i/UfMqKRU5V7mEyKTrUVgJXhNQPVCG8PBLoQ==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-label@2.1.8':
resolution: {integrity: sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==}
peerDependencies:
@@ -2581,6 +2877,19 @@ packages:
'@types/react-dom':
optional: true
+ '@radix-ui/react-menubar@1.1.16':
+ resolution: {integrity: sha512-EB1FktTz5xRRi2Er974AUQZWg2yVBb1yjip38/lgwtCVRd3a+maUoGHN/xs9Yv8SY8QwbSEb+YrxGadVWbEutA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-navigation-menu@1.2.14':
resolution: {integrity: sha512-YB9mTFQvCOAQMHU+C/jVl96WmuWeltyUEpRJJky51huhds5W2FQr1J8D/16sQlf0ozxkPK8uF3niQMdUwZPv5w==}
peerDependencies:
@@ -2594,6 +2903,32 @@ packages:
'@types/react-dom':
optional: true
+ '@radix-ui/react-one-time-password-field@0.1.8':
+ resolution: {integrity: sha512-ycS4rbwURavDPVjCb5iS3aG4lURFDILi6sKI/WITUMZ13gMmn/xGjpLoqBAalhJaDk8I3UbCM5GzKHrnzwHbvg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ '@radix-ui/react-password-toggle-field@0.1.3':
+ resolution: {integrity: sha512-/UuCrDBWravcaMix4TdT+qlNdVwOM1Nck9kWx/vafXsdfj1ChfhOdfi3cy9SGBpWgTXwYCuboT/oYpJy3clqfw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-popover@1.1.15':
resolution: {integrity: sha512-kr0X2+6Yy/vJzLYJUPCZEc8SfQcf+1COFoAqauJm74umQhta9M7lNJHP7QQS3vkvcGLQUbWpMzwrXYwrYztHKA==}
peerDependencies:
@@ -2729,6 +3064,19 @@ packages:
'@types/react-dom':
optional: true
+ '@radix-ui/react-progress@1.1.7':
+ resolution: {integrity: sha512-vPdg/tF6YC/ynuBIJlk1mm7Le0VgW6ub6J2UWnTQ7/D23KXcPI1qy+0vBkgKgd38RCMJavBXpB83HPNFMTb0Fg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-radio-group@1.3.8':
resolution: {integrity: sha512-VBKYIYImA5zsxACdisNQ3BjCBfmbGH3kQlnFVqlWU4tXwjy7cGX8ta80BcrO+WJXIn5iBylEH3K6ZTlee//lgQ==}
peerDependencies:
@@ -2781,6 +3129,19 @@ packages:
'@types/react-dom':
optional: true
+ '@radix-ui/react-separator@1.1.7':
+ resolution: {integrity: sha512-0HEb8R9E8A+jZjvmFCy/J4xhbXy3TV+9XSnGJ3KvTtjlIUy/YQ/p6UYZvi7YbeoeXdyU9+Y3scizK6hkY37baA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-separator@1.1.8':
resolution: {integrity: sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==}
peerDependencies:
@@ -2865,6 +3226,19 @@ packages:
'@types/react-dom':
optional: true
+ '@radix-ui/react-toast@1.2.15':
+ resolution: {integrity: sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-toggle-group@1.1.11':
resolution: {integrity: sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==}
peerDependencies:
@@ -2891,6 +3265,19 @@ packages:
'@types/react-dom':
optional: true
+ '@radix-ui/react-toolbar@1.1.11':
+ resolution: {integrity: sha512-4ol06/1bLoFu1nwUqzdD4Y5RZ9oDdKeiHIsntug54Hcr1pgaHiPqHFEaXI1IFP/EsOfROQZ8Mig9VTIRza6Tjg==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
'@radix-ui/react-tooltip@1.2.8':
resolution: {integrity: sha512-tY7sVt1yL9ozIxvmbtN5qtmH2krXcBCfjEiCgKGLqunJHvgvZG2Pcl2oQ3kbcZARb1BGEHdkLzcYGO8ynVlieg==}
peerDependencies:
@@ -3057,6 +3444,15 @@ packages:
'@radix-ui/rect@1.1.1':
resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
+ '@react-dnd/asap@5.0.2':
+ resolution: {integrity: sha512-WLyfoHvxhs0V9U+GTsGilGgf2QsPl6ZZ44fnv0/b8T3nQyvzxidxsg/ZltbWssbsRDlYW8UKSQMTGotuTotZ6A==}
+
+ '@react-dnd/invariant@4.0.2':
+ resolution: {integrity: sha512-xKCTqAK/FFauOM9Ta2pswIyT3D8AQlfrYdOi/toTPEhqCuAs1v5tcJ3Y08Izh1cJ5Jchwy9SeAXmMg6zrKs2iw==}
+
+ '@react-dnd/shallowequal@4.0.2':
+ resolution: {integrity: sha512-/RVXdLvJxLg4QKvMoM5WlwNR9ViO9z8B/qPcc+C0Sa/teJY7QG7kJ441DwzOjMYEY7GmU4dj5EcGHIkKZiQZCA==}
+
'@remirror/core-constants@3.0.0':
resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==}
@@ -3766,6 +4162,29 @@ packages:
resolution: {integrity: sha512-Xzmnb58+Db78gT/CCj/PVCvK+zxbnsw6F+O1oheYszJbBSdEjVhQi3C/Xttzxgi/GLmpvOggRs1RFpiJ8+c34Q==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@udecode/cn@52.0.11':
+ resolution: {integrity: sha512-y12tHgdTchnWjvqCaMbeFemng+EjSxcdxXO+AjJE7NJ6w9IqahLQE00NF3owSB+u/edn/vSyd0Pw3eWfjgB9SA==}
+ peerDependencies:
+ class-variance-authority: '>=0.7.0'
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+ tailwind-merge: '>=2.2.0'
+
+ '@udecode/react-hotkeys@52.0.11':
+ resolution: {integrity: sha512-MwdQlfTZhrP0O+BazuNgY9g2qJSZAB05ykdVCdWmBsjv5VQvQ3R9RkXLUMGD20TqUR62iT/Phb/ca8toxiCm0w==}
+ peerDependencies:
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@udecode/react-utils@52.0.11':
+ resolution: {integrity: sha512-po0msO04kCKWI3RJ8pn3roUnG5annln+GNcRd7KFp2oK+QwdOMG7M/+Drq2xvqnBpR1thxYy8fVxVZvlIULMCg==}
+ peerDependencies:
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
+ '@udecode/utils@52.0.1':
+ resolution: {integrity: sha512-T/qa4++J2MMY9CbhZ05ONpcpkvsRV0uBvOfMhhYWKkAND4DSVAVzmZTV7WQ5fjGq81agAped0WQxcqsEg617uQ==}
+
'@ungap/structured-clone@1.3.0':
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
@@ -4172,6 +4591,9 @@ packages:
convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+ copy-to-clipboard@3.3.3:
+ resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==}
+
core-js-compat@3.48.0:
resolution: {integrity: sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q==}
@@ -4327,6 +4749,13 @@ packages:
diff-match-patch@1.0.5:
resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==}
+ direction@1.0.4:
+ resolution: {integrity: sha512-GYqKi1aH7PJXxdhTeZBFrg8vUBeKXi+cNprXsC1kpJcbcVnV9wBsrOu1cQEdG0WeQwlfHiy3XvnKfIrJ2R0NzQ==}
+ hasBin: true
+
+ dnd-core@16.0.1:
+ resolution: {integrity: sha512-HK294sl7tbw6F6IeuK16YSBUoorvHpY8RHO+9yFfaJyCDVb6n7PRcezrOEOa2SBCqiYpemh5Jx20ZcjKdFAVng==}
+
doctrine@2.1.0:
resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==}
engines: {node: '>=0.10.0'}
@@ -5062,10 +5491,16 @@ packages:
highlightjs-vue@1.0.0:
resolution: {integrity: sha512-PDEfEF102G23vHmPhLyPboFCD+BkMGu+GuJe2d9/eH4FsCwvgBpnc9n0pGE+ffKdph38s6foEZiEjdgHdzp+IA==}
+ hoist-non-react-statics@3.3.2:
+ resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
+
html-encoding-sniffer@4.0.0:
resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==}
engines: {node: '>=18'}
+ html-entities@2.6.0:
+ resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==}
+
html-url-attributes@3.0.1:
resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
@@ -5103,6 +5538,9 @@ packages:
engines: {node: '>=16.x'}
hasBin: true
+ immer@10.2.0:
+ resolution: {integrity: sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==}
+
import-fresh@3.3.1:
resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
engines: {node: '>=6'}
@@ -5205,6 +5643,9 @@ packages:
is-hexadecimal@2.0.1:
resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
+ is-hotkey@0.2.0:
+ resolution: {integrity: sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw==}
+
is-map@2.0.3:
resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
engines: {node: '>= 0.4'}
@@ -5225,6 +5666,10 @@ packages:
resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
engines: {node: '>=12'}
+ is-plain-object@5.0.0:
+ resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
+ engines: {node: '>=0.10.0'}
+
is-potential-custom-element-name@1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
@@ -5281,6 +5726,12 @@ packages:
resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==}
hasBin: true
+ jotai-optics@0.4.0:
+ resolution: {integrity: sha512-osbEt9AgS55hC4YTZDew2urXKZkaiLmLqkTS/wfW5/l0ib8bmmQ7kBXSFaosV6jDDWSp00IipITcJARFHdp42g==}
+ peerDependencies:
+ jotai: '>=2.0.0'
+ optics-ts: '>=2.0.0'
+
jotai-tanstack-query@0.11.0:
resolution: {integrity: sha512-Ys0u0IuuS6/okUJOulFTdCVfVaeKbm1+lKVSN9zHhIxtrAXl9FM4yu7fNvxM6fSz/NCE9tZOKR0MQ3hvplaH8A==}
peerDependencies:
@@ -5294,6 +5745,18 @@ packages:
react:
optional: true
+ jotai-x@2.3.3:
+ resolution: {integrity: sha512-ZeSPjf77VINlJ0HyMfYcPv/9psjB0CtJIZP6S+s/eefaO/9+U37M9Jx5dWmILgTe8hAol99EbAv6DDrHobOucA==}
+ peerDependencies:
+ '@types/react': '>=17.0.0'
+ jotai: '>=2.0.0'
+ react: '>=17.0.0'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ react:
+ optional: true
+
jotai@2.16.0:
resolution: {integrity: sha512-NmkwPBet0SHQ28GBfEb10sqnbVOYyn6DL4iazZgGRDUKxSWL0iqcm+IK4TqTSFC2ixGk+XX2e46Wbv364a3cKg==}
engines: {node: '>=12.20.0'}
@@ -5312,6 +5775,18 @@ packages:
react:
optional: true
+ jotai@2.8.4:
+ resolution: {integrity: sha512-f6jwjhBJcDtpeauT2xH01gnqadKEySwwt1qNBLvAXcnojkmb76EdqRt05Ym8IamfHGAQz2qMKAwftnyjeSoHAA==}
+ engines: {node: '>=12.20.0'}
+ peerDependencies:
+ '@types/react': '>=17.0.0'
+ react: '>=17.0.0'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ react:
+ optional: true
+
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
@@ -5366,6 +5841,10 @@ packages:
resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
engines: {node: '>=4.0'}
+ katex@0.16.22:
+ resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==}
+ hasBin: true
+
katex@0.16.28:
resolution: {integrity: sha512-YHzO7721WbmAL6Ov1uzN/l5mY5WWWhJBSW+jq4tkfZfsxmo1hu6frS0EOswvjBUnWE6NtjEs48SFn5CQESRLZg==}
hasBin: true
@@ -5475,9 +5954,15 @@ packages:
lodash.debounce@4.0.8:
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
+ lodash.mapvalues@4.6.0:
+ resolution: {integrity: sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ==}
+
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
+ lodash@4.17.23:
+ resolution: {integrity: sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==}
+
long@5.3.2:
resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==}
@@ -5494,6 +5979,9 @@ packages:
lowlight@1.20.0:
resolution: {integrity: sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw==}
+ lowlight@3.3.0:
+ resolution: {integrity: sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==}
+
lru-cache@10.4.3:
resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
@@ -5519,6 +6007,11 @@ packages:
markdown-table@3.0.4:
resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==}
+ marked@15.0.12:
+ resolution: {integrity: sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA==}
+ engines: {node: '>= 18'}
+ hasBin: true
+
marked@17.0.2:
resolution: {integrity: sha512-s5HZGFQea7Huv5zZcAGhJLT3qLpAfnY7v7GWkICUr0+Wd5TFEtdlRR2XUL5Gg+RH7u2Df595ifrxR03mBaw7gA==}
engines: {node: '>= 20'}
@@ -5752,6 +6245,10 @@ packages:
ms@2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+ mutative@1.1.0:
+ resolution: {integrity: sha512-2PJADREjOusk3iJkD3rXV2YjAxTuaLxdfqtqTEt6vcY07LtEBR1seHuBHXWEIuscqRDGvbauYPs+A4Rj/KTczQ==}
+ engines: {node: '>=14.0'}
+
nanoid@3.3.11:
resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -5884,6 +6381,9 @@ packages:
oniguruma-to-es@4.3.4:
resolution: {integrity: sha512-3VhUGN3w2eYxnTzHn+ikMI+fp/96KoRSVK9/kMTcFqj1NRDh2IhQCKvYxDnWePKRXY/AqH+Fuiyb7VHSzBjHfA==}
+ optics-ts@2.4.1:
+ resolution: {integrity: sha512-HaYzMHvC80r7U/LqAd4hQyopDezC60PO2qF5GuIwALut2cl5rK1VWHsqTp0oqoJJWjiv6uXKqsO+Q2OO0C3MmQ==}
+
optionator@0.9.4:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
engines: {node: '>= 0.8.0'}
@@ -5938,6 +6438,9 @@ packages:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
+ performance-now@2.1.0:
+ resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==}
+
pg-cloudflare@1.2.7:
resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==}
@@ -5983,6 +6486,12 @@ packages:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'}
+ platejs@52.0.17:
+ resolution: {integrity: sha512-vJZijt8coKh6W60RmUG69DFM4ZwLhzNwSfOwfk5SkVWer1iDqqyW34JnGn5nKI8irj+45/sSzx4Nfgw9CR+QYw==}
+ peerDependencies:
+ react: '>=18.0.0'
+ react-dom: '>=18.0.0'
+
po-parser@2.0.0:
resolution: {integrity: sha512-SZvoKi3PoI/hHa2V9je9CW7Xgxl4dvO74cvaa6tWShIHT51FkPxje6pt0gTJznJrU67ix91nDaQp2hUxkOYhKA==}
@@ -6159,6 +6668,9 @@ packages:
resolution: {integrity: sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==}
engines: {node: '>=12.0.0'}
+ proxy-compare@2.6.0:
+ resolution: {integrity: sha512-8xuCeM3l8yqdmbPoYeLbrAXCBWu19XEYc5/F28f5qOaoAIMyfmBUkl5axiK+x9olUvRlcekvnm98AP9RDngOIw==}
+
pump@3.0.3:
resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==}
@@ -6176,16 +6688,55 @@ packages:
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ radix-ui@1.4.3:
+ resolution: {integrity: sha512-aWizCQiyeAenIdUbqEpXgRA1ya65P13NKn/W8rWkcN0OPkRDxdBVLWnIEDsS2RpwCK2nobI7oMUSmexzTDyAmA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+
+ raf@3.4.1:
+ resolution: {integrity: sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==}
+
rc@1.2.8:
resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
hasBin: true
- react-day-picker@9.13.0:
- resolution: {integrity: sha512-euzj5Hlq+lOHqI53NiuNhCP8HWgsPf/bBAVijR50hNaY1XwjKjShAnIe8jm8RD2W9IJUvihDIZ+KrmqfFzNhFQ==}
+ react-compiler-runtime@1.0.0:
+ resolution: {integrity: sha512-rRfjYv66HlG8896yPUDONgKzG5BxZD1nV9U6rkm+7VCuvQc903C4MjcoZR4zPw53IKSOX9wMQVpA1IAbRtzQ7w==}
+ peerDependencies:
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0 || ^0.0.0-experimental
+
+ react-day-picker@9.13.2:
+ resolution: {integrity: sha512-IMPiXfXVIAuR5Yk58DDPBC8QKClrhdXV+Tr/alBrwrHUw0qDDYB1m5zPNuTnnPIr/gmJ4ChMxmtqPdxm8+R4Eg==}
engines: {node: '>=18'}
peerDependencies:
react: '>=16.8.0'
+ react-dnd-html5-backend@16.0.1:
+ resolution: {integrity: sha512-Wu3dw5aDJmOGw8WjH1I1/yTH+vlXEL4vmjk5p+MHxP8HuHJS1lAGeIdG/hze1AvNeXWo/JgULV87LyQOr+r5jw==}
+
+ react-dnd@16.0.1:
+ resolution: {integrity: sha512-QeoM/i73HHu2XF9aKksIUuamHPDvRglEwdHL4jsp784BgUuWcg6mzfxT0QDdQz8Wj0qyRKx2eMg8iZtWvU4E2Q==}
+ peerDependencies:
+ '@types/hoist-non-react-statics': '>= 3.3.1'
+ '@types/node': '>= 12'
+ '@types/react': '>= 16'
+ react: '>= 16.14'
+ peerDependenciesMeta:
+ '@types/hoist-non-react-statics':
+ optional: true
+ '@types/node':
+ optional: true
+ '@types/react':
+ optional: true
+
react-dom@19.2.3:
resolution: {integrity: sha512-yELu4WmLPw5Mr/lmeEpox5rw3RETacE++JgHqQzd2dg+YbJuat3jH4ingc+WPZhxaoFzdv9y33G+F7Nl5O0GBg==}
peerDependencies:
@@ -6303,6 +6854,19 @@ packages:
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+ react-tracked@1.7.14:
+ resolution: {integrity: sha512-6UMlgQeRAGA+uyYzuQGm7kZB6ZQYFhc7sntgP7Oxwwd6M0Ud/POyb4K3QWT1eXvoifSa80nrAWnXWFGpOvbwkw==}
+ peerDependencies:
+ react: '>=16.8.0'
+ react-dom: '*'
+ react-native: '*'
+ scheduler: '>=0.19.0'
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
+
react-wrap-balancer@1.1.1:
resolution: {integrity: sha512-AB+l7FPRWl6uZ28VcJ8skkwLn2+UC62bjiw8tQUrZPlEWDVnR9MG0lghyn7EyxuJSsFEpht4G+yh2WikEqQ/5Q==}
peerDependencies:
@@ -6334,6 +6898,9 @@ packages:
recma-stringify@1.0.0:
resolution: {integrity: sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==}
+ redux@4.2.1:
+ resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==}
+
reflect.getprototypeof@1.0.10:
resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
engines: {node: '>= 0.4'}
@@ -6563,6 +7130,27 @@ packages:
simple-get@4.0.1:
resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
+ slate-dom@0.119.0:
+ resolution: {integrity: sha512-foc8a2NkE+1SldDIYaoqjhVKupt8RSuvHI868rfYOcypD4we5TT7qunjRKJ852EIRh/Ql8sSTepXgXKOUJnt1w==}
+ peerDependencies:
+ slate: '>=0.99.0'
+
+ slate-hyperscript@0.100.0:
+ resolution: {integrity: sha512-fb2KdAYg6RkrQGlqaIi4wdqz3oa0S4zKNBJlbnJbNOwa23+9FLD6oPVx9zUGqCSIpy+HIpOeqXrg0Kzwh/Ii4A==}
+ peerDependencies:
+ slate: '>=0.65.3'
+
+ slate-react@0.120.0:
+ resolution: {integrity: sha512-CMEJzozriddBjVmbxNvc2erCkXUuEkgdXIdM+jEMvxWMb51z0zhIVzgoxbGprVpzwBXY8Kv7aZOUDVMomzWH/g==}
+ peerDependencies:
+ react: '>=18.2.0'
+ react-dom: '>=18.2.0'
+ slate: '>=0.114.0'
+ slate-dom: '>=0.119.0'
+
+ slate@0.120.0:
+ resolution: {integrity: sha512-CXK/DADGgMZb4z9RTtXylzIDOxvmNJEF9bXV2bAGkLWhQ3rm7GORY9q0H/W41YJvAGZsLbH7nnrhMYr550hWDQ==}
+
snake-case@3.0.4:
resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==}
@@ -6702,6 +7290,14 @@ packages:
tailwind-merge@3.4.0:
resolution: {integrity: sha512-uSaO4gnW+b3Y2aWoWfFpX62vn2sR3skfhbjsEnaBI81WD1wBLlHZe5sWf0AqjksNdYTbGBEd0UasQMT3SNV15g==}
+ tailwind-merge@3.4.1:
+ resolution: {integrity: sha512-2OA0rFqWOkITEAOFWSBSApYkDeH9t2B3XSJuI4YztKBzK3mX0737A2qtxDZ7xkw9Zfh0bWl+r34sF3HXV+Ig7Q==}
+
+ tailwind-scrollbar-hide@4.0.0:
+ resolution: {integrity: sha512-gobtvVcThB2Dxhy0EeYSS1RKQJ5baDFkamkhwBvzvevwX6L4XQfpZ3me9s25Ss1ecFVT5jPYJ50n+7xTBJG9WQ==}
+ peerDependencies:
+ tailwindcss: '>=3.0.0 || >= 4.0.0 || >= 4.0.0-beta.8 || >= 4.0.0-alpha.20'
+
tailwindcss-animate@1.0.7:
resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
peerDependencies:
@@ -6725,6 +7321,9 @@ packages:
resolution: {integrity: sha512-nt6AMGKW1p/70DF/hGBdJB57B8Tspmbp5gfJ8ilhLnt7kkr2ye7hzD6NVG8GGErk2HWF34igrL2CXmNIkzKqKw==}
engines: {node: '>=18'}
+ tiny-invariant@1.3.1:
+ resolution: {integrity: sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==}
+
tinyexec@1.0.2:
resolution: {integrity: sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==}
engines: {node: '>=18'}
@@ -6744,6 +7343,9 @@ packages:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
+ toggle-selection@1.0.6:
+ resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==}
+
tough-cookie@5.1.2:
resolution: {integrity: sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==}
engines: {node: '>=16'}
@@ -6767,6 +7369,14 @@ packages:
peerDependencies:
typescript: '>=4.8.4'
+ ts-essentials@10.1.0:
+ resolution: {integrity: sha512-LirrVzbhIpFQ9BdGfqLnM9r7aP9rnyfeoxbP5ZEkdr531IaY21+KdebRSsbvqu28VDJtcDDn+AlGn95t0c52zQ==}
+ peerDependencies:
+ typescript: '>=4.5.0'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
tsconfig-paths@3.15.0:
resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==}
@@ -6894,6 +7504,24 @@ packages:
'@types/react':
optional: true
+ use-context-selector@1.4.4:
+ resolution: {integrity: sha512-pS790zwGxxe59GoBha3QYOwk8AFGp4DN6DOtH+eoqVmgBBRXVx4IlPDhJmmMiNQAgUaLlP+58aqRC3A4rdaSjg==}
+ peerDependencies:
+ react: '>=16.8.0'
+ react-dom: '*'
+ react-native: '*'
+ scheduler: '>=0.19.0'
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
+
+ use-deep-compare@1.3.0:
+ resolution: {integrity: sha512-94iG+dEdEP/Sl3WWde+w9StIunlV8Dgj+vkt5wTwMoFQLaijiEZSXXy8KtcStpmEDtIptRJiNeD4ACTtVvnIKA==}
+ peerDependencies:
+ react: '>=16.8.0'
+
use-intl@4.6.1:
resolution: {integrity: sha512-mUIj6QvJZ7Rk33mLDxRziz1YiBBAnIji8YW4TXXMdYHtaPEbVucrXD3iKQGAqJhbVn0VnjrEtIKYO1B18mfSJw==}
peerDependencies:
@@ -6927,6 +7555,11 @@ packages:
'@types/react':
optional: true
+ use-sync-external-store@1.4.0:
+ resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
use-sync-external-store@1.6.0:
resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==}
peerDependencies:
@@ -7109,6 +7742,11 @@ packages:
zod@4.2.1:
resolution: {integrity: sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==}
+ zustand-x@6.2.1:
+ resolution: {integrity: sha512-y3nQMQNx3BORY95vpuodJvh/8AqQu++S3q6mJYBSo1J0Q168Sy+FatqER658YESDqv2bwviXcIT3bgl/Ip6M5g==}
+ peerDependencies:
+ zustand: '>=5.0.2'
+
zustand@5.0.9:
resolution: {integrity: sha512-ALBtUj0AfjJt3uNRQoL1tL2tMvj6Gp/6e39dnfT6uzpelGru8v1tPOGBzayOWbPJvujM8JojDk3E1LxeFisBNg==}
engines: {node: '>=12.20.0'}
@@ -7198,10 +7836,10 @@ snapshots:
'@csstools/css-tokenizer': 3.0.4
lru-cache: 10.4.3
- '@assistant-ui/react-ai-sdk@1.1.20(@assistant-ui/react@0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)))(@types/react@19.2.7)(assistant-cloud@0.1.12)(react@19.2.3)':
+ '@assistant-ui/react-ai-sdk@1.1.20(@assistant-ui/react@0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)))(@types/react@19.2.7)(assistant-cloud@0.1.12)(react@19.2.3)':
dependencies:
'@ai-sdk/react': 2.0.118(react@19.2.3)(zod@4.2.1)
- '@assistant-ui/react': 0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
+ '@assistant-ui/react': 0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
ai: 5.0.116(zod@4.2.1)
react: 19.2.3
zod: 4.2.1
@@ -7209,9 +7847,9 @@ snapshots:
'@types/react': 19.2.7
assistant-cloud: 0.1.12
- '@assistant-ui/react-markdown@0.11.9(@assistant-ui/react@0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)))(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ '@assistant-ui/react-markdown@0.11.9(@assistant-ui/react@0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)))(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
- '@assistant-ui/react': 0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
+ '@assistant-ui/react': 0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
'@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3)
classnames: 2.5.1
@@ -7224,7 +7862,7 @@ snapshots:
- react-dom
- supports-color
- '@assistant-ui/react@0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))':
+ '@assistant-ui/react@0.11.53(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))':
dependencies:
'@assistant-ui/tap': 0.3.5(@types/react@19.2.7)(react@19.2.3)
'@radix-ui/primitive': 1.1.3
@@ -7242,7 +7880,7 @@ snapshots:
react-dom: 19.2.3(react@19.2.3)
react-textarea-autosize: 8.5.9(@types/react@19.2.7)(react@19.2.3)
zod: 4.2.1
- zustand: 5.0.9(@types/react@19.2.7)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
+ zustand: 5.0.9(@types/react@19.2.7)(immer@10.2.0)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
optionalDependencies:
'@types/react': 19.2.7
'@types/react-dom': 19.2.3(@types/react@19.2.7)
@@ -8022,7 +8660,7 @@ snapshots:
'@biomejs/cli-win32-x64@2.1.2':
optional: true
- '@blocknote/core@0.45.0(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(highlight.js@11.11.1)':
+ '@blocknote/core@0.45.0(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0)':
dependencies:
'@emoji-mart/data': 1.2.1
'@handlewithcare/prosemirror-inputrules': 0.1.3(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.4)
@@ -8044,7 +8682,7 @@ snapshots:
fast-deep-equal: 3.1.3
hast-util-from-dom: 5.0.1
prosemirror-dropcursor: 1.8.2
- prosemirror-highlight: 0.13.0(@shikijs/types@3.20.0)(@types/hast@3.0.4)(highlight.js@11.11.1)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-transform@1.10.5)(prosemirror-view@1.41.4)
+ prosemirror-highlight: 0.13.0(@shikijs/types@3.20.0)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-transform@1.10.5)(prosemirror-view@1.41.4)
prosemirror-model: 1.25.4
prosemirror-state: 1.4.4
prosemirror-tables: 1.8.3
@@ -8073,10 +8711,10 @@ snapshots:
- sugar-high
- supports-color
- '@blocknote/mantine@0.45.0(@floating-ui/dom@1.7.5)(@mantine/core@8.3.10(@mantine/hooks@8.3.10(react@19.2.3))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@mantine/hooks@8.3.10(react@19.2.3))(@mantine/utils@6.0.22(react@19.2.3))(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ '@blocknote/mantine@0.45.0(@floating-ui/dom@1.7.5)(@mantine/core@8.3.10(@mantine/hooks@8.3.10(react@19.2.3))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3))(@mantine/hooks@8.3.10(react@19.2.3))(@mantine/utils@6.0.22(react@19.2.3))(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
- '@blocknote/core': 0.45.0(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(highlight.js@11.11.1)
- '@blocknote/react': 0.45.0(@floating-ui/dom@1.7.5)(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@blocknote/core': 0.45.0(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0)
+ '@blocknote/react': 0.45.0(@floating-ui/dom@1.7.5)(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@mantine/core': 8.3.10(@mantine/hooks@8.3.10(react@19.2.3))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@mantine/hooks': 8.3.10(react@19.2.3)
'@mantine/utils': 6.0.22(react@19.2.3)
@@ -8096,9 +8734,9 @@ snapshots:
- sugar-high
- supports-color
- '@blocknote/react@0.45.0(@floating-ui/dom@1.7.5)(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ '@blocknote/react@0.45.0(@floating-ui/dom@1.7.5)(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
- '@blocknote/core': 0.45.0(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(highlight.js@11.11.1)
+ '@blocknote/core': 0.45.0(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0)
'@emoji-mart/data': 1.2.1
'@floating-ui/react': 0.27.16(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@floating-ui/utils': 0.2.10
@@ -8127,10 +8765,10 @@ snapshots:
- sugar-high
- supports-color
- '@blocknote/server-util@0.45.0(@floating-ui/dom@1.7.5)(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ '@blocknote/server-util@0.45.0(@floating-ui/dom@1.7.5)(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(lowlight@3.3.0)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.4)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
- '@blocknote/core': 0.45.0(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(highlight.js@11.11.1)
- '@blocknote/react': 0.45.0(@floating-ui/dom@1.7.5)(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@blocknote/core': 0.45.0(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0)
+ '@blocknote/react': 0.45.0(@floating-ui/dom@1.7.5)(@tiptap/extensions@3.14.0(@tiptap/core@3.14.0(@tiptap/pm@3.14.0))(@tiptap/pm@3.14.0))(@types/hast@3.0.4)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(highlight.js@11.11.1)(lowlight@3.3.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@tiptap/core': 3.14.0(@tiptap/pm@3.14.0)
'@tiptap/pm': 3.14.0
jsdom: 25.0.1
@@ -8751,6 +9389,8 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.5
+ '@juggle/resize-observer@3.4.0': {}
+
'@mantine/core@8.3.10(@mantine/hooks@8.3.10(react@19.2.3))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
'@floating-ui/react': 0.27.17(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -9001,6 +9641,217 @@ snapshots:
'@parcel/watcher-win32-ia32': 2.5.1
'@parcel/watcher-win32-x64': 2.5.1
+ '@platejs/autoformat@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ lodash: 4.17.23
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/basic-nodes@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/callout@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/code-block@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/combobox@52.0.15(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/core@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))':
+ dependencies:
+ '@platejs/slate': 52.0.10
+ '@udecode/react-hotkeys': 52.0.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@udecode/react-utils': 52.0.11(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@udecode/utils': 52.0.1
+ clsx: 2.1.1
+ html-entities: 2.6.0
+ is-hotkey: 0.2.0
+ jotai: 2.8.4(@types/react@19.2.7)(react@19.2.3)
+ jotai-optics: 0.4.0(jotai@2.8.4(@types/react@19.2.7)(react@19.2.3))(optics-ts@2.4.1)
+ jotai-x: 2.3.3(@types/react@19.2.7)(jotai@2.8.4(@types/react@19.2.7)(react@19.2.3))(react@19.2.3)
+ lodash: 4.17.23
+ nanoid: 5.1.6
+ optics-ts: 2.4.1
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+ slate: 0.120.0
+ slate-dom: 0.119.0(slate@0.120.0)
+ slate-hyperscript: 0.100.0(slate@0.120.0)
+ slate-react: 0.120.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(slate-dom@0.119.0(slate@0.120.0))(slate@0.120.0)
+ use-deep-compare: 1.3.0(react@19.2.3)
+ zustand: 5.0.9(@types/react@19.2.7)(immer@10.2.0)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
+ zustand-x: 6.2.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(zustand@5.0.9(@types/react@19.2.7)(immer@10.2.0)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)))
+ transitivePeerDependencies:
+ - '@types/react'
+ - immer
+ - react-native
+ - scheduler
+ - use-sync-external-store
+
+ '@platejs/dnd@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dnd-html5-backend@16.0.1)(react-dnd@16.0.1(@types/node@20.19.27)(@types/react@19.2.7)(react@19.2.3))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ lodash: 4.17.23
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ raf: 3.4.1
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dnd: 16.0.1(@types/node@20.19.27)(@types/react@19.2.7)(react@19.2.3)
+ react-dnd-html5-backend: 16.0.1
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/floating@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@floating-ui/core': 1.7.4
+ '@floating-ui/react': 0.27.17(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/indent@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/layout@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/link@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@platejs/floating': 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/list-classic@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ lodash: 4.17.23
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/markdown@52.1.0(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(typescript@5.9.3)':
+ dependencies:
+ marked: 15.0.12
+ mdast-util-math: 3.0.0
+ mdast-util-mdx: 3.0.0
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+ remark-mdx: 3.1.1
+ remark-parse: 11.0.0
+ remark-stringify: 11.0.0
+ ts-essentials: 10.1.0(typescript@5.9.3)
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+ - typescript
+
+ '@platejs/math@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ katex: 0.16.22
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/resizable@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/selection@52.0.16(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ copy-to-clipboard: 3.3.3
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/slash-command@52.0.15(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@platejs/combobox': 52.0.15(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/slate@52.0.10':
+ dependencies:
+ '@udecode/utils': 52.0.1
+ is-plain-object: 5.0.0
+ lodash: 4.17.23
+ slate: 0.120.0
+ slate-dom: 0.119.0(slate@0.120.0)
+
+ '@platejs/table@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@platejs/resizable': 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ lodash: 4.17.23
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/toggle@52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@platejs/indent': 52.0.11(platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)))(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ lodash: 4.17.23
+ platejs: 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@platejs/utils@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))':
+ dependencies:
+ '@platejs/core': 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ '@platejs/slate': 52.0.10
+ '@udecode/react-utils': 52.0.11(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@udecode/utils': 52.0.1
+ clsx: 2.1.1
+ lodash: 4.17.23
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+ transitivePeerDependencies:
+ - '@types/react'
+ - immer
+ - react-native
+ - scheduler
+ - use-sync-external-store
+
'@posthog/core@1.15.0':
dependencies:
cross-spawn: 7.0.6
@@ -9057,6 +9908,15 @@ snapshots:
'@radix-ui/primitive@1.1.3': {}
+ '@radix-ui/react-accessible-icon@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
'@radix-ui/react-accordion@1.2.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
'@radix-ui/primitive': 1.1.3
@@ -9097,6 +9957,28 @@ snapshots:
'@types/react': 19.2.7
'@types/react-dom': 19.2.3(@types/react@19.2.7)
+ '@radix-ui/react-aspect-ratio@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
+ '@radix-ui/react-avatar@1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
'@radix-ui/react-avatar@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
'@radix-ui/react-context': 1.1.3(@types/react@19.2.7)(react@19.2.3)
@@ -9386,6 +10268,37 @@ snapshots:
'@types/react': 19.2.7
'@types/react-dom': 19.2.3(@types/react@19.2.7)
+ '@radix-ui/react-form@0.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-label': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
+ '@radix-ui/react-hover-card@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
'@radix-ui/react-id@1.0.0(react@19.2.3)':
dependencies:
'@babel/runtime': 7.28.4
@@ -9407,6 +10320,15 @@ snapshots:
optionalDependencies:
'@types/react': 19.2.7
+ '@radix-ui/react-label@2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
'@radix-ui/react-label@2.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
'@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -9442,6 +10364,24 @@ snapshots:
'@types/react': 19.2.7
'@types/react-dom': 19.2.3(@types/react@19.2.7)
+ '@radix-ui/react-menubar@1.1.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
'@radix-ui/react-navigation-menu@1.2.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
'@radix-ui/primitive': 1.1.3
@@ -9464,6 +10404,42 @@ snapshots:
'@types/react': 19.2.7
'@types/react-dom': 19.2.3(@types/react@19.2.7)
+ '@radix-ui/react-one-time-password-field@0.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/number': 1.1.1
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
+ '@radix-ui/react-password-toggle-field@0.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-id': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.7)(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
'@radix-ui/react-popover@1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
'@radix-ui/primitive': 1.1.3
@@ -9489,7 +10465,7 @@ snapshots:
'@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
- '@floating-ui/react-dom': 2.1.6(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@floating-ui/react-dom': 2.1.7(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
'@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3)
'@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3)
@@ -9596,6 +10572,16 @@ snapshots:
'@types/react': 19.2.7
'@types/react-dom': 19.2.3(@types/react@19.2.7)
+ '@radix-ui/react-progress@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
'@radix-ui/react-radio-group@1.3.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
'@radix-ui/primitive': 1.1.3
@@ -9677,6 +10663,15 @@ snapshots:
'@types/react': 19.2.7
'@types/react-dom': 19.2.3(@types/react@19.2.7)
+ '@radix-ui/react-separator@1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
'@radix-ui/react-separator@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
'@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
@@ -9764,6 +10759,26 @@ snapshots:
'@types/react': 19.2.7
'@types/react-dom': 19.2.3(@types/react@19.2.7)
+ '@radix-ui/react-toast@1.2.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
'@radix-ui/react-toggle-group@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
'@radix-ui/primitive': 1.1.3
@@ -9790,6 +10805,21 @@ snapshots:
'@types/react': 19.2.7
'@types/react-dom': 19.2.3(@types/react@19.2.7)
+ '@radix-ui/react-toolbar@1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
'@radix-ui/react-tooltip@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
dependencies:
'@radix-ui/primitive': 1.1.3
@@ -9934,6 +10964,12 @@ snapshots:
'@radix-ui/rect@1.1.1': {}
+ '@react-dnd/asap@5.0.2': {}
+
+ '@react-dnd/invariant@4.0.2': {}
+
+ '@react-dnd/shallowequal@4.0.2': {}
+
'@remirror/core-constants@3.0.0': {}
'@rollup/rollup-android-arm-eabi@4.55.1':
@@ -10624,6 +11660,36 @@ snapshots:
'@typescript-eslint/types': 8.50.0
eslint-visitor-keys: 4.2.1
+ '@udecode/cn@52.0.11(@types/react@19.2.7)(class-variance-authority@0.7.1)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(tailwind-merge@3.4.0)':
+ dependencies:
+ '@udecode/react-utils': 52.0.11(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ class-variance-authority: 0.7.1
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+ tailwind-merge: 3.4.0
+ transitivePeerDependencies:
+ - '@types/react'
+
+ '@udecode/react-hotkeys@52.0.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+
+ '@udecode/react-utils@52.0.11(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)':
+ dependencies:
+ '@radix-ui/react-slot': 1.2.4(@types/react@19.2.7)(react@19.2.3)
+ '@udecode/utils': 52.0.1
+ clsx: 2.1.1
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+ transitivePeerDependencies:
+ - '@types/react'
+
+ '@udecode/utils@52.0.1': {}
+
'@ungap/structured-clone@1.3.0': {}
'@unrs/resolver-binding-android-arm-eabi@1.11.1':
@@ -11022,6 +12088,10 @@ snapshots:
convert-source-map@2.0.0: {}
+ copy-to-clipboard@3.3.3:
+ dependencies:
+ toggle-selection: 1.0.6
+
core-js-compat@3.48.0:
dependencies:
browserslist: 4.28.1
@@ -11165,6 +12235,14 @@ snapshots:
diff-match-patch@1.0.5: {}
+ direction@1.0.4: {}
+
+ dnd-core@16.0.1:
+ dependencies:
+ '@react-dnd/asap': 5.0.2
+ '@react-dnd/invariant': 4.0.2
+ redux: 4.2.1
+
doctrine@2.1.0:
dependencies:
esutils: 2.0.3
@@ -11236,7 +12314,7 @@ snapshots:
react: 19.2.3
react-dom: 19.2.3(react@19.2.3)
react-easy-sort: 1.8.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
- tailwind-merge: 3.4.0
+ tailwind-merge: 3.4.1
transitivePeerDependencies:
- '@types/react'
- '@types/react-dom'
@@ -12211,15 +13289,20 @@ snapshots:
highlight.js@10.7.3: {}
- highlight.js@11.11.1:
- optional: true
+ highlight.js@11.11.1: {}
highlightjs-vue@1.0.0: {}
+ hoist-non-react-statics@3.3.2:
+ dependencies:
+ react-is: 16.13.1
+
html-encoding-sniffer@4.0.0:
dependencies:
whatwg-encoding: 3.1.1
+ html-entities@2.6.0: {}
+
html-url-attributes@3.0.1: {}
html-void-elements@3.0.0: {}
@@ -12253,6 +13336,8 @@ snapshots:
image-size@2.0.2: {}
+ immer@10.2.0: {}
+
import-fresh@3.3.1:
dependencies:
parent-module: 1.0.1
@@ -12367,6 +13452,8 @@ snapshots:
is-hexadecimal@2.0.1: {}
+ is-hotkey@0.2.0: {}
+
is-map@2.0.3: {}
is-negative-zero@2.0.3: {}
@@ -12380,6 +13467,8 @@ snapshots:
is-plain-obj@4.1.0: {}
+ is-plain-object@5.0.0: {}
+
is-potential-custom-element-name@1.0.1: {}
is-regex@1.2.1:
@@ -12438,6 +13527,11 @@ snapshots:
jiti@2.6.1: {}
+ jotai-optics@0.4.0(jotai@2.8.4(@types/react@19.2.7)(react@19.2.3))(optics-ts@2.4.1):
+ dependencies:
+ jotai: 2.8.4(@types/react@19.2.7)(react@19.2.3)
+ optics-ts: 2.4.1
+
jotai-tanstack-query@0.11.0(@tanstack/query-core@5.90.12)(@tanstack/react-query@5.90.12(react@19.2.3))(jotai@2.16.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.7)(react@19.2.3))(react@19.2.3):
dependencies:
'@tanstack/query-core': 5.90.12
@@ -12446,6 +13540,13 @@ snapshots:
'@tanstack/react-query': 5.90.12(react@19.2.3)
react: 19.2.3
+ jotai-x@2.3.3(@types/react@19.2.7)(jotai@2.8.4(@types/react@19.2.7)(react@19.2.3))(react@19.2.3):
+ dependencies:
+ jotai: 2.8.4(@types/react@19.2.7)(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ react: 19.2.3
+
jotai@2.16.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.7)(react@19.2.3):
optionalDependencies:
'@babel/core': 7.29.0
@@ -12453,6 +13554,11 @@ snapshots:
'@types/react': 19.2.7
react: 19.2.3
+ jotai@2.8.4(@types/react@19.2.7)(react@19.2.3):
+ optionalDependencies:
+ '@types/react': 19.2.7
+ react: 19.2.3
+
js-tokens@4.0.0: {}
js-yaml@4.1.1:
@@ -12518,6 +13624,10 @@ snapshots:
object.assign: 4.1.7
object.values: 1.2.1
+ katex@0.16.22:
+ dependencies:
+ commander: 8.3.0
+
katex@0.16.28:
dependencies:
commander: 8.3.0
@@ -12604,8 +13714,12 @@ snapshots:
lodash.debounce@4.0.8: {}
+ lodash.mapvalues@4.6.0: {}
+
lodash.merge@4.6.2: {}
+ lodash@4.17.23: {}
+
long@5.3.2: {}
longest-streak@3.1.0: {}
@@ -12623,6 +13737,12 @@ snapshots:
fault: 1.0.4
highlight.js: 10.7.3
+ lowlight@3.3.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ devlop: 1.1.0
+ highlight.js: 11.11.1
+
lru-cache@10.4.3: {}
lru-cache@5.1.1:
@@ -12650,6 +13770,8 @@ snapshots:
markdown-table@3.0.4: {}
+ marked@15.0.12: {}
+
marked@17.0.2: {}
math-intrinsics@1.1.0: {}
@@ -13154,6 +14276,8 @@ snapshots:
ms@2.1.3: {}
+ mutative@1.1.0: {}
+
nanoid@3.3.11: {}
nanoid@5.1.6: {}
@@ -13296,6 +14420,8 @@ snapshots:
regex: 6.1.0
regex-recursion: 6.0.2
+ optics-ts@2.4.1: {}
+
optionator@0.9.4:
dependencies:
deep-is: 0.1.4
@@ -13365,6 +14491,8 @@ snapshots:
path-type@4.0.0: {}
+ performance-now@2.1.0: {}
+
pg-cloudflare@1.2.7:
optional: true
@@ -13406,6 +14534,24 @@ snapshots:
picomatch@4.0.3: {}
+ platejs@52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3)):
+ dependencies:
+ '@platejs/core': 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ '@platejs/slate': 52.0.10
+ '@platejs/utils': 52.0.17(@types/react@19.2.7)(immer@10.2.0)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(use-sync-external-store@1.6.0(react@19.2.3))
+ '@udecode/react-hotkeys': 52.0.11(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@udecode/react-utils': 52.0.11(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@udecode/utils': 52.0.1
+ react: 19.2.3
+ react-compiler-runtime: 1.0.0(react@19.2.3)
+ react-dom: 19.2.3(react@19.2.3)
+ transitivePeerDependencies:
+ - '@types/react'
+ - immer
+ - react-native
+ - scheduler
+ - use-sync-external-store
+
po-parser@2.0.0: {}
possible-typed-array-names@1.1.0: {}
@@ -13527,11 +14673,12 @@ snapshots:
prosemirror-state: 1.4.4
prosemirror-view: 1.41.4
- prosemirror-highlight@0.13.0(@shikijs/types@3.20.0)(@types/hast@3.0.4)(highlight.js@11.11.1)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-transform@1.10.5)(prosemirror-view@1.41.4):
+ prosemirror-highlight@0.13.0(@shikijs/types@3.20.0)(@types/hast@3.0.4)(highlight.js@11.11.1)(lowlight@3.3.0)(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-transform@1.10.5)(prosemirror-view@1.41.4):
optionalDependencies:
'@shikijs/types': 3.20.0
'@types/hast': 3.0.4
highlight.js: 11.11.1
+ lowlight: 3.3.0
prosemirror-model: 1.25.4
prosemirror-state: 1.4.4
prosemirror-transform: 1.10.5
@@ -13628,6 +14775,8 @@ snapshots:
'@types/node': 20.19.27
long: 5.3.2
+ proxy-compare@2.6.0: {}
+
pump@3.0.3:
dependencies:
end-of-stream: 1.4.5
@@ -13642,6 +14791,73 @@ snapshots:
queue-microtask@1.2.3: {}
+ radix-ui@1.4.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3):
+ dependencies:
+ '@radix-ui/primitive': 1.1.3
+ '@radix-ui/react-accessible-icon': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-alert-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-aspect-ratio': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-avatar': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-checkbox': 1.3.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-collection': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-context-menu': 2.2.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-direction': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-dismissable-layer': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-dropdown-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-focus-guards': 1.1.3(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-focus-scope': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-form': 0.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-hover-card': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-label': 2.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-menu': 2.1.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-menubar': 1.1.16(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-navigation-menu': 1.2.14(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-one-time-password-field': 0.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-password-toggle-field': 0.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-popover': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-popper': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-portal': 1.1.9(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-presence': 1.1.5(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-primitive': 2.1.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-progress': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-radio-group': 1.3.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-roving-focus': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-scroll-area': 1.2.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-select': 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-separator': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-slider': 1.3.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-slot': 1.2.3(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-switch': 1.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-toast': 1.2.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-toggle': 1.1.10(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-toggle-group': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-toolbar': 1.1.11(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-tooltip': 1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ '@radix-ui/react-use-callback-ref': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-controllable-state': 1.2.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-effect-event': 0.0.2(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-escape-keydown': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-is-hydrated': 0.1.0(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-layout-effect': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-use-size': 1.1.1(@types/react@19.2.7)(react@19.2.3)
+ '@radix-ui/react-visually-hidden': 1.2.3(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.3(react@19.2.3))(react@19.2.3)
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ optionalDependencies:
+ '@types/react': 19.2.7
+ '@types/react-dom': 19.2.3(@types/react@19.2.7)
+
+ raf@3.4.1:
+ dependencies:
+ performance-now: 2.1.0
+
rc@1.2.8:
dependencies:
deep-extend: 0.6.0
@@ -13650,13 +14866,33 @@ snapshots:
strip-json-comments: 2.0.1
optional: true
- react-day-picker@9.13.0(react@19.2.3):
+ react-compiler-runtime@1.0.0(react@19.2.3):
+ dependencies:
+ react: 19.2.3
+
+ react-day-picker@9.13.2(react@19.2.3):
dependencies:
'@date-fns/tz': 1.4.1
date-fns: 4.1.0
date-fns-jalali: 4.1.0-0
react: 19.2.3
+ react-dnd-html5-backend@16.0.1:
+ dependencies:
+ dnd-core: 16.0.1
+
+ react-dnd@16.0.1(@types/node@20.19.27)(@types/react@19.2.7)(react@19.2.3):
+ dependencies:
+ '@react-dnd/invariant': 4.0.2
+ '@react-dnd/shallowequal': 4.0.2
+ dnd-core: 16.0.1
+ fast-deep-equal: 3.1.3
+ hoist-non-react-statics: 3.3.2
+ react: 19.2.3
+ optionalDependencies:
+ '@types/node': 20.19.27
+ '@types/react': 19.2.7
+
react-dom@19.2.3(react@19.2.3):
dependencies:
react: 19.2.3
@@ -13785,6 +15021,15 @@ snapshots:
transitivePeerDependencies:
- '@types/react'
+ react-tracked@1.7.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0):
+ dependencies:
+ proxy-compare: 2.6.0
+ react: 19.2.3
+ scheduler: 0.27.0
+ use-context-selector: 1.4.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)
+ optionalDependencies:
+ react-dom: 19.2.3(react@19.2.3)
+
react-wrap-balancer@1.1.1(react@19.2.3):
dependencies:
react: 19.2.3
@@ -13829,6 +15074,10 @@ snapshots:
unified: 11.0.5
vfile: 6.0.3
+ redux@4.2.1:
+ dependencies:
+ '@babel/runtime': 7.28.4
+
reflect.getprototypeof@1.0.10:
dependencies:
call-bind: 1.0.8
@@ -14225,6 +15474,37 @@ snapshots:
simple-concat: 1.0.1
optional: true
+ slate-dom@0.119.0(slate@0.120.0):
+ dependencies:
+ '@juggle/resize-observer': 3.4.0
+ direction: 1.0.4
+ is-hotkey: 0.2.0
+ is-plain-object: 5.0.0
+ lodash: 4.17.23
+ scroll-into-view-if-needed: 3.1.0
+ slate: 0.120.0
+ tiny-invariant: 1.3.1
+
+ slate-hyperscript@0.100.0(slate@0.120.0):
+ dependencies:
+ is-plain-object: 5.0.0
+ slate: 0.120.0
+
+ slate-react@0.120.0(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(slate-dom@0.119.0(slate@0.120.0))(slate@0.120.0):
+ dependencies:
+ '@juggle/resize-observer': 3.4.0
+ direction: 1.0.4
+ is-hotkey: 0.2.0
+ lodash: 4.17.23
+ react: 19.2.3
+ react-dom: 19.2.3(react@19.2.3)
+ scroll-into-view-if-needed: 3.1.0
+ slate: 0.120.0
+ slate-dom: 0.119.0(slate@0.120.0)
+ tiny-invariant: 1.3.1
+
+ slate@0.120.0: {}
+
snake-case@3.0.4:
dependencies:
dot-case: 3.0.4
@@ -14394,6 +15674,12 @@ snapshots:
tailwind-merge@3.4.0: {}
+ tailwind-merge@3.4.1: {}
+
+ tailwind-scrollbar-hide@4.0.0(tailwindcss@4.1.18):
+ dependencies:
+ tailwindcss: 4.1.18
+
tailwindcss-animate@1.0.7(tailwindcss@4.1.18):
dependencies:
tailwindcss: 4.1.18
@@ -14421,6 +15707,8 @@ snapshots:
throttleit@2.1.0: {}
+ tiny-invariant@1.3.1: {}
+
tinyexec@1.0.2: {}
tinyglobby@0.2.15:
@@ -14438,6 +15726,8 @@ snapshots:
dependencies:
is-number: 7.0.0
+ toggle-selection@1.0.6: {}
+
tough-cookie@5.1.2:
dependencies:
tldts: 6.1.86
@@ -14456,6 +15746,10 @@ snapshots:
dependencies:
typescript: 5.9.3
+ ts-essentials@10.1.0(typescript@5.9.3):
+ optionalDependencies:
+ typescript: 5.9.3
+
tsconfig-paths@3.15.0:
dependencies:
'@types/json5': 0.0.29
@@ -14634,6 +15928,18 @@ snapshots:
optionalDependencies:
'@types/react': 19.2.7
+ use-context-selector@1.4.4(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0):
+ dependencies:
+ react: 19.2.3
+ scheduler: 0.27.0
+ optionalDependencies:
+ react-dom: 19.2.3(react@19.2.3)
+
+ use-deep-compare@1.3.0(react@19.2.3):
+ dependencies:
+ dequal: 2.0.3
+ react: 19.2.3
+
use-intl@4.6.1(react@19.2.3):
dependencies:
'@formatjs/fast-memoize': 2.2.7
@@ -14662,6 +15968,10 @@ snapshots:
optionalDependencies:
'@types/react': 19.2.7
+ use-sync-external-store@1.4.0(react@19.2.3):
+ dependencies:
+ react: 19.2.3
+
use-sync-external-store@1.6.0(react@19.2.3):
dependencies:
react: 19.2.3
@@ -14818,9 +16128,24 @@ snapshots:
zod@4.2.1: {}
- zustand@5.0.9(@types/react@19.2.7)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)):
+ zustand-x@6.2.1(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)(zustand@5.0.9(@types/react@19.2.7)(immer@10.2.0)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))):
+ dependencies:
+ immer: 10.2.0
+ lodash.mapvalues: 4.6.0
+ mutative: 1.1.0
+ react-tracked: 1.7.14(react-dom@19.2.3(react@19.2.3))(react@19.2.3)(scheduler@0.27.0)
+ use-sync-external-store: 1.4.0(react@19.2.3)
+ zustand: 5.0.9(@types/react@19.2.7)(immer@10.2.0)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3))
+ transitivePeerDependencies:
+ - react
+ - react-dom
+ - react-native
+ - scheduler
+
+ zustand@5.0.9(@types/react@19.2.7)(immer@10.2.0)(react@19.2.3)(use-sync-external-store@1.6.0(react@19.2.3)):
optionalDependencies:
'@types/react': 19.2.7
+ immer: 10.2.0
react: 19.2.3
use-sync-external-store: 1.6.0(react@19.2.3)