diff --git a/.gitignore b/.gitignore index f8b97dd..a2b30d0 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,7 @@ apps/web/test-results/ apps/web/playwright-report/ apps/web/blob-report/ apps/web/.playwright-artifacts/ +.playwright-cli/ **/trace.zip **/*.webm .vercel/ diff --git a/apps/web/package.json b/apps/web/package.json index a844f66..4fa7d88 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -17,6 +17,10 @@ "@plot/api-client": "workspace:*", "@plot/auth": "workspace:*", "@stylexjs/stylex": "^0.19.0", + "@tiptap/core": "^3.30.2", + "@tiptap/extension-placeholder": "^3.30.2", + "@tiptap/react": "^3.30.2", + "@tiptap/starter-kit": "^3.30.2", "better-auth": "^1.6.23", "blobatar": "0.2.0", "clsx": "^2.1.1", @@ -26,7 +30,8 @@ "react": "19.2.4", "react-dom": "19.2.4", "resend": "^6.17.1", - "tailwind-merge": "^3.6.0" + "tailwind-merge": "^3.6.0", + "tiptap-markdown": "^0.9.0" }, "devDependencies": { "@tailwindcss/postcss": "^4", diff --git a/apps/web/src/features/artifacts/artifact-document-surface.tsx b/apps/web/src/features/artifacts/artifact-document-surface.tsx index 56137b8..b41a226 100644 --- a/apps/web/src/features/artifacts/artifact-document-surface.tsx +++ b/apps/web/src/features/artifacts/artifact-document-surface.tsx @@ -2,7 +2,7 @@ import type { Artifact, ArtifactHistoryDetail, PlotApiClient } from "@plot/api-client"; -import { CitedDraftEditor, type SaveArtifactInput } from "@/features/citations/cited-draft-editor"; +import { TiptapDraftEditor, type SaveArtifactInput } from "@/features/citations/tiptap-draft-editor"; import { ExportDialog } from "@/features/citations/export-dialog"; type ArtifactDocumentSurfaceProps = { @@ -47,7 +47,7 @@ export function ArtifactDocumentSurface({ {!workspacePresentation ? (

{shownPack.title || "Generated artifact"}

) : null} - :

Editing and delivery are disabled for this snapshot.

} - ({ ), })); -vi.mock("@/features/citations/cited-draft-editor", () => ({ CitedDraftEditor: () =>
Reviewed artifact
})); +vi.mock("@/features/citations/tiptap-draft-editor", () => ({ TiptapDraftEditor: () =>
Reviewed artifact
})); vi.mock("@/features/citations/export-dialog", () => ({ ExportDialog: ({ presentation }: { presentation?: string }) => presentation === "copy" ? : null })); vi.mock("@/features/citations/artifact-history-panel", () => ({ ArtifactHistoryPanel: () =>
History
})); diff --git a/apps/web/src/features/citations/tiptap-citation-extension.tsx b/apps/web/src/features/citations/tiptap-citation-extension.tsx new file mode 100644 index 0000000..1274baa --- /dev/null +++ b/apps/web/src/features/citations/tiptap-citation-extension.tsx @@ -0,0 +1,317 @@ +"use client"; + +import { Node as TiptapNode, mergeAttributes } from "@tiptap/core"; +import { NodeViewWrapper, ReactNodeViewRenderer, type NodeViewProps } from "@tiptap/react"; +import { Citation } from "@astryxdesign/core/Citation"; +import { ExternalLink, ChevronLeft, ChevronRight, X } from "lucide-react"; +import { useState, useId, useRef, useEffect, type ReactNode } from "react"; + +export type CitationSourceItem = { + title: string; + url: string; + provider?: string; + excerpt?: string; +}; + +export const TiptapCitationExtension = TiptapNode.create({ + name: "citation", + group: "inline", + inline: true, + atom: true, + selectable: true, + + addAttributes() { + return { + statementId: { + default: null, + parseHTML: (element) => element.getAttribute("data-statement-id"), + renderHTML: (attributes) => ({ + "data-statement-id": attributes.statementId, + }), + }, + sources: { + default: [], + parseHTML: (element) => { + try { + const raw = element.getAttribute("data-sources"); + return raw ? JSON.parse(raw) : []; + } catch { + return []; + } + }, + renderHTML: (attributes) => ({ + "data-sources": JSON.stringify(attributes.sources || []), + }), + }, + number: { + default: 1, + parseHTML: (element) => Number(element.getAttribute("data-number")) || 1, + renderHTML: (attributes) => ({ + "data-number": attributes.number, + }), + }, + }; + }, + + parseHTML() { + return [{ tag: "span[data-citation-node]" }]; + }, + + renderHTML({ HTMLAttributes }) { + return ["span", mergeAttributes(HTMLAttributes, { "data-citation-node": "" })]; + }, + + addNodeView() { + return ReactNodeViewRenderer(TiptapCitationNodeView); + }, +}); + +export function TiptapCitationNodeView({ node }: NodeViewProps) { + const { sources = [], number = 1 } = node.attrs as { + sources: CitationSourceItem[]; + number: number; + statementId: string | null; + }; + const [open, setOpen] = useState(false); + const [currentIndex, setCurrentIndex] = useState(0); + const popoverId = useId(); + const popoverRef = useRef(null); + const triggerRef = useRef(null); + + const sourceList: CitationSourceItem[] = sources.length + ? sources + : [{ title: "Source", url: "#" }]; + const currentSource = sourceList[currentIndex] || sourceList[0]; + const primarySource = sourceList[0]; + const additionalCount = sourceList.length - 1; + + useEffect(() => { + if (!open) return; + + function handleOutsideClick(event: Event) { + if ( + event.target instanceof Node && + !popoverRef.current?.contains(event.target) && + !triggerRef.current?.contains(event.target) + ) { + setOpen(false); + } + } + + function handleKeyDown(event: KeyboardEvent) { + if (event.key === "Escape") { + event.preventDefault(); + setOpen(false); + } + } + + document.addEventListener("pointerdown", handleOutsideClick, true); + document.addEventListener("click", handleOutsideClick, true); + document.addEventListener("keydown", handleKeyDown); + return () => { + document.removeEventListener("pointerdown", handleOutsideClick, true); + document.removeEventListener("click", handleOutsideClick, true); + document.removeEventListener("keydown", handleKeyDown); + }; + }, [open]); + + return ( + + { + e.preventDefault(); + e.stopPropagation(); + setOpen((prev) => !prev); + }} + onKeyDown={(e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + setOpen((prev) => !prev); + } + }} + className="inline-flex cursor-pointer items-center transition-transform hover:opacity-90 active:scale-95" + > + 0 ? `${primarySource.title} +${additionalCount}` : primarySource.title, + url: primarySource.url, + icon: getSourceProviderIcon(primarySource), + }} + number={number} + variant="label" + /> + + + {open ? ( + + ) : null} + + ); +} + +function getSourceProviderIcon(source?: CitationSourceItem): ReactNode { + const url = (source?.url || "").toLowerCase(); + const provider = (source?.provider || "").toLowerCase(); + + if (url.includes("github.com") || provider === "github") { + return ( + + + + ); + } + + if (url.includes("linear.app") || provider === "linear") { + return ( + + + + ); + } + + if (url.includes("notion.so") || provider === "notion") { + return ( + + + + ); + } + + if (url.includes("slack.com") || provider === "slack") { + return ( + + + + + + + ); + } + + if (url.includes("figma.com") || provider === "figma") { + return ( + + + + + + + + ); + } + + return ( + + + + + + ); +} + +function resolveProviderName(source?: CitationSourceItem): string { + const url = (source?.url || "").toLowerCase(); + if (url.includes("github.com")) return "GitHub"; + if (url.includes("linear.app")) return "Linear"; + if (url.includes("notion.so")) return "Notion"; + if (url.includes("slack.com")) return "Slack"; + if (url.includes("figma.com")) return "Figma"; + return "Source"; +} diff --git a/apps/web/src/features/citations/tiptap-draft-editor.test.tsx b/apps/web/src/features/citations/tiptap-draft-editor.test.tsx new file mode 100644 index 0000000..48ad56b --- /dev/null +++ b/apps/web/src/features/citations/tiptap-draft-editor.test.tsx @@ -0,0 +1,114 @@ +// @vitest-environment jsdom + +import { render, screen, waitFor } from "@testing-library/react"; +import { describe, expect, it, vi } from "vitest"; + +import { TiptapDraftEditor } from "./tiptap-draft-editor"; +import type { Artifact } from "@plot/api-client"; + +const pack: Artifact = { + id: "pack-1", + status: "NEEDS_REVIEW", + title: "July changelog", + variant: { + id: "variant-1", + status: "NEEDS_REVIEW", + revisionId: "artifact-revision-1", + revisionNumber: 1, + lexicalContent: lexicalContent( + "Sign-in recovery now explains the next step.", + "The release is delightful.", + ), + sentences: [ + { + id: "sentence-1", + revisionId: "sentence-revision-1", + revisionNumber: 1, + orderIndex: 0, + body: "Sign-in recovery now explains the next step.", + origin: "GENERATED", + citations: [ + { + evidenceId: "evidence-1", + provider: "GITHUB", + sourceLabel: "PR #184", + originalUrl: "https://github.com/acme/plot/pull/184", + }, + ], + }, + { + id: "sentence-2", + revisionId: "sentence-revision-2", + revisionNumber: 1, + orderIndex: 1, + body: "The release is delightful.", + origin: "GENERATED", + citations: [], + }, + ], + sources: [ + { + evidenceId: "evidence-1", + provider: "GITHUB", + sourceLabel: "PR #184", + originalUrl: "https://github.com/acme/plot/pull/184", + statementIds: ["sentence-1"], + }, + ], + }, +}; + +function lexicalContent(...bodies: string[]) { + return { + root: { + children: bodies.map((body) => ({ + children: [{ detail: 0, format: 0, mode: "normal", style: "", text: body, type: "text", version: 1 }], + direction: null, + format: "", + indent: 0, + type: "paragraph", + version: 1, + })), + direction: null, + format: "", + indent: 0, + type: "root", + version: 1, + }, + }; +} + +describe("TiptapDraftEditor", () => { + it("renders historical snapshots read-only without a delivery edit control", () => { + render(); + + expect(screen.getByRole("textbox", { name: "Historical artifact content" })).toHaveAttribute("contenteditable", "false"); + expect(screen.queryByRole("button", { name: "Save draft" })).not.toBeInTheDocument(); + }); + + it("renders document text and Astryx inline citations correctly", async () => { + const onSaveArtifact = vi.fn().mockResolvedValue(pack); + render(); + + expect(screen.getByRole("textbox", { name: "Draft content" })).toBeInTheDocument(); + expect(screen.getByText("Sign-in recovery now explains the next step.")).toBeInTheDocument(); + expect(screen.getByText("The release is delightful.")).toBeInTheDocument(); + }); + + it("displays save confirmation status", async () => { + const onSaveArtifact = vi.fn().mockResolvedValue(pack); + const onSaveStateChange = vi.fn(); + + render( + , + ); + + await waitFor(() => { + expect(onSaveStateChange).toHaveBeenCalledWith("saved"); + }); + }); +}); diff --git a/apps/web/src/features/citations/tiptap-draft-editor.tsx b/apps/web/src/features/citations/tiptap-draft-editor.tsx new file mode 100644 index 0000000..6c7ef35 --- /dev/null +++ b/apps/web/src/features/citations/tiptap-draft-editor.tsx @@ -0,0 +1,410 @@ +"use client"; + +import { useEditor, EditorContent, type JSONContent } from "@tiptap/react"; +import StarterKit from "@tiptap/starter-kit"; +import Placeholder from "@tiptap/extension-placeholder"; +import { Markdown } from "tiptap-markdown"; +import { Save } from "lucide-react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; + +import type { + Artifact, + ContentSentence, + ContentStatementInput, +} from "@plot/api-client"; +import { SourcesPopover } from "./sources-popover"; +import { TiptapCitationExtension, type CitationSourceItem } from "./tiptap-citation-extension"; + +export type SaveArtifactInput = { + expectedRevisionNumber: number; + lexicalContent: Record; + statements: ContentStatementInput[]; +}; + +type TiptapDraftEditorProps = { + pack: Artifact; + onSaveArtifact: (input: SaveArtifactInput) => Promise; + onPackChange?: (pack: Artifact) => void; + readOnly?: boolean; + embedded?: boolean; + onSaveStateChange?: (state: "saved" | "saving" | "dirty" | "error") => void; + initialDraft?: Omit; + onDraftChange?: (draft: Omit) => void; + presentation?: "panel" | "document"; + saveRequestToken?: number; +}; + +export function TiptapDraftEditor(props: TiptapDraftEditorProps) { + const revisionKey = `${props.pack.variant.revisionId}:${props.pack.variant.revisionNumber}:${props.readOnly ? "read-only" : "editable"}`; + return ; +} + +function TiptapArtifactEditor({ + pack, + onSaveArtifact, + onPackChange, + readOnly = false, + embedded = false, + onSaveStateChange, + initialDraft, + onDraftChange, + presentation = "panel", + saveRequestToken, +}: TiptapDraftEditorProps) { + const sentences = useMemo( + () => [...pack.variant.sentences].sort((a, b) => a.orderIndex - b.orderIndex), + [pack.variant.sentences], + ); + const revisionNumber = pack.variant.revisionNumber; + const revisionKey = `${pack.variant.revisionId}:${revisionNumber}`; + const initialContent = useMemo( + () => initialDraft?.lexicalContent ?? pack.variant.lexicalContent, + [initialDraft?.lexicalContent, pack.variant.lexicalContent], + ); + + const initialTiptapDoc = useMemo( + () => convertToTiptapDoc(initialContent, sentences), + [initialContent, sentences], + ); + + const [saving, setSaving] = useState(false); + const [message, setMessage] = useState(""); + const previousSaveRequestRef = useRef(saveRequestToken); + const draftStateRef = useRef>(initialContent); + const draftStatementsRef = useRef( + initialDraft?.statements ?? defaultStatementsFor(sentences), + ); + + const editor = useEditor({ + immediatelyRender: false, + editable: !readOnly, + content: initialTiptapDoc, + extensions: [ + StarterKit.configure({ + heading: { levels: [1, 2, 3] }, + }), + Placeholder.configure({ + placeholder: "Write the source-backed artifact…", + }), + Markdown.configure({ + html: true, + tightLists: true, + }), + TiptapCitationExtension, + ], + editorProps: { + attributes: { + role: "textbox", + "aria-label": readOnly ? "Historical artifact content" : "Draft content", + "aria-readonly": readOnly ? "true" : "false", + class: presentation === "document" + ? "min-h-[720px] focus:outline-none text-[15px] leading-6 text-black/88 dark:text-white/88 prose prose-none max-w-none [&_h1]:mb-[22px] [&_h1]:font-display [&_h1]:text-[30px] [&_h1]:leading-[38px] [&_h2]:mb-[22px] [&_h2]:text-[19px] [&_h2]:font-semibold [&_h2]:leading-[26px] [&_li]:mb-1.5 [&_ol]:list-decimal [&_ol]:pl-5 [&_p]:mb-[22px] [&_ul]:list-disc [&_ul]:pl-5" + : `min-h-[260px] rounded-lg border border-black/10 px-4 py-4 text-[15px] leading-7 text-black/84 focus:outline-none focus-within:border-black/35 dark:border-white/12 dark:text-white/86 dark:focus-within:border-white/35 prose prose-none max-w-none ${ + readOnly ? "bg-black/[0.025] dark:bg-white/[0.025]" : "bg-white dark:bg-[#18181b]" + }`, + }, + }, + onUpdate: ({ editor: currentEditor }) => { + const json = currentEditor.getJSON(); + const lexicalJson = tiptapToLexicalJson(json); + draftStateRef.current = lexicalJson; + + // Extract statement inputs from block nodes + const statements = extractStatementsFromTiptap(json, sentences); + draftStatementsRef.current = statements; + + if (!readOnly) { + onDraftChange?.({ lexicalContent: lexicalJson, statements }); + onSaveStateChange?.("dirty"); + } + }, + }); + + useEffect(() => { + onSaveStateChange?.("saved"); + }, [onSaveStateChange, revisionKey]); + + const save = useCallback(async () => { + if (saving || readOnly) return; + setSaving(true); + setMessage(""); + onSaveStateChange?.("saving"); + try { + const updated = await onSaveArtifact({ + expectedRevisionNumber: revisionNumber, + lexicalContent: draftStateRef.current, + statements: draftStatementsRef.current, + }); + onPackChange?.(updated); + setMessage( + `Saved ${new Intl.DateTimeFormat(undefined, { + hour: "numeric", + minute: "2-digit", + }).format(new Date())}.`, + ); + onSaveStateChange?.("saved"); + } catch (error) { + setMessage(error instanceof Error ? error.message : "The draft could not be saved."); + onSaveStateChange?.("error"); + } finally { + setSaving(false); + } + }, [onPackChange, onSaveArtifact, onSaveStateChange, readOnly, revisionNumber, saving]); + + useEffect(() => { + if (saveRequestToken === undefined || previousSaveRequestRef.current === saveRequestToken) return; + previousSaveRequestRef.current = saveRequestToken; + void save(); + }, [save, saveRequestToken]); + + const documentPresentation = presentation === "document"; + + return ( +
+ {!documentPresentation ? ( +
+
+

+ {readOnly ? "Historical preview" : "Artifact document"} +

+

+ {readOnly + ? "This snapshot is read-only. Editing and delivery are disabled." + : "Edit the whole artifact. Sources stay outside the document and stay attached to it."} +

+
+ +
+ ) : null} + +
+ +
+ + {!documentPresentation ? ( +
+

+ {readOnly ? "Saved snapshot" : saving ? "Saving…" : message || "Saved"} +

+ {!readOnly ? ( + + ) : null} +
+ ) : null} + + {message ? ( +

+ {message} +

+ ) : null} +
+ ); +} + +// Converts Lexical or Tiptap JSON to a Tiptap Document with Inline Citation Nodes +function convertToTiptapDoc( + content: Record | undefined, + sentences: ContentSentence[], +): JSONContent { + if (!content) { + return { + type: "doc", + content: [{ type: "paragraph" }], + }; + } + + // If already in Tiptap format + if (content.type === "doc" && Array.isArray(content.content)) { + return content as JSONContent; + } + + // Convert Lexical AST to Tiptap JSON + const root = (content.root as Record) || content; + const children = Array.isArray(root.children) ? (root.children as Record[]) : []; + + if (!children.length) { + return { + type: "doc", + content: [{ type: "paragraph" }], + }; + } + + const tiptapContent: JSONContent[] = children.map((lexicalNode, blockIndex) => { + const nodeType = (lexicalNode.type as string) || "paragraph"; + const lexicalChildren = Array.isArray(lexicalNode.children) + ? (lexicalNode.children as Record[]) + : []; + + const paragraphContent: JSONContent[] = []; + + // Extract text nodes + for (const child of lexicalChildren) { + if (child.type === "text" && typeof child.text === "string" && child.text) { + paragraphContent.push({ + type: "text", + text: child.text, + }); + } else if (child.type === "linebreak") { + paragraphContent.push({ + type: "hardBreak", + }); + } + } + + // Attach inline citation if this sentence block has citations + const matchedSentence = sentences[blockIndex] || sentences.find((s) => s.orderIndex === blockIndex); + if (matchedSentence && matchedSentence.citations && matchedSentence.citations.length > 0) { + const citationSources: CitationSourceItem[] = matchedSentence.citations.map((c) => ({ + title: c.sourceLabel || "Source", + url: c.originalUrl || "#", + provider: c.provider || "GitHub", + })); + + paragraphContent.push({ + type: "citation", + attrs: { + statementId: matchedSentence.id, + number: blockIndex + 1, + sources: citationSources, + }, + }); + } + + if (nodeType === "heading") { + const tag = (lexicalNode.tag as string) || "h2"; + const level = tag === "h1" ? 1 : tag === "h3" ? 3 : 2; + return { + type: "heading", + attrs: { level }, + content: paragraphContent.length ? paragraphContent : undefined, + }; + } + + return { + type: "paragraph", + content: paragraphContent.length ? paragraphContent : undefined, + }; + }); + + return { + type: "doc", + content: tiptapContent.length ? tiptapContent : [{ type: "paragraph" }], + }; +} + +function extractStatementsFromTiptap( + doc: JSONContent, + originalSentences: ContentSentence[], +): ContentStatementInput[] { + const content = doc.content || []; + const statements: ContentStatementInput[] = []; + + content.forEach((block, index) => { + const text = extractTextFromBlock(block); + if (!text.trim()) return; + + const matchedSentence = originalSentences[index]; + statements.push({ + id: matchedSentence?.id, + orderIndex: index, + body: text.trim(), + }); + }); + + return statements.length + ? statements + : [{ id: null, orderIndex: 0, body: "Generated artifact" }]; +} + +function extractTextFromBlock(node: JSONContent): string { + if (!node.content) return ""; + return node.content + .map((child) => { + if (child.type === "text") return child.text || ""; + if (child.type === "hardBreak") return "\n"; + return ""; + }) + .join(""); +} + +function defaultStatementsFor(sentences: ContentSentence[]): ContentStatementInput[] { + return sentences.map((sentence) => ({ + id: sentence.id, + orderIndex: sentence.orderIndex, + body: sentence.body, + })); +} + +function tiptapToLexicalJson(doc: JSONContent): Record { + const content = doc.content || []; + return { + root: { + children: content.map((block) => { + const paragraphChildren: Record[] = []; + if (block.content) { + for (const child of block.content) { + if (child.type === "text" && child.text) { + paragraphChildren.push({ + detail: 0, + format: 0, + mode: "normal", + style: "", + text: child.text, + type: "text", + version: 1, + }); + } else if (child.type === "hardBreak") { + paragraphChildren.push({ + type: "linebreak", + version: 1, + }); + } + } + } + if (!paragraphChildren.length) { + paragraphChildren.push({ + detail: 0, + format: 0, + mode: "normal", + style: "", + text: "", + type: "text", + version: 1, + }); + } + return { + children: paragraphChildren, + direction: null, + format: "", + indent: 0, + type: "paragraph", + version: 1, + }; + }), + direction: null, + format: "", + indent: 0, + type: "root", + version: 1, + }, + }; +} diff --git a/bun.lock b/bun.lock index 1b4ddbd..324d050 100644 --- a/bun.lock +++ b/bun.lock @@ -16,6 +16,10 @@ "@plot/api-client": "workspace:*", "@plot/auth": "workspace:*", "@stylexjs/stylex": "^0.19.0", + "@tiptap/core": "^3.30.2", + "@tiptap/extension-placeholder": "^3.30.2", + "@tiptap/react": "^3.30.2", + "@tiptap/starter-kit": "^3.30.2", "better-auth": "^1.6.23", "blobatar": "0.2.0", "clsx": "^2.1.1", @@ -26,6 +30,7 @@ "react-dom": "19.2.4", "resend": "^6.17.1", "tailwind-merge": "^3.6.0", + "tiptap-markdown": "^0.9.0", }, "devDependencies": { "@tailwindcss/postcss": "^4", @@ -442,6 +447,64 @@ "@testing-library/react": ["@testing-library/react@16.3.2", "", { "dependencies": { "@babel/runtime": "7.29.7" }, "optionalDependencies": { "@types/react": "19.2.17", "@types/react-dom": "19.2.3" }, "peerDependencies": { "@testing-library/dom": "10.4.1", "react": "19.2.4", "react-dom": "19.2.4" } }, "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g=="], + "@tiptap/core": ["@tiptap/core@3.30.2", "", { "peerDependencies": { "@tiptap/pm": "3.30.2" } }, "sha512-QbZC/s1OOqcoUdkhIY16TjR/gCtR0qAk9e4bJwUqOJqZuv5ozqCL5hzWm22jjTPp6c6Ei2tPd6t30VwfIKW4lQ=="], + + "@tiptap/extension-blockquote": ["@tiptap/extension-blockquote@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2", "@tiptap/pm": "3.30.2" } }, "sha512-BOkwhZenek7vzXBOgKppSrlx4YryBdAYu1p1MXKn0R9A9eNmE2HVhmm0gG49+E8BhsE/TG8wKVclwET42JJiIg=="], + + "@tiptap/extension-bold": ["@tiptap/extension-bold@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2" } }, "sha512-MsvJhPgYejY2D9MhwYJv8AmscozvLBI8qtJ7YLdYZBWkMR4bgmxHq5+xqEfBsao9bOMMwBon9p3+P+/Tq5ReWA=="], + + "@tiptap/extension-bubble-menu": ["@tiptap/extension-bubble-menu@3.30.2", "", { "dependencies": { "@floating-ui/dom": "^1.0.0" }, "peerDependencies": { "@tiptap/core": "3.30.2", "@tiptap/pm": "3.30.2" } }, "sha512-oS0WiWNXHKpiPYMkcnHm1j7iEvufTGGtLFtcJJd3olb5OS6V2acoXVDL0nNJDmRQ32K3QXut3fbRcMseMxT+lw=="], + + "@tiptap/extension-bullet-list": ["@tiptap/extension-bullet-list@3.30.2", "", { "peerDependencies": { "@tiptap/extension-list": "3.30.2" } }, "sha512-+awIL/TUz4aB3rL68igU1rWfaaoBIAkPcakkktkRq8gYf0bd9eSb48P6kHkpx/3q+JyK7g9vsnltLNHNh6twnA=="], + + "@tiptap/extension-code": ["@tiptap/extension-code@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2" } }, "sha512-r8EZk3R9yGpF6v5xxafAU1HwrD/e+RpbfnmVi2TeB/ZHAsVO62fW96E32G0t6IdaCtOFtAd85hkDAaOfCT4yGg=="], + + "@tiptap/extension-code-block": ["@tiptap/extension-code-block@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2", "@tiptap/pm": "3.30.2" } }, "sha512-9otGKaQZmePHrLXFtCtz+BYDn5z4sSumTkUqQIQHz0gVxwPoTi7g51RedwxvViTb/zu2XV5ROXYLHIxKxypMPg=="], + + "@tiptap/extension-document": ["@tiptap/extension-document@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2" } }, "sha512-+xIv67V+/2L1uvz98FAT5W7kWEfHwfNV3MD7b4UsKPU0lhcCWuVOXy0JB8yYmdNExqpI7xT9g3MWzREoBvBQSg=="], + + "@tiptap/extension-dropcursor": ["@tiptap/extension-dropcursor@3.30.2", "", { "peerDependencies": { "@tiptap/extensions": "3.30.2" } }, "sha512-nyRKUmItATnKI9AiRChmjhcBbCEsNxRu+AaCz+cx8EvnAcNHsVRdNYL5PmBs3WlNA/Et4Eb2DG0hVQDnNF61eg=="], + + "@tiptap/extension-floating-menu": ["@tiptap/extension-floating-menu@3.30.2", "", { "peerDependencies": { "@floating-ui/dom": "^1.0.0", "@tiptap/core": "3.30.2", "@tiptap/pm": "3.30.2" } }, "sha512-A8PLvvh8W6PUMrqh+EpBerxm+Ucr0irGxJvwAnzYQmNGNIJ9U4OVgw4OcEU+9JH0gMmEzDcHzMPP2s/s1lIcyw=="], + + "@tiptap/extension-gapcursor": ["@tiptap/extension-gapcursor@3.30.2", "", { "peerDependencies": { "@tiptap/extensions": "3.30.2" } }, "sha512-7Xk0ut6FM+RAsvKxDN3bAtk7zvYZ6Aa8pawJ6s7dLAmLR9JwrZevlcL4FSrj4bR7rqKOj92RYCFxzgTEbWimag=="], + + "@tiptap/extension-hard-break": ["@tiptap/extension-hard-break@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2" } }, "sha512-IxSNgmG3d4OZdUTeebrOI7SxdIWXXJqlcGiSNDabWqxipUitfy3mZ3gDDE6G01koKxZRbhz4KIplAZlpxnTFSg=="], + + "@tiptap/extension-heading": ["@tiptap/extension-heading@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2" } }, "sha512-PblDvgSJ05p1t6hzyPi02xeiBjB0M2abReoGEImqSWCy79UqnAGacgsZo4EeEawtJV1NEP8chhvmX+nRtzdT1A=="], + + "@tiptap/extension-horizontal-rule": ["@tiptap/extension-horizontal-rule@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2", "@tiptap/pm": "3.30.2" } }, "sha512-j8aswLTsuEdJKC62DF+kw0EgvIRL7QMUyAVp2fdjR0qgM0ZVlEwCC4qIEq3kK9tFVU4kRtQ5BSj/jn6QwrlbCA=="], + + "@tiptap/extension-italic": ["@tiptap/extension-italic@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2" } }, "sha512-pp8uaiuXsUbLm5rYzR1jlWbwm1mAahRajdHwAKBtthFRB2rDvC7ZWhKaCSoKhZvfIDRmu9/B67+uAHoutL0dCA=="], + + "@tiptap/extension-link": ["@tiptap/extension-link@3.30.2", "", { "dependencies": { "linkifyjs": "^4.3.3" }, "peerDependencies": { "@tiptap/core": "3.30.2", "@tiptap/pm": "3.30.2" } }, "sha512-jwdcymKcrbFpj5hRAuGVLCq8FieVkGFnENyroYmvkad+XAt8ZLy/MTFYRN6SK3ukH6PZMY7H4iObGtciQaC5nw=="], + + "@tiptap/extension-list": ["@tiptap/extension-list@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2", "@tiptap/pm": "3.30.2" } }, "sha512-MIUpo1Bd9Rf1Qg+TNYNwDZ4xsfFeQahjU9Xhy6UcaszKQzbAM7KCzn5BObNytK1NdcqNHsC8Wj5vFvMKEzrXdw=="], + + "@tiptap/extension-list-item": ["@tiptap/extension-list-item@3.30.2", "", { "peerDependencies": { "@tiptap/extension-list": "3.30.2" } }, "sha512-HWgRCRlGxulE+hN1VUcnWD6P2NE08VBgGtcaxOfdXVqaI93BCK6AhRQZGpLsfKgajLk+5DXTBraaitwnBqzCxg=="], + + "@tiptap/extension-list-keymap": ["@tiptap/extension-list-keymap@3.30.2", "", { "peerDependencies": { "@tiptap/extension-list": "3.30.2" } }, "sha512-TTve3WOlQaYu1ahMqsQ/T0wzaxfgZvcOl3/OuPyInOi8QtxXhqGhFjmYe5jOr56G9W2QDuFWVsZecVwfDte9zg=="], + + "@tiptap/extension-ordered-list": ["@tiptap/extension-ordered-list@3.30.2", "", { "peerDependencies": { "@tiptap/extension-list": "3.30.2" } }, "sha512-Z7OO1HcF0idda1n6vodXeQ3h2ylN9JR4IfIGUYkar5Xl9JusK8PDETTBQZQn//96p49I2d+GoWsD2LXPtjHXXg=="], + + "@tiptap/extension-paragraph": ["@tiptap/extension-paragraph@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2" } }, "sha512-ulEu3LNt+kPVAWEnrhoz13Fs8Q/v/8NUxQbAeteuBchQ8joxJXuWExhpy1fUfZir5+b+W5z7/NesgPjZQfv47w=="], + + "@tiptap/extension-placeholder": ["@tiptap/extension-placeholder@3.30.2", "", { "peerDependencies": { "@tiptap/extensions": "3.30.2" } }, "sha512-Bj1seUvPCoRrD/LpzMoKD+jQIjxuc+oq931GpPq4wobSUUbD4pF/0NMwpCLpiHO19QnTQz8+9p2dqPdlc44LHA=="], + + "@tiptap/extension-strike": ["@tiptap/extension-strike@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2" } }, "sha512-fBLxMXz6hYIURzLOD+/L6aVATztsKham00ANWmGi13vN0hx2lQMYZffN+gR+QqiCDfMQxBXzrf5a7tJuDiQHLQ=="], + + "@tiptap/extension-text": ["@tiptap/extension-text@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2" } }, "sha512-n/iZnirgRmXet6f97kolAnP3j8DsgLSiTbz/KLWc8eBYiFmkjRzkuisOm5xuGdfGIxwpB4x3tlSF4ef4DLnbRg=="], + + "@tiptap/extension-underline": ["@tiptap/extension-underline@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2" } }, "sha512-SZiTMnvqXcnrtJX+X25ZbYsuDO83haGOVMBD/O+mAWYNYXhaSc5Rkph5czzItxrd+Yyp/vs4PiwD7XTNbfqmpA=="], + + "@tiptap/extensions": ["@tiptap/extensions@3.30.2", "", { "peerDependencies": { "@tiptap/core": "3.30.2", "@tiptap/pm": "3.30.2" } }, "sha512-2LqAHXk26QDsryW+beECxYeBzv5Ylk4GuB3cOmfghS7/G37R2W+Te3TkUK7BT0EWoDryvBT57/5q0DEFIhfZZg=="], + + "@tiptap/pm": ["@tiptap/pm@3.30.2", "", { "dependencies": { "prosemirror-changeset": "^2.4.1", "prosemirror-commands": "^1.7.1", "prosemirror-dropcursor": "^1.8.2", "prosemirror-gapcursor": "^1.4.1", "prosemirror-history": "^1.5.0", "prosemirror-inputrules": "^1.5.1", "prosemirror-keymap": "^1.2.3", "prosemirror-model": "^1.25.11", "prosemirror-schema-list": "^1.5.1", "prosemirror-state": "^1.4.4", "prosemirror-tables": "^1.8.5", "prosemirror-transform": "^1.12.0", "prosemirror-view": "^1.41.9" } }, "sha512-BJN8tUx4ppFN3R3cV/FJfrJbJkvo1lj4uciq+nwpjwzdRvFzqIuglWf+HLcJ6CwlYpLOHp7ArgkBg4Q5e60Gog=="], + + "@tiptap/react": ["@tiptap/react@3.30.2", "", { "dependencies": { "@types/use-sync-external-store": "^0.0.6", "fast-equals": "^5.3.3", "use-sync-external-store": "^1.4.0" }, "optionalDependencies": { "@tiptap/extension-bubble-menu": "^3.30.2", "@tiptap/extension-floating-menu": "^3.30.2" }, "peerDependencies": { "@tiptap/core": "3.30.2", "@tiptap/pm": "3.30.2", "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", "@types/react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0", "react": "^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-7hGaTstpUeTmQ008mCPkjz+GSlChWhucgy+PeX0z93v4+nh7qM5F+0lh+kJ9zo6Os5abO7v36GtgHRZdQI6+FQ=="], + + "@tiptap/starter-kit": ["@tiptap/starter-kit@3.30.2", "", { "dependencies": { "@tiptap/core": "3.30.2", "@tiptap/extension-blockquote": "3.30.2", "@tiptap/extension-bold": "3.30.2", "@tiptap/extension-bullet-list": "3.30.2", "@tiptap/extension-code": "3.30.2", "@tiptap/extension-code-block": "3.30.2", "@tiptap/extension-document": "3.30.2", "@tiptap/extension-dropcursor": "3.30.2", "@tiptap/extension-gapcursor": "3.30.2", "@tiptap/extension-hard-break": "3.30.2", "@tiptap/extension-heading": "3.30.2", "@tiptap/extension-horizontal-rule": "3.30.2", "@tiptap/extension-italic": "3.30.2", "@tiptap/extension-link": "3.30.2", "@tiptap/extension-list": "3.30.2", "@tiptap/extension-list-item": "3.30.2", "@tiptap/extension-list-keymap": "3.30.2", "@tiptap/extension-ordered-list": "3.30.2", "@tiptap/extension-paragraph": "3.30.2", "@tiptap/extension-strike": "3.30.2", "@tiptap/extension-text": "3.30.2", "@tiptap/extension-underline": "3.30.2", "@tiptap/extensions": "3.30.2", "@tiptap/pm": "3.30.2" } }, "sha512-fJSrhW1CyD4sjYA20evSP4Cp13B/HhbxCdM974K0xpHOVqvCtNU9w2s9hfq9mg2yGoU7MSNHKNYMkJjIi2/Xyw=="], + "@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="], "@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="], @@ -456,6 +519,12 @@ "@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="], + "@types/linkify-it": ["@types/linkify-it@3.0.5", "", {}, "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw=="], + + "@types/markdown-it": ["@types/markdown-it@13.0.9", "", { "dependencies": { "@types/linkify-it": "^3", "@types/mdurl": "^1" } }, "sha512-1XPwR0+MgXLWfTn9gCsZ55AHOKW1WN+P9vr0PaQh5aerR9LLQXUbjfEAFhjmEmyoYFWAyuN2Mqkn40MZ4ukjBw=="], + + "@types/mdurl": ["@types/mdurl@1.0.5", "", {}, "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA=="], + "@types/node": ["@types/node@20.19.43", "", { "dependencies": { "undici-types": "6.21.0" } }, "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA=="], "@types/pg": ["@types/pg@8.20.0", "", { "dependencies": { "@types/node": "20.19.43", "pg-protocol": "1.15.0", "pg-types": "2.2.0" } }, "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow=="], @@ -466,6 +535,8 @@ "@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="], + "@types/use-sync-external-store": ["@types/use-sync-external-store@0.0.6", "", {}, "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg=="], + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.62.0", "", { "dependencies": { "@eslint-community/regexpp": "4.12.2", "@typescript-eslint/scope-manager": "8.62.0", "@typescript-eslint/type-utils": "8.62.0", "@typescript-eslint/utils": "8.62.0", "@typescript-eslint/visitor-keys": "8.62.0", "ignore": "7.0.5", "natural-compare": "1.4.0", "ts-api-utils": "2.5.0" }, "peerDependencies": { "@typescript-eslint/parser": "8.62.0", "eslint": "9.39.4", "typescript": "5.9.3" } }, "sha512-o+mpz7EYiMzXoySXiKmzlabIvTVqUuK5yLrAedRPRDA0IpPFMUV1IXt6OqljIxX/kumN6EjUYp41Hqelh6p/Dw=="], "@typescript-eslint/parser": ["@typescript-eslint/parser@8.62.0", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.62.0", "@typescript-eslint/types": "8.62.0", "@typescript-eslint/typescript-estree": "8.62.0", "@typescript-eslint/visitor-keys": "8.62.0", "debug": "4.4.3" }, "peerDependencies": { "eslint": "9.39.4", "typescript": "5.9.3" } }, "sha512-dzHeT2gySzZtLDsuqxU9AkYgIsQoHAHtRBpOqM+Ofzx1Bwrd2RcCjQJ+6iQbsHOIR6NS33bF2W1k3blN1zLDrA=="], @@ -742,6 +813,8 @@ "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], + "fast-equals": ["fast-equals@5.4.1", "", {}, "sha512-DjlFSM5Pk9cGcL0q5QXl66eGzx0N6szNgaswwc5ZphlBohjTVJSnGgI+rJVOgOi65qUoQnDZN4nDqi33udtydQ=="], + "fast-glob": ["fast-glob@3.3.1", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "@nodelib/fs.walk": "1.2.8", "glob-parent": "5.1.2", "merge2": "1.4.1", "micromatch": "4.0.8" } }, "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg=="], "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], @@ -954,6 +1027,10 @@ "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="], + "linkify-it": ["linkify-it@5.0.2", "", { "dependencies": { "uc.micro": "^2.0.0" } }, "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q=="], + + "linkifyjs": ["linkifyjs@4.3.3", "", {}, "sha512-P8aEP5U/D1/IlTY2OeYsErdwh9bGuLE30NcXtKEjgdHcahveQoQwM2yZNsioQHsWFz0P7KKudisbrzCgR0sDHg=="], + "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], @@ -968,10 +1045,16 @@ "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], + "markdown-it": ["markdown-it@14.3.0", "", { "dependencies": { "argparse": "^2.0.1", "entities": "^4.5.0", "linkify-it": "^5.0.2", "mdurl": "^2.0.0", "punycode.js": "^2.3.1", "uc.micro": "^2.1.0" }, "bin": { "markdown-it": "bin/markdown-it.mjs" } }, "sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw=="], + + "markdown-it-task-lists": ["markdown-it-task-lists@2.1.1", "", {}, "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA=="], + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], "mdn-data": ["mdn-data@2.27.1", "", {}, "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ=="], + "mdurl": ["mdurl@2.1.0", "", {}, "sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg=="], + "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], "micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "3.0.3", "picomatch": "2.3.2" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], @@ -1018,6 +1101,8 @@ "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "0.1.4", "fast-levenshtein": "2.0.6", "levn": "0.4.1", "prelude-ls": "1.2.1", "type-check": "0.4.0", "word-wrap": "1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], + "orderedmap": ["orderedmap@2.1.1", "", {}, "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g=="], + "own-keys": ["own-keys@1.0.1", "", { "dependencies": { "get-intrinsic": "1.3.0", "object-keys": "1.1.1", "safe-push-apply": "1.0.0" } }, "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg=="], "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], @@ -1080,8 +1165,38 @@ "prop-types": ["prop-types@15.8.1", "", { "dependencies": { "loose-envify": "1.4.0", "object-assign": "4.1.1", "react-is": "16.13.1" } }, "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg=="], + "prosemirror-changeset": ["prosemirror-changeset@2.4.1", "", { "dependencies": { "prosemirror-transform": "^1.0.0" } }, "sha512-96WBLhOaYhJ+kPhLg3uW359Tz6I/MfcrQfL4EGv4SrcqKEMC1gmoGrXHecPE8eOwTVCJ4IwgfzM8fFad25wNfw=="], + + "prosemirror-commands": ["prosemirror-commands@1.7.2", "", { "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.10.2" } }, "sha512-q6Q6szxqdu9Xd6EcdKsqXghu5nQdZTpB4Q9yd04WRc7/jt763e/rT60Owh0L1GYY+T46o5rD+9lEN36dZS43tw=="], + + "prosemirror-dropcursor": ["prosemirror-dropcursor@1.8.3", "", { "dependencies": { "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.1.0", "prosemirror-view": "^1.1.0" } }, "sha512-FoYbsJR8gK+DGlqhNoE29Loa38eIZPzQRIb1VMaDNBoo4OLP6vVof/jR8qFY/6XvUd6Dhug8MDCHl2a/h8RTfQ=="], + + "prosemirror-gapcursor": ["prosemirror-gapcursor@1.4.1", "", { "dependencies": { "prosemirror-keymap": "^1.0.0", "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", "prosemirror-view": "^1.0.0" } }, "sha512-pMdYaEnjNMSwl11yjEGtgTmLkR08m/Vl+Jj443167p9eB3HVQKhYCc4gmHVDsLPODfZfjr/MmirsdyZziXbQKw=="], + + "prosemirror-history": ["prosemirror-history@1.5.0", "", { "dependencies": { "prosemirror-state": "^1.2.2", "prosemirror-transform": "^1.0.0", "prosemirror-view": "^1.31.0", "rope-sequence": "^1.3.0" } }, "sha512-zlzTiH01eKA55UAf1MEjtssJeHnGxO0j4K4Dpx+gnmX9n+SHNlDqI2oO1Kv1iPN5B1dm5fsljCfqKF9nFL6HRg=="], + + "prosemirror-inputrules": ["prosemirror-inputrules@1.5.1", "", { "dependencies": { "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.0.0" } }, "sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw=="], + + "prosemirror-keymap": ["prosemirror-keymap@1.2.3", "", { "dependencies": { "prosemirror-state": "^1.0.0", "w3c-keyname": "^2.2.0" } }, "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw=="], + + "prosemirror-markdown": ["prosemirror-markdown@1.13.6", "", { "dependencies": { "@types/markdown-it": "^14.0.0", "markdown-it": "^14.0.0", "prosemirror-model": "^1.25.0" } }, "sha512-dY6g2BXRjkHW2ldNRDKfTF0x0R4ifk5rgPaABd/UhvrymtsGVxTbHn01goEsHAvO9nN0O34cttlW1qg/XUcaIg=="], + + "prosemirror-model": ["prosemirror-model@1.25.11", "", { "dependencies": { "orderedmap": "^2.0.0" } }, "sha512-QWg9RhnpLlogAmp3p96uEFrE5txQpFynd4vhBAELkwgOCWQs/X0yCzB3/hrHqiPwf91RG5KyWq6553zs9JqIOQ=="], + + "prosemirror-schema-list": ["prosemirror-schema-list@1.5.1", "", { "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.7.3" } }, "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q=="], + + "prosemirror-state": ["prosemirror-state@1.4.4", "", { "dependencies": { "prosemirror-model": "^1.0.0", "prosemirror-transform": "^1.0.0", "prosemirror-view": "^1.27.0" } }, "sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw=="], + + "prosemirror-tables": ["prosemirror-tables@1.8.5", "", { "dependencies": { "prosemirror-keymap": "^1.2.3", "prosemirror-model": "^1.25.4", "prosemirror-state": "^1.4.4", "prosemirror-transform": "^1.10.5", "prosemirror-view": "^1.41.4" } }, "sha512-V/0cDCsHKHe/tfWkeCmthNUcEp1IVO3p6vwN8XtwE9PZQLAZJigbw3QoraAdfJPir4NKJtNvOB8oYGKRl+t0Dw=="], + + "prosemirror-transform": ["prosemirror-transform@1.12.0", "", { "dependencies": { "prosemirror-model": "^1.21.0" } }, "sha512-GxboyN4AMIsoHNtz5uf2r2Ru551i5hWeCMD6E2Ib4Eogqoub0NflniaBPVQ4MrGE5yZ8JV9tUHg9qcZTTrcN4w=="], + + "prosemirror-view": ["prosemirror-view@1.42.2", "", { "dependencies": { "prosemirror-model": "^1.25.8", "prosemirror-state": "^1.0.0", "prosemirror-transform": "^1.1.0" } }, "sha512-Pdg0l5kXm8aLDquFAnQFTCITg0q44sLqBlHlpsVLD9segdOao8TOfQdAhCrCXyVgPSRr6UDDROOIWA3bIrN9YQ=="], + "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], + "punycode.js": ["punycode.js@2.3.1", "", {}, "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA=="], + "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], "react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="], @@ -1110,6 +1225,8 @@ "rolldown": ["rolldown@1.1.5", "", { "dependencies": { "@oxc-project/types": "0.139.0", "@rolldown/pluginutils": "1.0.1" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.1.5", "@rolldown/binding-darwin-arm64": "1.1.5", "@rolldown/binding-darwin-x64": "1.1.5", "@rolldown/binding-freebsd-x64": "1.1.5", "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", "@rolldown/binding-linux-arm64-gnu": "1.1.5", "@rolldown/binding-linux-arm64-musl": "1.1.5", "@rolldown/binding-linux-ppc64-gnu": "1.1.5", "@rolldown/binding-linux-s390x-gnu": "1.1.5", "@rolldown/binding-linux-x64-gnu": "1.1.5", "@rolldown/binding-linux-x64-musl": "1.1.5", "@rolldown/binding-openharmony-arm64": "1.1.5", "@rolldown/binding-wasm32-wasi": "1.1.5", "@rolldown/binding-win32-arm64-msvc": "1.1.5", "@rolldown/binding-win32-x64-msvc": "1.1.5" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA=="], + "rope-sequence": ["rope-sequence@1.3.4", "", {}, "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ=="], + "rou3": ["rou3@0.7.12", "", {}, "sha512-iFE4hLDuloSWcD7mjdCDhx2bKcIsYbtOTpfH5MHHLSKMOUyjqQXTeZVa289uuwEGEKFoE/BAPbhaU4B774nceg=="], "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "1.2.3" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], @@ -1208,6 +1325,8 @@ "tinyrainbow": ["tinyrainbow@3.1.0", "", {}, "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw=="], + "tiptap-markdown": ["tiptap-markdown@0.9.0", "", { "dependencies": { "@types/markdown-it": "^13.0.7", "markdown-it": "^14.1.0", "markdown-it-task-lists": "^2.1.1", "prosemirror-markdown": "^1.11.1" }, "peerDependencies": { "@tiptap/core": "^3.0.1" } }, "sha512-dKLQ9iiuGNgrlGVjrNauF/UBzWu4LYOx5pkD0jNkmQt/GOwfCJsBuzZTsf1jZ204ANHOm572mZ9PYvGh1S7tpQ=="], + "tldts": ["tldts@7.4.8", "", { "dependencies": { "tldts-core": "7.4.8" }, "bin": { "tldts": "bin/cli.js" } }, "sha512-htwgN/8KRB3z3vnC0BOETVh2m499g5GmyTK9Wq5JBLX3FNz6tSBveAd+fQhzy9hkjif8vy2jwDMR1sGhLtZl2A=="], "tldts-core": ["tldts-core@7.4.8", "", {}, "sha512-c1P7u0EhACHj7lPy4MJm8iTFEU8+nB0LCtddH0fhP7noaVoXAqafMtOOeX+ulpuPBqnrRgRhw494RICT3mbhnw=="], @@ -1238,6 +1357,8 @@ "typescript-eslint": ["typescript-eslint@8.62.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.62.0", "@typescript-eslint/parser": "8.62.0", "@typescript-eslint/typescript-estree": "8.62.0", "@typescript-eslint/utils": "8.62.0" }, "peerDependencies": { "eslint": "9.39.4", "typescript": "5.9.3" } }, "sha512-8QxXi+ZACKX0kaqO4gY8kn0RSD9gFfaHDWwjqtEN48aWCBkX4MJaufWN+c3BzlrXLOxfywDL8CaoqUwcRq4j4Q=="], + "uc.micro": ["uc.micro@2.1.0", "", {}, "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A=="], + "unbox-primitive": ["unbox-primitive@1.1.0", "", { "dependencies": { "call-bound": "1.0.4", "has-bigints": "1.1.0", "has-symbols": "1.1.0", "which-boxed-primitive": "1.1.1" } }, "sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw=="], "undici": ["undici@7.28.0", "", {}, "sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA=="], @@ -1250,10 +1371,14 @@ "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "2.3.1" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], + "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], + "vite": ["vite@8.1.4", "", { "dependencies": { "lightningcss": "1.32.0", "picomatch": "4.0.5", "postcss": "8.5.23", "rolldown": "1.1.5", "tinyglobby": "0.2.17" }, "optionalDependencies": { "@types/node": "20.19.43", "fsevents": "2.3.3", "jiti": "2.7.0" }, "bin": { "vite": "bin/vite.js" } }, "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ=="], "vitest": ["vitest@4.1.10", "", { "dependencies": { "@vitest/expect": "4.1.10", "@vitest/mocker": "4.1.10", "@vitest/pretty-format": "4.1.10", "@vitest/runner": "4.1.10", "@vitest/snapshot": "4.1.10", "@vitest/spy": "4.1.10", "@vitest/utils": "4.1.10", "es-module-lexer": "2.3.1", "expect-type": "1.4.0", "magic-string": "0.30.21", "obug": "2.1.3", "pathe": "2.0.3", "picomatch": "4.0.4", "std-env": "4.2.0", "tinybench": "2.9.0", "tinyexec": "1.2.4", "tinyglobby": "0.2.17", "tinyrainbow": "3.1.0", "why-is-node-running": "2.3.0" }, "optionalDependencies": { "@types/node": "20.19.43", "jsdom": "29.1.1" }, "peerDependencies": { "vite": "8.1.4" }, "bin": { "vitest": "./vitest.mjs" } }, "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw=="], + "w3c-keyname": ["w3c-keyname@2.2.8", "", {}, "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ=="], + "w3c-xmlserializer": ["w3c-xmlserializer@5.0.0", "", { "dependencies": { "xml-name-validator": "5.0.0" } }, "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA=="], "webidl-conversions": ["webidl-conversions@8.0.1", "", {}, "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ=="], @@ -1330,6 +1455,8 @@ "is-bun-module/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], + "markdown-it/entities": ["entities@4.5.0", "", {}, "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw=="], + "micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="], "playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="], @@ -1338,6 +1465,8 @@ "prop-types/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="], + "prosemirror-markdown/@types/markdown-it": ["@types/markdown-it@14.2.0", "", { "dependencies": { "@types/linkify-it": "^5", "@types/mdurl": "^2" } }, "sha512-NoQ2yGlLWj4wpxMs+TYmRKk3thDrQ97agr7sFqfLsAlvoS8SNQuTrlObhFqG9iugdTtgOE9jpJ6FNM4ZGsa5xQ=="], + "sharp/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="], "vite/picomatch": ["picomatch@4.0.5", "", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="], @@ -1348,6 +1477,10 @@ "@unrs/resolver-binding-wasm32-wasi/@emnapi/core/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "2.8.1" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="], + "prosemirror-markdown/@types/markdown-it/@types/linkify-it": ["@types/linkify-it@5.0.0", "", {}, "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q=="], + + "prosemirror-markdown/@types/markdown-it/@types/mdurl": ["@types/mdurl@2.0.0", "", {}, "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="], + "@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="], } }