@tutti-os/ui-rich-text 0.0.18 → 0.0.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/at-panel/index.d.ts +1 -1
- package/dist/at-panel/model.d.ts +1 -1
- package/dist/{chunk-YFXORJLD.js → chunk-RHEJPXOW.js} +2 -2
- package/dist/{chunk-QOVFZUZN.js → chunk-W2IS5BLZ.js} +18 -6
- package/dist/chunk-W2IS5BLZ.js.map +1 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +1 -1
- package/dist/editor/index.d.ts +1 -1
- package/dist/editor/index.js +3 -4
- package/dist/editor/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/{mention-CgUcsO8r.d.ts → mention-DJq2OJ4K.d.ts} +5 -0
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/index.js +2 -2
- package/dist/types/index.d.ts +2 -2
- package/package.json +3 -3
- package/dist/chunk-QOVFZUZN.js.map +0 -1
- /package/dist/{chunk-YFXORJLD.js.map → chunk-RHEJPXOW.js.map} +0 -0
package/dist/at-panel/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { MentionPaletteProps, MentionRowItem } from './model.js';
|
|
|
2
2
|
export { DEFAULT_RICH_TEXT_AT_PANEL_PAGE_SIZE, MentionFileVisualKind, MentionFileVisualKindInput, MentionPaletteCategory, MentionPaletteEntry, MentionPaletteFilterId, MentionPaletteGroup, MentionPaletteGroupId, MentionPaletteState, MentionPaletteTheme, MentionRowAppFactoryItem, MentionRowAppItem, MentionRowFileItem, MentionRowIssueItem, MentionRowSessionItem, MentionRowStatusTag, MentionRowStatusTone, MentionRowStatusVariant, RICH_TEXT_AT_ALL_FILTER_ID, RichTextAtFilterId, RichTextAtFilterTab, RichTextAtGroupId, RichTextAtSearchGroup, RichTextTriggerProviderGroup, activityMentionStatusBadgeClassName, activityMentionStatusTone, buildDefaultRichTextTriggerProviderGroups, buildMentionPaletteState, buildRichTextAtFilterTabs, findRichTextTriggerProviderGroup, flattenMentionPaletteEntries, groupRichTextAtMatches, issueMentionStatusBadgeClassName, issueMentionStatusTone, mentionStatusBadgeClassName, normalizeAtPanelQuery, resolveMentionFileThumbnailUrl, resolveMentionFileVisualKind, richTextAtGroupExpandCount } from './model.js';
|
|
3
3
|
import { JSX } from 'react';
|
|
4
4
|
import '../types/index.js';
|
|
5
|
-
import '../mention-
|
|
5
|
+
import '../mention-DJq2OJ4K.js';
|
|
6
6
|
|
|
7
7
|
declare function MentionPalette<TItem>(props: MentionPaletteProps<TItem>): JSX.Element;
|
|
8
8
|
|
package/dist/at-panel/model.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { RichTextTriggerQueryMatch, RichTextTriggerInsertResult } from '../types/index.js';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import '../mention-
|
|
3
|
+
import '../mention-DJq2OJ4K.js';
|
|
4
4
|
|
|
5
5
|
type MentionPaletteFilterId = string;
|
|
6
6
|
type MentionPaletteGroupId = string;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createRichTextLinkMarkdown,
|
|
3
3
|
createRichTextMentionMarkdown
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-W2IS5BLZ.js";
|
|
5
5
|
|
|
6
6
|
// src/plugins/mention.ts
|
|
7
7
|
var richTextMentionTrigger = "@";
|
|
@@ -355,4 +355,4 @@ export {
|
|
|
355
355
|
createRichTextTriggerRegistry,
|
|
356
356
|
createRichTextMentionRegistry
|
|
357
357
|
};
|
|
358
|
-
//# sourceMappingURL=chunk-
|
|
358
|
+
//# sourceMappingURL=chunk-RHEJPXOW.js.map
|
|
@@ -88,7 +88,15 @@ function findMarkdownHrefEnd(value, cursor) {
|
|
|
88
88
|
var MARKDOWN_IMAGE_PATTERN = /!\[([^\]]*)\]\(([^)\s]+)\)/g;
|
|
89
89
|
var EXTERNAL_LINK_PREFIX = /^(?:[a-z]+:)?\/\//i;
|
|
90
90
|
var MENTION_LINK_PREFIX = /^mention:\/\//i;
|
|
91
|
-
var
|
|
91
|
+
var RESERVED_MENTION_SCOPE_KEYS = /* @__PURE__ */ new Set([
|
|
92
|
+
"appId",
|
|
93
|
+
"id",
|
|
94
|
+
"kind",
|
|
95
|
+
"link",
|
|
96
|
+
"provider",
|
|
97
|
+
"v",
|
|
98
|
+
"version"
|
|
99
|
+
]);
|
|
92
100
|
function normalizeLineEndings(value) {
|
|
93
101
|
return value.replace(/\r\n?/g, "\n");
|
|
94
102
|
}
|
|
@@ -167,6 +175,9 @@ function isRichTextMentionHref(href) {
|
|
|
167
175
|
function normalizeMentionLabel(value) {
|
|
168
176
|
return value.trim().replace(/^@+/, "").trim();
|
|
169
177
|
}
|
|
178
|
+
function isReservedMentionScopeKey(key) {
|
|
179
|
+
return RESERVED_MENTION_SCOPE_KEYS.has(key) || key.startsWith("meta.");
|
|
180
|
+
}
|
|
170
181
|
function createMentionQueryParams(mention) {
|
|
171
182
|
const params = new URLSearchParams();
|
|
172
183
|
for (const [key, value] of Object.entries(mention.scope ?? {}).sort(
|
|
@@ -174,7 +185,7 @@ function createMentionQueryParams(mention) {
|
|
|
174
185
|
)) {
|
|
175
186
|
const nextKey = key.trim();
|
|
176
187
|
const nextValue = value.trim();
|
|
177
|
-
if (!nextKey || !nextValue ||
|
|
188
|
+
if (!nextKey || !nextValue || isReservedMentionScopeKey(nextKey)) {
|
|
178
189
|
continue;
|
|
179
190
|
}
|
|
180
191
|
params.set(nextKey, nextValue);
|
|
@@ -211,15 +222,16 @@ function parseRichTextMentionHref(href, label) {
|
|
|
211
222
|
const providerId = decodeURIComponent(parsed.hostname).trim();
|
|
212
223
|
const encodedEntityId = parsed.pathname.replace(/^\/+/, "");
|
|
213
224
|
const entityId = decodeURIComponent(encodedEntityId).trim();
|
|
214
|
-
const
|
|
215
|
-
if (!providerId || !encodedEntityId || encodedEntityId.includes("/") || !entityId
|
|
225
|
+
const rawLabel = normalizeMentionLabel(label?.trim() ?? "");
|
|
226
|
+
if (!providerId || !encodedEntityId || encodedEntityId.includes("/") || !entityId) {
|
|
216
227
|
return null;
|
|
217
228
|
}
|
|
229
|
+
const nextLabel = rawLabel || entityId;
|
|
218
230
|
const scopeEntries = [];
|
|
219
231
|
for (const [key, value] of parsed.searchParams.entries()) {
|
|
220
232
|
const scopeKey = key.trim();
|
|
221
233
|
const scopeValue = value.trim();
|
|
222
|
-
if (!scopeKey ||
|
|
234
|
+
if (!scopeKey || isReservedMentionScopeKey(scopeKey)) {
|
|
223
235
|
return null;
|
|
224
236
|
}
|
|
225
237
|
if (scopeValue) {
|
|
@@ -531,4 +543,4 @@ export {
|
|
|
531
543
|
parseRichTextContentToDocument,
|
|
532
544
|
serializeRichTextDocumentToContent
|
|
533
545
|
};
|
|
534
|
-
//# sourceMappingURL=chunk-
|
|
546
|
+
//# sourceMappingURL=chunk-W2IS5BLZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/extensions/names.ts","../src/core/richTextMarkdownLinks.ts","../src/core/richTextDocument.ts"],"sourcesContent":["export const workspaceReferenceNodeName = \"workspaceReference\";\nexport const mentionReferenceNodeName = \"mentionReference\";\n","export interface RichTextMarkdownLinkMatch {\n href: string;\n index: number;\n label: string;\n source: string;\n to: number;\n}\n\nexport function* findRichTextMarkdownLinks(\n value: string\n): Generator<RichTextMarkdownLinkMatch> {\n let cursor = 0;\n\n while (cursor < value.length) {\n const labelStart = value.indexOf(\"[\", cursor);\n if (labelStart < 0) {\n return;\n }\n if (labelStart > 0 && value[labelStart - 1] === \"!\") {\n cursor = labelStart + 1;\n continue;\n }\n\n const labelEnd = findMarkdownLabelEnd(value, labelStart + 1);\n if (labelEnd < 0 || value[labelEnd + 1] !== \"(\") {\n cursor = labelStart + 1;\n continue;\n }\n\n const hrefStart = labelEnd + 2;\n const hrefEnd = findMarkdownHrefEnd(value, hrefStart);\n if (hrefEnd < 0) {\n cursor = labelStart + 1;\n continue;\n }\n\n yield {\n href: unescapeMarkdownLinkText(value.slice(hrefStart, hrefEnd)),\n index: labelStart,\n label: unescapeMarkdownLinkText(value.slice(labelStart + 1, labelEnd)),\n source: value.slice(labelStart, hrefEnd + 1),\n to: hrefEnd + 1\n };\n cursor = hrefEnd + 1;\n }\n}\n\nfunction unescapeMarkdownLinkText(value: string): string {\n return value.replace(/\\\\([\\\\[\\]()])/g, \"$1\");\n}\n\nfunction findMarkdownLabelEnd(value: string, cursor: number): number {\n let escaped = false;\n\n for (let index = cursor; index < value.length; index += 1) {\n const char = value[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (char === \"]\") {\n return index;\n }\n }\n\n return -1;\n}\n\nfunction findMarkdownHrefEnd(value: string, cursor: number): number {\n let escaped = false;\n let depth = 0;\n\n for (let index = cursor; index < value.length; index += 1) {\n const char = value[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (char === \"(\") {\n depth += 1;\n continue;\n }\n if (char !== \")\") {\n continue;\n }\n if (depth === 0) {\n return index;\n }\n depth -= 1;\n }\n\n return -1;\n}\n","import type { JSONContent } from \"@tiptap/core\";\nimport {\n mentionReferenceNodeName,\n workspaceReferenceNodeName\n} from \"../extensions/names.ts\";\nimport type {\n RichTextMentionAttrs,\n RichTextMentionIdentity\n} from \"../types/mention.ts\";\nimport {\n findRichTextMarkdownLinks,\n type RichTextMarkdownLinkMatch\n} from \"./richTextMarkdownLinks.ts\";\n\nexport type RichTextLinkRef = {\n name: string;\n path: string;\n href: string;\n kind: \"file\" | \"folder\";\n};\n\nexport type RichTextLinkInput = {\n name?: string | null;\n path: string;\n kind?: \"file\" | \"folder\";\n};\n\nexport type RichTextMentionRef = RichTextMentionAttrs;\nexport type RichTextDocument = JSONContent;\n\nconst MARKDOWN_IMAGE_PATTERN = /!\\[([^\\]]*)\\]\\(([^)\\s]+)\\)/g;\nconst EXTERNAL_LINK_PREFIX = /^(?:[a-z]+:)?\\/\\//i;\nconst MENTION_LINK_PREFIX = /^mention:\\/\\//i;\nconst RESERVED_MENTION_SCOPE_KEYS = new Set([\n \"appId\",\n \"id\",\n \"kind\",\n \"link\",\n \"provider\",\n \"v\",\n \"version\"\n]);\n\ntype LegacyJSONContentNode = {\n type?: string;\n text?: string;\n attrs?: Record<string, unknown>;\n content?: LegacyJSONContentNode[];\n};\n\nfunction normalizeLineEndings(value: string): string {\n return value.replace(/\\r\\n?/g, \"\\n\");\n}\n\nfunction normalizeContentString(value?: string | null): string {\n const trimmed = normalizeLineEndings(value ?? \"\").trim();\n if (!trimmed) {\n return \"\";\n }\n const markdown = convertLegacyDocumentString(trimmed);\n return markdown || trimmed;\n}\n\nexport function normalizeRichTextContent(value?: string | null): string {\n return normalizeContentString(value);\n}\n\nfunction convertLegacyDocumentString(value: string): string {\n try {\n const parsed = JSON.parse(value) as LegacyJSONContentNode;\n if (parsed?.type !== \"doc\" || !Array.isArray(parsed.content)) {\n return \"\";\n }\n return renderLegacyNodesToMarkdown(parsed.content).trim();\n } catch {\n return \"\";\n }\n}\n\nfunction renderLegacyNodesToMarkdown(nodes: LegacyJSONContentNode[]): string {\n return nodes\n .map((node) => renderLegacyNodeToMarkdown(node))\n .filter((part) => part.length > 0)\n .join(\"\\n\\n\");\n}\n\nfunction renderLegacyNodeToMarkdown(\n node: LegacyJSONContentNode | null | undefined\n): string {\n if (!node) {\n return \"\";\n }\n if (node.type === \"text\") {\n return node.text ?? \"\";\n }\n if (node.type === \"workspaceFileLink\") {\n const attrs = node.attrs ?? {};\n const kind = attrs.kind === \"folder\" ? \"folder\" : \"file\";\n const hrefValue =\n (typeof attrs.href === \"string\" ? attrs.href : undefined) ||\n (typeof attrs.path === \"string\" ? attrs.path : undefined) ||\n \"\";\n const href = normalizeRichTextLinkHref(hrefValue, kind);\n const label =\n (typeof attrs.name === \"string\" ? attrs.name : undefined)?.trim() ||\n href.split(\"/\").filter(Boolean).at(-1) ||\n href;\n return href && label ? `[${label}](${href})` : label;\n }\n if (Array.isArray(node.content)) {\n const inline = node.content\n .map((child) => renderLegacyNodeToMarkdown(child))\n .filter((part) => part.length > 0)\n .join(\"\")\n .trim();\n if (!inline) {\n return \"\";\n }\n if (node.type === \"paragraph\") {\n return inline;\n }\n return inline;\n }\n return \"\";\n}\n\nfunction normalizeWorkspacePath(\n pathOrHref: string,\n kind: \"file\" | \"folder\"\n): string {\n const trimmed = pathOrHref.trim();\n if (!trimmed) {\n return \"\";\n }\n if (kind === \"folder\" && !trimmed.endsWith(\"/\")) {\n return `${trimmed}/`;\n }\n return trimmed;\n}\n\nfunction isWorkspaceReferenceHref(href: string): boolean {\n const trimmed = href.trim();\n if (\n !trimmed ||\n MENTION_LINK_PREFIX.test(trimmed) ||\n EXTERNAL_LINK_PREFIX.test(trimmed)\n ) {\n return false;\n }\n return true;\n}\n\nexport function isRichTextMentionHref(href: string): boolean {\n return MENTION_LINK_PREFIX.test(href.trim());\n}\n\nfunction normalizeMentionLabel(value: string): string {\n return value.trim().replace(/^@+/, \"\").trim();\n}\n\nfunction isReservedMentionScopeKey(key: string): boolean {\n return RESERVED_MENTION_SCOPE_KEYS.has(key) || key.startsWith(\"meta.\");\n}\n\nfunction createMentionQueryParams(\n mention: RichTextMentionIdentity\n): URLSearchParams {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(mention.scope ?? {}).sort(\n ([left], [right]) => left.localeCompare(right)\n )) {\n const nextKey = key.trim();\n const nextValue = value.trim();\n if (!nextKey || !nextValue || isReservedMentionScopeKey(nextKey)) {\n continue;\n }\n params.set(nextKey, nextValue);\n }\n return params;\n}\n\nexport function createRichTextMentionHref(\n mention: RichTextMentionIdentity\n): string {\n const providerId = mention.providerId.trim();\n const entityId = mention.entityId.trim();\n const label = normalizeMentionLabel(mention.label);\n if (!providerId || !entityId || !label) {\n return \"\";\n }\n\n const params = createMentionQueryParams(mention);\n const queryString = params.toString();\n const pathname = `${encodeURIComponent(providerId)}/${encodeURIComponent(entityId)}`;\n return queryString\n ? `mention://${pathname}?${queryString}`\n : `mention://${pathname}`;\n}\n\nexport function createRichTextMentionMarkdown(\n mention: RichTextMentionIdentity\n): string {\n const label = normalizeMentionLabel(mention.label);\n const href = createRichTextMentionHref(mention);\n if (!label || !href) {\n return \"\";\n }\n return `[${escapeMarkdownLinkLabel(`@${label}`)}](${escapeMarkdownLinkHref(href)})`;\n}\n\nexport function parseRichTextMentionHref(\n href: string,\n label?: string | null\n): RichTextMentionRef | null {\n const trimmedHref = href.trim();\n if (!isRichTextMentionHref(trimmedHref)) {\n return null;\n }\n\n try {\n const parsed = new URL(trimmedHref);\n const providerId = decodeURIComponent(parsed.hostname).trim();\n const encodedEntityId = parsed.pathname.replace(/^\\/+/, \"\");\n const entityId = decodeURIComponent(encodedEntityId).trim();\n const rawLabel = normalizeMentionLabel(label?.trim() ?? \"\");\n\n if (\n !providerId ||\n !encodedEntityId ||\n encodedEntityId.includes(\"/\") ||\n !entityId\n ) {\n return null;\n }\n\n const nextLabel = rawLabel || entityId;\n\n const scopeEntries: Array<readonly [string, string]> = [];\n for (const [key, value] of parsed.searchParams.entries()) {\n const scopeKey = key.trim();\n const scopeValue = value.trim();\n if (!scopeKey || isReservedMentionScopeKey(scopeKey)) {\n return null;\n }\n if (scopeValue) {\n scopeEntries.push([scopeKey, scopeValue]);\n }\n }\n\n const mention: RichTextMentionRef = {\n trigger: \"@\",\n providerId,\n entityId,\n label: nextLabel\n };\n if (scopeEntries.length > 0) {\n mention.scope = Object.fromEntries(scopeEntries);\n }\n return mention;\n } catch {\n return null;\n }\n}\n\nexport function normalizeRichTextLinkHref(\n pathOrHref: string,\n kind: \"file\" | \"folder\" = \"file\"\n): string {\n return normalizeWorkspacePath(pathOrHref, kind);\n}\n\nexport function createRichTextLinkMarkdown(input: RichTextLinkInput): string {\n const kind = input.kind === \"folder\" ? \"folder\" : \"file\";\n const href = normalizeRichTextLinkHref(input.path, kind);\n const displayName =\n input.name?.trim() ||\n href.split(\"/\").filter(Boolean).at(-1) ||\n href ||\n input.path.trim();\n if (!href || !displayName) {\n return \"\";\n }\n return `[${escapeMarkdownLinkLabel(displayName)}](${escapeMarkdownLinkHref(href)})`;\n}\n\nexport function appendRichTextLinksToContent(\n value: string | null | undefined,\n refs: readonly RichTextLinkInput[]\n): string {\n const content = normalizeContentString(value);\n const existing = new Set(\n extractRichTextLinksFromContent(content).map((ref) => ref.path)\n );\n const rendered = refs\n .map((ref) => {\n const kind = ref.kind === \"folder\" ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(ref.path, kind);\n if (!path || existing.has(path)) {\n return \"\";\n }\n existing.add(path);\n return createRichTextLinkMarkdown({ ...ref, path, kind });\n })\n .filter(Boolean);\n\n if (rendered.length === 0) {\n return content;\n }\n return content ? `${content} ${rendered.join(\" \")}` : rendered.join(\" \");\n}\n\nexport function extractRichTextLinksFromContent(\n value: string | null | undefined\n): RichTextLinkRef[] {\n const content = normalizeContentString(value);\n const refs = new Map<string, RichTextLinkRef>();\n for (const match of findRichTextMarkdownLinks(content)) {\n const name = match.label.trim();\n const href = match.href.trim();\n if (!name || !isWorkspaceReferenceHref(href)) {\n continue;\n }\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(href, kind);\n if (!path || refs.has(path)) {\n continue;\n }\n refs.set(path, {\n name,\n path,\n href: path,\n kind\n });\n }\n return [...refs.values()];\n}\n\nexport function extractRichTextMentionsFromContent(\n value: string | null | undefined\n): RichTextMentionRef[] {\n const content = normalizeContentString(value);\n const refs = new Map<string, RichTextMentionRef>();\n\n for (const match of findRichTextMarkdownLinks(content)) {\n const label = match.label.trim();\n const href = match.href.trim();\n const mention = parseRichTextMentionHref(href, label);\n if (!mention) {\n continue;\n }\n const mentionKey = [\n mention.providerId,\n mention.entityId,\n JSON.stringify(\n Object.fromEntries(\n Object.entries(mention.scope ?? {}).sort(([left], [right]) =>\n left.localeCompare(right)\n )\n )\n )\n ].join(\":\");\n if (refs.has(mentionKey)) {\n continue;\n }\n refs.set(mentionKey, mention);\n }\n\n return [...refs.values()];\n}\n\nexport function removeRichTextMentionFromContent(\n content: string,\n mention: Pick<RichTextMentionAttrs, \"providerId\" | \"entityId\">\n): string {\n const providerId = mention.providerId.trim();\n const entityId = mention.entityId.trim();\n if (!providerId || !entityId) {\n return normalizeContentString(content);\n }\n\n const normalized = normalizeContentString(content);\n const next = replaceRichTextMarkdownLinks(normalized, (match) => {\n const parsedMention = parseRichTextMentionHref(match.href, match.label);\n if (!parsedMention) {\n return match.source;\n }\n return parsedMention.providerId === providerId &&\n parsedMention.entityId === entityId\n ? \"\"\n : match.source;\n });\n\n return next\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function removeRichTextLinkFromContent(\n content: string,\n path: string\n): string {\n const targetPath = path.trim();\n if (!targetPath) {\n return normalizeContentString(content);\n }\n const normalized = normalizeContentString(content);\n const next = replaceRichTextMarkdownLinks(normalized, (match) => {\n const href = match.href.trim();\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n const refPath = normalizeRichTextLinkHref(href, kind);\n return refPath === targetPath ? \"\" : match.source;\n });\n return next\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n[ \\t]+/g, \"\\n\")\n .replace(/[ \\t]{2,}/g, \" \")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function extractPlainTextFromContent(value?: string | null): string {\n const content = normalizeContentString(value);\n if (!content) {\n return \"\";\n }\n return replaceRichTextMarkdownLinks(\n content.replace(MARKDOWN_IMAGE_PATTERN, \" $1 \"),\n (match) => ` ${match.label} `\n )\n .replace(/^[\\s>*#+-]+/gm, \" \")\n .replace(/`([^`]+)`/g, \" $1 \")\n .replace(/[*_~]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function extractPlainTextWithoutFilesFromContent(\n value?: string | null\n): string {\n const content = normalizeContentString(value);\n if (!content) {\n return \"\";\n }\n return replaceRichTextMarkdownLinks(\n content.replace(MARKDOWN_IMAGE_PATTERN, \" \"),\n () => \" \"\n )\n .replace(/^[\\s>*#+-]+/gm, \" \")\n .replace(/`([^`]+)`/g, \" $1 \")\n .replace(/[*_~]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function parseRichTextContentToDocument(\n value?: string | null\n): RichTextDocument {\n const content = normalizeContentString(value);\n if (!content) {\n return {\n type: \"doc\",\n content: [{ type: \"paragraph\" }]\n };\n }\n\n const paragraphs = content\n .split(/\\n{2,}/)\n .map((paragraph) => createRichTextParagraphNode(paragraph))\n .filter((paragraph) => Array.isArray(paragraph.content));\n\n return {\n type: \"doc\",\n content: paragraphs.length > 0 ? paragraphs : [{ type: \"paragraph\" }]\n };\n}\n\nexport function serializeRichTextDocumentToContent(\n document: RichTextDocument\n): string {\n const paragraphs = (document.content ?? [])\n .map((node) => serializeRichTextBlockNode(node))\n .filter((value) => value.length > 0);\n\n return paragraphs.join(\"\\n\\n\").trim();\n}\n\nfunction createRichTextParagraphNode(paragraph: string): JSONContent {\n return {\n type: \"paragraph\",\n content: createRichTextInlineNodes(paragraph)\n };\n}\n\nfunction createRichTextInlineNodes(text: string): JSONContent[] {\n const content: JSONContent[] = [];\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(text)) {\n const { index, source } = match;\n if (index > cursor) {\n appendPlainTextNodes(content, text.slice(cursor, index));\n }\n\n const label = match.label.trim();\n const href = match.href.trim();\n const mention = parseRichTextMentionHref(href, label);\n if (mention) {\n content.push({\n type: mentionReferenceNodeName,\n attrs: mention\n });\n } else if (label && isWorkspaceReferenceHref(href)) {\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n content.push({\n type: workspaceReferenceNodeName,\n attrs: {\n kind,\n label,\n path: normalizeRichTextLinkHref(href, kind)\n }\n });\n } else {\n appendPlainTextNodes(content, source);\n }\n\n cursor = match.to;\n }\n\n if (cursor < text.length) {\n appendPlainTextNodes(content, text.slice(cursor));\n }\n\n return content;\n}\n\nfunction replaceRichTextMarkdownLinks(\n value: string,\n replace: (match: RichTextMarkdownLinkMatch) => string\n): string {\n let nextValue = \"\";\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(value)) {\n nextValue += value.slice(cursor, match.index);\n nextValue += replace(match);\n cursor = match.to;\n }\n\n return `${nextValue}${value.slice(cursor)}`;\n}\n\nfunction escapeMarkdownLinkLabel(value: string): string {\n return value.replace(/[\\\\[\\]]/g, \"\\\\$&\");\n}\n\nfunction escapeMarkdownLinkHref(value: string): string {\n return value.replace(/[\\\\()]/g, \"\\\\$&\");\n}\n\nfunction appendPlainTextNodes(content: JSONContent[], text: string): void {\n if (!text) {\n return;\n }\n\n const lines = text.split(\"\\n\");\n lines.forEach((line, index) => {\n if (line.length > 0) {\n content.push({\n type: \"text\",\n text: line\n });\n }\n if (index < lines.length - 1) {\n content.push({ type: \"hardBreak\" });\n }\n });\n}\n\nfunction serializeRichTextBlockNode(node: JSONContent): string {\n if (node.type === \"paragraph\") {\n return serializeRichTextInlineNodes(node.content ?? []);\n }\n return serializeRichTextInlineNodes(node.content ?? []);\n}\n\nfunction serializeRichTextInlineNodes(nodes: readonly JSONContent[]): string {\n return nodes\n .map((node) => {\n if (node.type === \"text\") {\n return typeof node.text === \"string\" ? node.text : \"\";\n }\n if (node.type === \"hardBreak\") {\n return \"\\n\";\n }\n if (node.type === workspaceReferenceNodeName) {\n const attrs = node.attrs ?? {};\n return createRichTextLinkMarkdown({\n kind: attrs.kind === \"folder\" ? \"folder\" : \"file\",\n name: typeof attrs.label === \"string\" ? attrs.label : \"\",\n path: typeof attrs.path === \"string\" ? attrs.path : \"\"\n });\n }\n if (node.type === mentionReferenceNodeName) {\n const attrs = node.attrs ?? {};\n const label = typeof attrs.label === \"string\" ? attrs.label.trim() : \"\";\n const providerId =\n typeof attrs.providerId === \"string\" ? attrs.providerId.trim() : \"\";\n const entityId =\n typeof attrs.entityId === \"string\" ? attrs.entityId.trim() : \"\";\n if (!label || !providerId || !entityId) {\n return \"\";\n }\n const scope =\n attrs.scope && typeof attrs.scope === \"object\"\n ? (attrs.scope as Record<string, string>)\n : undefined;\n return createRichTextMentionMarkdown({\n entityId,\n label,\n providerId,\n scope\n });\n }\n\n if (Array.isArray(node.content)) {\n return serializeRichTextInlineNodes(node.content);\n }\n\n return \"\";\n })\n .join(\"\");\n}\n"],"mappings":"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","names":[]}
|
package/dist/core/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { JSONContent } from '@tiptap/core';
|
|
2
|
-
import { a as RichTextMentionIdentity, R as RichTextMentionAttrs } from '../mention-
|
|
2
|
+
import { a as RichTextMentionIdentity, R as RichTextMentionAttrs } from '../mention-DJq2OJ4K.js';
|
|
3
3
|
|
|
4
4
|
type RichTextLinkRef = {
|
|
5
5
|
name: string;
|
package/dist/core/index.js
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
removeRichTextLinkFromContent,
|
|
17
17
|
removeRichTextMentionFromContent,
|
|
18
18
|
serializeRichTextDocumentToContent
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-W2IS5BLZ.js";
|
|
20
20
|
export {
|
|
21
21
|
appendRichTextLinksToContent,
|
|
22
22
|
createRichTextLinkMarkdown,
|
package/dist/editor/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ReactNode, JSX } from 'react';
|
|
2
2
|
import { RichTextTriggerProvider, RichTextTrigger, RichTextTriggerConfig, RichTextTriggerBoundary, RichTextTriggerRegistry, RichTextTriggerQueryInput, RichTextTriggerQueryMatch } from '../types/index.js';
|
|
3
3
|
import { a as RichTextI18nRuntime } from '../richTextI18n-CUeqHuEQ.js';
|
|
4
|
-
import { R as RichTextMentionAttrs, l as RichTextResolvedMention, m as RichTextResolvedMentionView } from '../mention-
|
|
4
|
+
import { R as RichTextMentionAttrs, l as RichTextResolvedMention, m as RichTextResolvedMentionView } from '../mention-DJq2OJ4K.js';
|
|
5
5
|
import '@tutti-os/ui-i18n-runtime';
|
|
6
6
|
|
|
7
7
|
interface RichTextTriggerTextOverrides {
|
package/dist/editor/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
getRichTextMentionDisplayText,
|
|
8
8
|
renderRichTextTriggerInsertResult,
|
|
9
9
|
resolveRichTextMentionView
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-RHEJPXOW.js";
|
|
11
11
|
import {
|
|
12
12
|
findRichTextMarkdownLinks,
|
|
13
13
|
isRichTextMentionHref,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
parseRichTextMentionHref,
|
|
19
19
|
serializeRichTextDocumentToContent,
|
|
20
20
|
workspaceReferenceNodeName
|
|
21
|
-
} from "../chunk-
|
|
21
|
+
} from "../chunk-W2IS5BLZ.js";
|
|
22
22
|
|
|
23
23
|
// src/editor/RichTextTriggerEditor.tsx
|
|
24
24
|
import {
|
|
@@ -1079,7 +1079,6 @@ import { cn as cn3 } from "@tutti-os/ui-system/utils";
|
|
|
1079
1079
|
|
|
1080
1080
|
// src/editor/richTextTextareaDecorationModel.ts
|
|
1081
1081
|
var EXTERNAL_LINK_PREFIX = /^(?:[a-z]+:)?\/\//i;
|
|
1082
|
-
var MENTION_LINK_PREFIX = /^mention:\/\//i;
|
|
1083
1082
|
var TEXTAREA_PRESENTATION_STYLE_PROPERTIES = [
|
|
1084
1083
|
{ styleName: "paddingTop", cssName: "padding-top" },
|
|
1085
1084
|
{ styleName: "paddingRight", cssName: "padding-right" },
|
|
@@ -1108,7 +1107,7 @@ function isDecoratableMarkdownHref(href) {
|
|
|
1108
1107
|
if (!trimmedHref) {
|
|
1109
1108
|
return false;
|
|
1110
1109
|
}
|
|
1111
|
-
if (EXTERNAL_LINK_PREFIX.test(trimmedHref) ||
|
|
1110
|
+
if (EXTERNAL_LINK_PREFIX.test(trimmedHref) || isRichTextMentionHref(trimmedHref)) {
|
|
1112
1111
|
return false;
|
|
1113
1112
|
}
|
|
1114
1113
|
return true;
|
package/dist/editor/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/editor/RichTextTriggerEditor.tsx","../../src/editor/richTextTriggerQuery.ts","../../src/editor/richTextIme.ts","../../src/editor/richTextTriggerText.ts","../../src/editor/RichTextTriggerMenuItem.tsx","../../src/extensions/mentionReference.ts","../../src/extensions/MentionReferenceNodeView.tsx","../../src/extensions/workspaceReference.ts","../../src/extensions/WorkspaceReferenceNodeView.tsx","../../src/extensions/workspaceReferencePresentation.ts","../../src/editor/RichTextTriggerTextarea.tsx","../../src/editor/richTextTextareaDecorationModel.ts","../../src/editor/richTextTextareaDecorations.tsx","../../src/editor/richTextTextareaCaret.ts","../../src/editor/RichTextMentionReadonly.tsx","../../src/editor/RichTextReadonlyContent.tsx","../../src/editor/richTextReadonlyContentModel.ts"],"sourcesContent":["import {\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactNode,\n type JSX\n} from \"react\";\nimport Document from \"@tiptap/extension-document\";\nimport HardBreak from \"@tiptap/extension-hard-break\";\nimport Paragraph from \"@tiptap/extension-paragraph\";\nimport Text from \"@tiptap/extension-text\";\nimport type { Editor as TiptapEditor } from \"@tiptap/react\";\nimport { EditorContent, useEditor } from \"@tiptap/react\";\nimport { ViewportMenuSurface } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport { createRichTextMentionAttrs } from \"../plugins/index.ts\";\nimport { createRichTextTriggerRegistry } from \"../plugins/triggerRegistry.ts\";\nimport type {\n RichTextMentionAttrs,\n RichTextMentionPresentation\n} from \"../types/mention.ts\";\nimport type {\n RichTextTriggerInsertResult,\n RichTextTriggerProvider,\n RichTextTriggerQueryMatch,\n RichTextTrigger,\n RichTextTriggerConfig\n} from \"../types/trigger.ts\";\nimport {\n normalizeRichTextContent,\n normalizeRichTextLinkHref,\n parseRichTextContentToDocument,\n serializeRichTextDocumentToContent\n} from \"../core/richTextDocument.ts\";\nimport {\n findRichTextTriggerQuery,\n queryRichTextTriggerMatches\n} from \"./richTextTriggerQuery.ts\";\nimport { isRichTextImeComposing } from \"./richTextIme.ts\";\nimport {\n resolveRichTextTriggerText,\n type RichTextTriggerTextOverrides\n} from \"./richTextTriggerText.ts\";\nimport { RichTextTriggerMenuItem } from \"./RichTextTriggerMenuItem.tsx\";\nimport type { RichTextI18nRuntime } from \"../i18n/richTextI18n.ts\";\nimport { MentionReference } from \"../extensions/mentionReference.ts\";\nimport { WorkspaceReference } from \"../extensions/workspaceReference.ts\";\nimport {\n mentionReferenceNodeName,\n workspaceReferenceNodeName\n} from \"../extensions/names.ts\";\n\nexport interface RichTextTriggerEditorProps {\n value: string;\n onChange: (value: string) => void;\n triggerProviders?: readonly RichTextTriggerProvider[];\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n textareaClassName?: string;\n placeholderClassName?: string;\n minQueryLength?: number;\n maxResults?: number;\n removeDecorationAriaLabel?: string;\n i18n?: RichTextI18nRuntime;\n textOverrides?: RichTextTriggerTextOverrides;\n overlay?: ReactNode;\n focusSignal?: unknown;\n menuZIndex?: string | number;\n}\n\ntype RichTextEditorTriggerQueryState = {\n from: number;\n keyword: string;\n trigger: RichTextTrigger;\n to: number;\n};\n\nconst RICH_TEXT_MENTION_PRESENTATION_KEYS = [\n \"agentProviderId\",\n \"agentIconUrl\",\n \"iconUrl\",\n \"thumbnailUrl\",\n \"subtitle\",\n \"description\",\n \"participant\",\n \"status\",\n \"statusDataStatus\",\n \"statusLabel\",\n \"statusPulse\",\n \"userAvatarPlaceholderUrl\"\n] as const satisfies readonly (keyof RichTextMentionPresentation)[];\n\nexport function RichTextTriggerEditor({\n value,\n onChange,\n triggerProviders = [],\n placeholder,\n disabled = false,\n className,\n textareaClassName,\n placeholderClassName,\n minQueryLength = 0,\n maxResults = 8,\n removeDecorationAriaLabel,\n i18n,\n textOverrides,\n overlay,\n focusSignal,\n menuZIndex\n}: RichTextTriggerEditorProps): JSX.Element {\n const menuOffset = 6;\n const normalizedValue = normalizeRichTextContent(value);\n const text = resolveRichTextTriggerText(\n textOverrides,\n removeDecorationAriaLabel,\n i18n\n );\n const latestOnChangeRef = useRef(onChange);\n const lastSerializedValueRef = useRef(normalizedValue);\n const lastFocusSignalRef = useRef(focusSignal);\n const mentionHydrationRequestRef = useRef(0);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const registry = useMemo(\n () => createRichTextTriggerRegistry(triggerProviders),\n [triggerProviders]\n );\n const activeTriggerConfigs = useMemo(\n () => registry.listTriggerConfigs(),\n [registry]\n );\n const [isFocused, setIsFocused] = useState(false);\n const [query, setQuery] = useState<RichTextEditorTriggerQueryState | null>(\n null\n );\n const [matches, setMatches] = useState<readonly RichTextTriggerQueryMatch[]>(\n []\n );\n const [activeIndex, setActiveIndex] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [menuPoint, setMenuPoint] = useState<{ x: number; y: number } | null>(\n null\n );\n\n latestOnChangeRef.current = onChange;\n\n const editor = useEditor({\n immediatelyRender: false,\n editable: !disabled,\n extensions: [\n Document,\n Paragraph,\n Text,\n HardBreak,\n WorkspaceReference.configure({\n removeActionAriaLabel: text.removeReferenceActionLabel\n }),\n MentionReference\n ],\n content: parseRichTextContentToDocument(normalizedValue),\n editorProps: {\n attributes: {\n class: cn(\n \"w-full whitespace-pre-wrap break-words outline-none\",\n textareaClassName\n )\n }\n },\n onBlur() {\n window.setTimeout(() => {\n setIsFocused(false);\n setQuery(null);\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n }, 100);\n },\n onFocus() {\n setIsFocused(true);\n },\n onUpdate({ editor }) {\n const serialized = serializeRichTextDocumentToContent(editor.getJSON());\n lastSerializedValueRef.current = serialized;\n latestOnChangeRef.current(serialized);\n }\n });\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n if (lastSerializedValueRef.current === normalizedValue) {\n return;\n }\n\n const currentSerialized = serializeRichTextDocumentToContent(\n editor.getJSON()\n );\n if (currentSerialized === normalizedValue) {\n lastSerializedValueRef.current = normalizedValue;\n return;\n }\n\n editor.commands.setContent(\n parseRichTextContentToDocument(normalizedValue),\n {\n emitUpdate: false\n }\n );\n lastSerializedValueRef.current = normalizedValue;\n }, [editor, normalizedValue]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const requestId = mentionHydrationRequestRef.current + 1;\n mentionHydrationRequestRef.current = requestId;\n const mentions = collectHydratableMentionNodes(editor);\n if (mentions.length === 0) {\n return;\n }\n\n for (const mention of mentions) {\n const provider = registry.getProvider(mention.attrs.providerId);\n if (!provider?.resolveMention) {\n continue;\n }\n\n void Promise.resolve(provider.resolveMention(mention.attrs))\n .then((resolved) => {\n if (\n !resolved ||\n mentionHydrationRequestRef.current !== requestId ||\n editor.isDestroyed\n ) {\n return;\n }\n\n applyResolvedMentionAttrs(editor, mention.pos, mention.attrs, {\n label: resolved.label,\n presentation: resolved.presentation\n });\n })\n .catch(() => {\n // Resolver failures keep the fallback label-only mention.\n });\n }\n }, [editor, registry, normalizedValue]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n if (Object.is(lastFocusSignalRef.current, focusSignal)) {\n return;\n }\n\n lastFocusSignalRef.current = focusSignal;\n editor.commands.focus(\"end\");\n }, [editor, focusSignal]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n editor.setEditable(!disabled);\n editor.view.dispatch(\n editor.state.tr.setMeta(\"richTextEditable\", !disabled)\n );\n }, [disabled, editor]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const updateQueryState = () => {\n const nextQuery = findEditorAtQuery(editor, activeTriggerConfigs);\n setQuery(nextQuery);\n };\n\n const updateFocus = () => {\n const nextFocused = editor.isFocused;\n setIsFocused(nextFocused);\n updateQueryState();\n };\n\n updateQueryState();\n editor.on(\"selectionUpdate\", updateQueryState);\n editor.on(\"transaction\", updateQueryState);\n editor.on(\"focus\", updateFocus);\n editor.on(\"blur\", updateFocus);\n return () => {\n editor.off(\"selectionUpdate\", updateQueryState);\n editor.off(\"transaction\", updateQueryState);\n editor.off(\"focus\", updateFocus);\n editor.off(\"blur\", updateFocus);\n };\n }, [activeTriggerConfigs, editor]);\n\n useEffect(() => {\n if (!editor || !query || activeTriggerConfigs.length === 0) {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n return;\n }\n\n if (query.keyword.length < minQueryLength) {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n return;\n }\n\n const abortController = new AbortController();\n setIsLoading(true);\n\n void queryRichTextTriggerMatches(registry, {\n abortSignal: abortController.signal,\n keyword: query.keyword,\n maxResults,\n trigger: query.trigger,\n context: {\n blockText: editor.state.selection.$from.parent.textBetween(\n 0,\n editor.state.selection.$from.parent.content.size,\n \"\\n\",\n \"\\uFFFC\"\n ),\n documentText: serializeRichTextDocumentToContent(editor.getJSON())\n }\n })\n .then((nextMatches) => {\n if (abortController.signal.aborted) {\n return;\n }\n setMatches(nextMatches);\n setActiveIndex((current) =>\n nextMatches.length === 0\n ? 0\n : Math.max(0, Math.min(current, nextMatches.length - 1))\n );\n })\n .finally(() => {\n if (!abortController.signal.aborted) {\n setIsLoading(false);\n }\n });\n\n return () => {\n abortController.abort();\n };\n }, [\n editor,\n maxResults,\n minQueryLength,\n activeTriggerConfigs.length,\n query,\n registry\n ]);\n\n useLayoutEffect(() => {\n if (!editor || !query) {\n setMenuPoint(null);\n return;\n }\n\n const updateMenuPoint = () => {\n const coords = editor.view.coordsAtPos(editor.state.selection.from);\n const nextMenuPoint = {\n x: coords.left,\n y: coords.bottom + menuOffset\n };\n setMenuPoint(nextMenuPoint);\n };\n\n updateMenuPoint();\n window.addEventListener(\"resize\", updateMenuPoint);\n window.addEventListener(\"scroll\", updateMenuPoint, {\n capture: true,\n passive: true\n });\n return () => {\n window.removeEventListener(\"resize\", updateMenuPoint);\n window.removeEventListener(\"scroll\", updateMenuPoint, true);\n };\n }, [editor, menuOffset, query]);\n\n const canQueryTrigger =\n !!query &&\n activeTriggerConfigs.length > 0 &&\n query.keyword.length >= minQueryLength;\n const isMenuOpen = canQueryTrigger && (isFocused || !!menuPoint);\n const isEmpty =\n !editor ||\n serializeRichTextDocumentToContent(editor.getJSON()).trim().length === 0;\n\n const applyMatch = (match: RichTextTriggerQueryMatch) => {\n if (!editor || !query) {\n return;\n }\n\n const content = renderInsertResultAsEditorContent(\n match.providerId,\n match.insertResult\n );\n if (!content) {\n return;\n }\n\n editor\n .chain()\n .focus()\n .insertContentAt({ from: query.from, to: query.to }, content)\n .run();\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (isRichTextImeComposing(event)) {\n return;\n }\n\n if (!isMenuOpen) {\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n return;\n }\n\n if (matches.length === 0) {\n return;\n }\n\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n setActiveIndex((current) => (current + 1) % matches.length);\n return;\n }\n\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveIndex(\n (current) => (current - 1 + matches.length) % matches.length\n );\n return;\n }\n\n if (event.key === \"Enter\" || event.key === \"Tab\") {\n const match = matches[activeIndex];\n if (!match) {\n return;\n }\n event.preventDefault();\n applyMatch(match);\n return;\n }\n };\n\n return (\n <div\n className={cn(\"relative min-w-0 w-full\", className)}\n ref={containerRef}\n >\n <div className=\"w-full min-w-0\" onKeyDownCapture={handleKeyDown}>\n <EditorContent editor={editor} />\n </div>\n {isEmpty && placeholder ? (\n <div className=\"pointer-events-none absolute top-0 right-0 left-0 px-0 py-0 text-[var(--text-placeholder)]\">\n <div\n className={cn(\n \"min-w-0 w-full whitespace-pre-wrap\",\n placeholderClassName ?? textareaClassName,\n \"text-[var(--text-placeholder)]\"\n )}\n >\n {placeholder}\n </div>\n </div>\n ) : null}\n {overlay}\n {isMenuOpen && menuPoint ? (\n <ViewportMenuSurface\n open\n className=\"tutti-rich-text-at-menu max-h-64 w-[min(28rem,calc(100vw-24px))] overflow-y-auto p-1\"\n placement={{\n type: \"point\",\n point: menuPoint,\n alignX: \"start\",\n alignY: \"start\",\n estimatedSize: {\n width: 360,\n height: 256\n }\n }}\n style={menuZIndex === undefined ? undefined : { zIndex: menuZIndex }}\n >\n {matches.length > 0 ? (\n matches.map((match, index) => (\n <RichTextTriggerMenuItem\n key={`${match.providerId}:${match.key}`}\n label={match.label}\n selected={index === activeIndex}\n subtitle={match.subtitle}\n iconUrl={match.iconUrl}\n workspaceReferenceFileKind={getWorkspaceReferenceFileKind(\n match.insertResult\n )}\n onSelect={() => applyMatch(match)}\n />\n ))\n ) : (\n <div className=\"px-3 py-2 text-[11px] leading-4 text-[var(--text-secondary)]\">\n {isLoading ? text.loadingLabel : text.noMatchesLabel}\n </div>\n )}\n </ViewportMenuSurface>\n ) : null}\n </div>\n );\n}\n\nfunction findEditorAtQuery(\n editor: TiptapEditor,\n triggers: readonly RichTextTriggerConfig[]\n): RichTextEditorTriggerQueryState | null {\n const query = findEditorTriggerQuery(editor, triggers);\n if (!query) {\n return null;\n }\n return query;\n}\n\nfunction findEditorTriggerQuery(\n editor: TiptapEditor,\n triggers: readonly RichTextTriggerConfig[]\n): RichTextEditorTriggerQueryState | null {\n const { selection } = editor.state;\n if (!selection.empty) {\n return null;\n }\n\n const { $from } = selection;\n if (!$from.parent.isTextblock) {\n return null;\n }\n\n const textBeforeCursor = $from.parent.textBetween(\n 0,\n $from.parentOffset,\n \"\\n\",\n \"\\uFFFC\"\n );\n const query = findRichTextTriggerQuery(\n textBeforeCursor,\n textBeforeCursor.length,\n triggers\n );\n if (!query) {\n return null;\n }\n\n const distanceFromQueryStart = textBeforeCursor.length - query.from;\n return {\n from: selection.from - distanceFromQueryStart,\n keyword: query.keyword,\n trigger: query.trigger,\n to: selection.from\n };\n}\n\nfunction renderInsertResultAsEditorContent(\n providerId: string,\n result: RichTextTriggerInsertResult\n) {\n switch (result.kind) {\n case \"mention\":\n return {\n type: mentionReferenceNodeName,\n attrs: createRichTextMentionAttrs(providerId, result.mention)\n };\n case \"markdown-link\": {\n const kind = result.href.endsWith(\"/\") ? \"folder\" : \"file\";\n return {\n type: workspaceReferenceNodeName,\n attrs: {\n kind,\n label: result.label,\n path: normalizeRichTextLinkHref(result.href, kind)\n }\n };\n }\n case \"text\":\n return result.text;\n default:\n return null;\n }\n}\n\nfunction getWorkspaceReferenceFileKind(\n result: RichTextTriggerInsertResult\n): \"file\" | \"folder\" | undefined {\n if (result.kind !== \"markdown-link\") {\n return undefined;\n }\n return result.href.endsWith(\"/\") ? \"folder\" : \"file\";\n}\n\nfunction collectHydratableMentionNodes(\n editor: TiptapEditor\n): Array<{ attrs: RichTextMentionAttrs; pos: number }> {\n const mentions: Array<{ attrs: RichTextMentionAttrs; pos: number }> = [];\n\n editor.state.doc.descendants((node, pos) => {\n if (node.type.name !== mentionReferenceNodeName) {\n return;\n }\n const attrs = node.attrs as Partial<RichTextMentionAttrs>;\n if (\n attrs.trigger !== \"@\" ||\n typeof attrs.providerId !== \"string\" ||\n !attrs.providerId.trim() ||\n typeof attrs.entityId !== \"string\" ||\n !attrs.entityId.trim() ||\n typeof attrs.label !== \"string\" ||\n !attrs.label.trim()\n ) {\n return;\n }\n\n mentions.push({\n pos,\n attrs: {\n trigger: \"@\",\n providerId: attrs.providerId.trim(),\n entityId: attrs.entityId.trim(),\n label: attrs.label.trim().replace(/^@+/, \"\").trim(),\n scope: normalizeMentionStringRecord(attrs.scope),\n presentation: normalizeMentionPresentation(attrs.presentation)\n }\n });\n });\n\n return mentions;\n}\n\nfunction applyResolvedMentionAttrs(\n editor: TiptapEditor,\n pos: number,\n currentAttrs: RichTextMentionAttrs,\n resolved: {\n label?: string;\n presentation?: RichTextMentionPresentation;\n }\n): void {\n const node = editor.state.doc.nodeAt(pos);\n if (!node || node.type.name !== mentionReferenceNodeName) {\n return;\n }\n\n const attrs = node.attrs as Partial<RichTextMentionAttrs>;\n if (\n attrs.providerId !== currentAttrs.providerId ||\n attrs.entityId !== currentAttrs.entityId ||\n JSON.stringify(normalizeMentionStringRecord(attrs.scope) ?? {}) !==\n JSON.stringify(currentAttrs.scope ?? {})\n ) {\n return;\n }\n\n const nextLabel = resolved.label?.trim().replace(/^@+/, \"\").trim();\n const nextPresentation = normalizeMentionPresentation(resolved.presentation);\n const nextAttrs: RichTextMentionAttrs = {\n trigger: \"@\",\n providerId: currentAttrs.providerId,\n entityId: currentAttrs.entityId,\n label: nextLabel || currentAttrs.label,\n scope: currentAttrs.scope,\n presentation: nextPresentation ?? currentAttrs.presentation\n };\n\n if (\n attrs.label === nextAttrs.label &&\n JSON.stringify(normalizeMentionPresentation(attrs.presentation) ?? {}) ===\n JSON.stringify(nextAttrs.presentation ?? {})\n ) {\n return;\n }\n\n const transaction = editor.state.tr.setNodeMarkup(pos, undefined, nextAttrs);\n transaction.setMeta(\"addToHistory\", false);\n transaction.setMeta(\"preventUpdate\", true);\n editor.view.dispatch(transaction);\n}\n\nfunction normalizeMentionStringRecord(\n value: unknown\n): Readonly<Record<string, string>> | undefined {\n if (!value || typeof value !== \"object\") {\n return undefined;\n }\n const entries = Object.entries(value as Record<string, unknown>)\n .map(\n ([key, entryValue]) =>\n [\n key.trim(),\n typeof entryValue === \"string\" ? entryValue.trim() : \"\"\n ] as const\n )\n .filter(([key, entryValue]) => key.length > 0 && entryValue.length > 0)\n .sort(([left], [right]) => left.localeCompare(right));\n\n return entries.length > 0\n ? Object.freeze(Object.fromEntries(entries))\n : undefined;\n}\n\nfunction normalizeMentionPresentation(\n value: unknown\n): RichTextMentionPresentation | undefined {\n if (!value || typeof value !== \"object\") {\n return undefined;\n }\n const source = value as Record<keyof RichTextMentionPresentation, unknown>;\n const next: RichTextMentionPresentation = {};\n\n for (const key of RICH_TEXT_MENTION_PRESENTATION_KEYS) {\n const fieldValue = source[key];\n if (typeof fieldValue !== \"string\") {\n continue;\n }\n const trimmed = fieldValue.trim();\n if (trimmed) {\n next[key] = trimmed;\n }\n }\n\n return Object.keys(next).length > 0 ? Object.freeze(next) : undefined;\n}\n","import type {\n RichTextTrigger,\n RichTextTriggerBoundary,\n RichTextTriggerConfig,\n RichTextTriggerQueryInput,\n RichTextTriggerQueryMatch,\n RichTextTriggerRegistry\n} from \"../types/trigger.ts\";\n\nexport interface RichTextTriggerQueryState {\n from: number;\n to: number;\n keyword: string;\n trigger: RichTextTrigger;\n}\n\nexport function isRichTextTriggerPrefixBoundary(\n character: string,\n boundary: RichTextTriggerBoundary\n): boolean {\n if (boundary === \"whitespace\") {\n return /\\s/.test(character);\n }\n return /[\\s,;:!?<>{}|\\\\'\"`~()[\\]]/.test(character);\n}\n\nexport function findRichTextTriggerQuery(\n value: string,\n caret: number,\n triggerConfigs: readonly RichTextTriggerConfig[]\n): RichTextTriggerQueryState | null {\n const cursor = Math.max(0, Math.min(caret, value.length));\n if (triggerConfigs.length === 0) {\n return null;\n }\n let segmentStart = cursor;\n while (segmentStart > 0) {\n const previous = value[segmentStart - 1] ?? \"\";\n if (/\\s/.test(previous)) {\n break;\n }\n segmentStart -= 1;\n }\n\n const segment = value.slice(segmentStart, cursor);\n for (let index = segment.length - 1; index >= 0; index -= 1) {\n const trigger = segment[index] as RichTextTrigger;\n const matchingConfigs = triggerConfigs.filter(\n (config) => config.trigger === trigger\n );\n if (matchingConfigs.length === 0) {\n continue;\n }\n const previous = segment[index - 1] ?? \"\";\n if (\n index > 0 &&\n !matchingConfigs.some((config) =>\n isRichTextTriggerPrefixBoundary(previous, config.boundary)\n )\n ) {\n continue;\n }\n\n const candidate = segment.slice(index);\n if (/[[\\]()]/.test(candidate.slice(1))) {\n return null;\n }\n\n return {\n from: segmentStart + index,\n to: cursor,\n trigger,\n keyword: candidate.slice(1)\n };\n }\n\n return null;\n}\n\nexport async function queryRichTextTriggerMatches(\n registry: RichTextTriggerRegistry,\n input: RichTextTriggerQueryInput\n): Promise<readonly RichTextTriggerQueryMatch[]> {\n try {\n return await registry.query(input);\n } catch {\n return [];\n }\n}\n","export interface RichTextImeKeyboardEventLike {\n isComposing?: boolean;\n keyCode?: number;\n nativeEvent?: {\n isComposing?: boolean;\n keyCode?: number;\n which?: number;\n };\n which?: number;\n}\n\nexport function isRichTextImeComposing(\n event: RichTextImeKeyboardEventLike\n): boolean {\n if (event.isComposing || event.nativeEvent?.isComposing) {\n return true;\n }\n\n const keyCode = event.keyCode ?? event.nativeEvent?.keyCode;\n const which = event.which ?? event.nativeEvent?.which;\n return keyCode === 229 || which === 229;\n}\n","import {\n createDefaultRichTextI18nRuntime,\n type RichTextI18nRuntime\n} from \"../i18n/richTextI18n.ts\";\n\nexport interface RichTextTriggerTextOverrides {\n loadingLabel?: string;\n noMatchesLabel?: string;\n removeReferenceActionLabel?: string;\n}\n\nexport interface ResolvedRichTextTriggerText {\n loadingLabel: string;\n noMatchesLabel: string;\n removeReferenceActionLabel: string;\n}\n\nconst defaultRichTextI18n = createDefaultRichTextI18nRuntime();\n\nexport function resolveRichTextTriggerText(\n overrides?: RichTextTriggerTextOverrides,\n removeDecorationAriaLabel?: string,\n i18n: RichTextI18nRuntime = defaultRichTextI18n\n): ResolvedRichTextTriggerText {\n return {\n loadingLabel:\n overrides?.loadingLabel?.trim() || i18n.t(\"richTextAt.loading\"),\n noMatchesLabel:\n overrides?.noMatchesLabel?.trim() || i18n.t(\"richTextAt.noMatches\"),\n removeReferenceActionLabel:\n removeDecorationAriaLabel?.trim() ||\n overrides?.removeReferenceActionLabel?.trim() ||\n i18n.t(\"richTextAt.removeReferenceActionLabel\")\n };\n}\n\nexport const defaultRichTextTriggerText = resolveRichTextTriggerText();\n","import type { JSX, MouseEvent } from \"react\";\nimport { FileIcon, FolderFilledIcon } from \"@tutti-os/ui-system/icons\";\n\ntype RichTextTriggerMenuItemProps = {\n iconUrl?: string;\n label: string;\n selected: boolean;\n subtitle?: string;\n workspaceReferenceFileKind?: \"file\" | \"folder\";\n onSelect: () => void;\n};\n\nexport function RichTextTriggerMenuItem({\n iconUrl,\n label,\n selected,\n subtitle,\n workspaceReferenceFileKind,\n onSelect\n}: RichTextTriggerMenuItemProps): JSX.Element {\n return (\n <button\n aria-selected={selected}\n className={[\n \"flex w-full cursor-pointer items-center gap-2 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-[var(--text-primary)] outline-0 transition-colors duration-100\",\n selected ? \"bg-[var(--transparency-block)]\" : \"\",\n \"hover:bg-[var(--transparency-block)]\"\n ].join(\" \")}\n type=\"button\"\n onMouseDown={(event: MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n onSelect();\n }}\n >\n <RichTextTriggerMenuIcon\n iconUrl={iconUrl}\n workspaceReferenceFileKind={workspaceReferenceFileKind}\n />\n <span className=\"flex min-w-0 flex-auto flex-col items-start gap-0.5\">\n <span className=\"w-full overflow-hidden text-ellipsis whitespace-nowrap text-[13px] leading-5 font-semibold\">\n {label}\n </span>\n {subtitle ? (\n <span className=\"w-full overflow-hidden text-ellipsis whitespace-nowrap text-[11px] leading-4 text-[var(--text-secondary)]\">\n {subtitle}\n </span>\n ) : null}\n </span>\n </button>\n );\n}\n\nfunction RichTextTriggerMenuIcon({\n iconUrl,\n workspaceReferenceFileKind\n}: {\n iconUrl?: string;\n workspaceReferenceFileKind?: \"file\" | \"folder\";\n}): JSX.Element {\n const normalizedIconUrl = iconUrl?.trim() ?? \"\";\n\n if (workspaceReferenceFileKind) {\n const Icon =\n workspaceReferenceFileKind === \"folder\" ? FolderFilledIcon : FileIcon;\n return (\n <span\n aria-hidden=\"true\"\n className=\"inline-grid size-4 flex-none place-items-center text-[var(--folder)]\"\n data-rich-text-trigger-icon=\"true\"\n >\n <Icon className=\"size-4\" />\n </span>\n );\n }\n\n return (\n <span\n aria-hidden=\"true\"\n className=\"inline-grid size-4 flex-none place-items-center overflow-hidden rounded bg-[var(--bg-block,var(--transparency-block))]\"\n data-rich-text-trigger-icon=\"true\"\n >\n {normalizedIconUrl ? (\n <img\n alt=\"\"\n className=\"block size-full object-cover object-center\"\n decoding=\"async\"\n draggable={false}\n loading=\"lazy\"\n src={normalizedIconUrl}\n />\n ) : (\n <span className=\"block size-3 rounded-[3px] bg-[var(--transparency-block)]\" />\n )}\n </span>\n );\n}\n","import { mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport { mentionReferenceNodeName } from \"./names.ts\";\nimport { MentionReferenceNodeView } from \"./MentionReferenceNodeView.tsx\";\n\nexport interface MentionReferenceAttrs {\n entityId: string;\n label: string;\n presentation?: Readonly<Record<string, string>>;\n providerId: string;\n scope?: Readonly<Record<string, string>>;\n trigger: \"@\";\n}\n\nexport const MentionReference = Node.create({\n name: mentionReferenceNodeName,\n group: \"inline\",\n inline: true,\n atom: true,\n selectable: true,\n\n addAttributes() {\n return {\n entityId: {\n default: \"\"\n },\n label: {\n default: \"\"\n },\n presentation: {\n default: null\n },\n providerId: {\n default: \"\"\n },\n scope: {\n default: null\n },\n trigger: {\n default: \"@\"\n }\n };\n },\n\n parseHTML() {\n return [{ tag: \"span[data-rich-text-mention-reference]\" }];\n },\n\n renderHTML({ HTMLAttributes }) {\n const label =\n typeof HTMLAttributes.label === \"string\" ? HTMLAttributes.label : \"\";\n const displayLabel = label.trim().replace(/^@+/, \"\").trim();\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-rich-text-mention-reference\": \"true\",\n class:\n \"inline-flex max-w-full items-center overflow-hidden rounded-md bg-transparency-block px-1.5 py-0.5 align-baseline text-[13px] font-medium text-[var(--text-primary)]\"\n }),\n displayLabel ? `@${displayLabel}` : \"\"\n ];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(MentionReferenceNodeView, {\n as: \"span\",\n className: \"inline-flex max-w-full align-baseline\"\n });\n }\n});\n","import type { JSX } from \"react\";\nimport { NodeViewWrapper, type NodeViewProps } from \"@tiptap/react\";\nimport {\n MentionPill,\n type MentionPillKind\n} from \"@tutti-os/ui-system/components\";\n\nconst richTextMentionReferencePillClassName = \"max-w-[16rem]\";\n\nfunction readStringAttr(value: unknown): string {\n return typeof value === \"string\" ? value.trim() : \"\";\n}\n\nfunction readMentionPresentationUrl(presentation: unknown): string | null {\n if (!presentation || typeof presentation !== \"object\") {\n return null;\n }\n const value =\n (presentation as { iconUrl?: unknown; thumbnailUrl?: unknown }).iconUrl ??\n (presentation as { thumbnailUrl?: unknown }).thumbnailUrl;\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed || null;\n}\n\n// 句柄类 mention(如 workspace-reference 项目引用)的图标随 href 的 scope 编码,\n// markdown 带不了 presentation,故回退读 scope.icon,使 chip 与 agent 一样显示来源图标。\nfunction readMentionScopeValue(scope: unknown, key: string): string {\n if (!scope || typeof scope !== \"object\") {\n return \"\";\n }\n return readStringAttr((scope as Record<string, unknown>)[key]);\n}\n\n// providerId(+ workspace-reference 的 source)映射到设计系统 MentionPill 的 kind,\n// 让颜色/图标与 agent GUI 的 mention chip 完全一致。\nfunction resolveMentionPillKind(\n providerId: string,\n scope: unknown\n): MentionPillKind {\n const id = providerId.trim();\n if (id === \"agent-session\" || id === \"session\") {\n return \"session\";\n }\n if (id === \"workspace-app\") {\n return \"app\";\n }\n if (id === \"workspace-issue\") {\n return \"issue\";\n }\n if (id === \"workspace-reference\") {\n return readMentionScopeValue(scope, \"source\") === \"task\" ? \"issue\" : \"app\";\n }\n if (id === \"file\") {\n return \"file\";\n }\n return \"issue\";\n}\n\nexport function MentionReferenceNodeView({\n node,\n selected\n}: NodeViewProps): JSX.Element {\n const label =\n typeof node.attrs.label === \"string\"\n ? node.attrs.label.trim().replace(/^@+/, \"\").trim()\n : \"\";\n const iconUrl =\n readMentionPresentationUrl(node.attrs.presentation) ||\n readMentionScopeValue(node.attrs.scope, \"icon\");\n const kind = resolveMentionPillKind(\n readStringAttr(node.attrs.providerId),\n node.attrs.scope\n );\n\n return (\n <NodeViewWrapper\n as=\"span\"\n className={`inline-flex max-w-full align-baseline${\n selected ? \" is-selected\" : \"\"\n }`}\n contentEditable={false}\n data-rich-text-mention-reference=\"true\"\n >\n <MentionPill\n className={richTextMentionReferencePillClassName}\n iconUrl={iconUrl || undefined}\n kind={kind}\n label={label}\n removable={false}\n />\n </NodeViewWrapper>\n );\n}\n","import { mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport { workspaceReferenceNodeName } from \"./names.ts\";\nimport { WorkspaceReferenceNodeView } from \"./WorkspaceReferenceNodeView.tsx\";\nimport { getWorkspaceReferencePresentation } from \"./workspaceReferencePresentation.ts\";\nimport { defaultRichTextTriggerText } from \"../editor/richTextTriggerText.ts\";\n\nexport interface WorkspaceReferenceAttrs {\n kind: \"file\" | \"folder\";\n label: string;\n path: string;\n}\n\nexport const WorkspaceReference = Node.create({\n name: workspaceReferenceNodeName,\n addOptions() {\n return {\n removeActionAriaLabel:\n defaultRichTextTriggerText.removeReferenceActionLabel\n };\n },\n group: \"inline\",\n inline: true,\n atom: true,\n selectable: true,\n\n addAttributes() {\n return {\n kind: {\n default: \"file\"\n },\n label: {\n default: \"\"\n },\n path: {\n default: \"\"\n }\n } satisfies Record<keyof WorkspaceReferenceAttrs, { default: string }>;\n },\n\n parseHTML() {\n return [{ tag: \"span[data-rich-text-workspace-reference]\" }];\n },\n\n renderHTML({ HTMLAttributes }) {\n const kind = HTMLAttributes.kind === \"folder\" ? \"folder\" : \"file\";\n const label =\n typeof HTMLAttributes.label === \"string\" ? HTMLAttributes.label : \"\";\n const path =\n typeof HTMLAttributes.path === \"string\" ? HTMLAttributes.path : \"\";\n const presentation = getWorkspaceReferencePresentation(label, path);\n const referenceColorClassName =\n kind === \"folder\"\n ? \"text-[var(--rich-text-folder)]\"\n : \"text-[var(--rich-text-mention-file)]\";\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-rich-text-workspace-reference\": \"true\",\n \"data-rich-text-workspace-kind\": kind,\n \"data-agent-file-mention\": \"true\",\n \"data-agent-mention-kind\": \"file\",\n \"data-slot\": \"mention-pill\",\n title: presentation.fullPath,\n class: [\n \"group relative top-[3px] inline-flex max-w-full cursor-default items-center gap-1.5 overflow-hidden rounded-[4px] border border-transparent bg-transparent px-1.5 py-0.5 align-baseline text-[13px] font-medium leading-5 no-underline transition-colors hover:border-transparent hover:bg-[color-mix(in_srgb,currentColor_12%,transparent)]\",\n referenceColorClassName\n ].join(\" \")\n }),\n [\n \"span\",\n {\n \"aria-hidden\": \"true\",\n class: \"grid size-4 shrink-0 place-items-center text-current\"\n },\n kind === \"folder\" ? \"D\" : \"F\"\n ],\n [\n \"span\",\n {\n class: \"min-w-0 max-w-[20rem] truncate text-[13px] font-medium\"\n },\n presentation.displayLabel\n ]\n ];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(WorkspaceReferenceNodeView);\n }\n});\n","import { useEffect, useState, type JSX, type PointerEvent } from \"react\";\nimport { NodeViewWrapper, type NodeViewProps } from \"@tiptap/react\";\nimport {\n MentionPill,\n Tooltip,\n TooltipContent,\n TooltipTrigger\n} from \"@tutti-os/ui-system/components\";\nimport { getWorkspaceReferencePresentation } from \"./workspaceReferencePresentation.ts\";\nimport { defaultRichTextTriggerText } from \"../editor/richTextTriggerText.ts\";\n\nconst richTextWorkspaceReferencePillClassName = \"max-w-[18rem]\";\n\nexport function WorkspaceReferenceNodeView({\n deleteNode,\n editor,\n extension,\n node,\n selected\n}: NodeViewProps): JSX.Element {\n const [isEditable, setIsEditable] = useState(editor.isEditable);\n const attrs = node.attrs as {\n kind?: string;\n label?: string;\n path?: string;\n };\n const extensionOptions = extension.options as {\n removeActionAriaLabel?: string;\n };\n const kind = attrs.kind === \"folder\" ? \"folder\" : \"file\";\n const label = typeof attrs.label === \"string\" ? attrs.label : \"\";\n const path = typeof attrs.path === \"string\" ? attrs.path : \"\";\n const presentation = getWorkspaceReferencePresentation(label, path);\n const removeActionAriaLabel =\n typeof extensionOptions.removeActionAriaLabel === \"string\"\n ? extensionOptions.removeActionAriaLabel\n : defaultRichTextTriggerText.removeReferenceActionLabel;\n\n useEffect(() => {\n const syncEditable = () => {\n setIsEditable(editor.isEditable);\n };\n\n syncEditable();\n editor.on(\"transaction\", syncEditable);\n editor.on(\"update\", syncEditable);\n return () => {\n editor.off(\"transaction\", syncEditable);\n editor.off(\"update\", syncEditable);\n };\n }, [editor]);\n\n const handleRemove = (event: PointerEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n if (!editor.isEditable) {\n return;\n }\n deleteNode();\n };\n\n return (\n <NodeViewWrapper\n as=\"span\"\n className={`inline-flex max-w-full align-baseline ${\n selected ? \"is-selected\" : \"\"\n }`}\n contentEditable={false}\n data-rich-text-workspace-reference=\"true\"\n >\n <Tooltip>\n <TooltipTrigger asChild>\n <MentionPill\n className={richTextWorkspaceReferencePillClassName}\n fileKind={kind}\n kind=\"file\"\n label={presentation.displayLabel}\n removable={isEditable}\n removeButtonProps={\n isEditable\n ? {\n \"aria-label\": removeActionAriaLabel,\n onPointerDown: handleRemove,\n tabIndex: -1\n }\n : undefined\n }\n />\n </TooltipTrigger>\n <TooltipContent\n className=\"max-w-md whitespace-normal break-all\"\n sideOffset={8}\n >\n {presentation.fullPath}\n </TooltipContent>\n </Tooltip>\n </NodeViewWrapper>\n );\n}\n","export interface WorkspaceReferencePresentation {\n displayLabel: string;\n fullPath: string;\n}\n\nexport function getWorkspaceReferencePresentation(\n label: string,\n path: string\n): WorkspaceReferencePresentation {\n const displayLabel = normalizeReferenceLabel(label, path);\n const fullPath = normalizeFullPath(path);\n\n return {\n displayLabel,\n fullPath\n };\n}\n\nfunction normalizeReferenceLabel(label: string, path: string): string {\n const trimmedLabel = label.trim();\n\n if (trimmedLabel !== \"\") {\n return trimmedLabel;\n }\n\n return getPathBasename(path) || path.trim();\n}\n\nfunction normalizeFullPath(path: string): string {\n return trimTrailingSeparators(path.trim());\n}\n\nfunction getPathBasename(path: string): string {\n const normalizedPath = trimTrailingSeparators(path.trim());\n\n if (normalizedPath === \"\" || isPathRoot(normalizedPath)) {\n return normalizedPath;\n }\n\n const segments = normalizedPath.split(/[\\\\/]+/).filter(Boolean);\n\n return segments.at(-1) ?? \"\";\n}\n\nfunction trimTrailingSeparators(path: string): string {\n if (path === \"\") {\n return \"\";\n }\n\n if (isPathRoot(path)) {\n return path;\n }\n\n return path.replace(/[\\\\/]+$/, \"\");\n}\n\nfunction isPathRoot(path: string): boolean {\n return (\n path === \"/\" ||\n path === \"\\\\\" ||\n path === \"//\" ||\n path === \"\\\\\\\\\" ||\n /^[A-Za-z]:[\\\\/]?$/.test(path)\n );\n}\n","import {\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type PointerEvent,\n type ReactNode,\n type JSX,\n type KeyboardEvent\n} from \"react\";\nimport { ViewportMenuSurface } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport { createRichTextTriggerRegistry } from \"../plugins/triggerRegistry.ts\";\nimport { renderRichTextTriggerInsertResult } from \"../plugins/trigger.ts\";\nimport type {\n RichTextTriggerProvider,\n RichTextTriggerQueryMatch\n} from \"../types/trigger.ts\";\nimport {\n findRichTextTriggerQuery,\n queryRichTextTriggerMatches\n} from \"./richTextTriggerQuery.ts\";\nimport { isRichTextImeComposing } from \"./richTextIme.ts\";\nimport {\n buildRichTextTextareaDecorationSegments,\n getTextareaPresentationStyle,\n hasRichTextTextareaDecorations,\n resolveRichTextTextareaSelectionBoundary\n} from \"./richTextTextareaDecorationModel.ts\";\nimport {\n resolveRichTextTriggerText,\n type RichTextTriggerTextOverrides\n} from \"./richTextTriggerText.ts\";\nimport { RichTextTriggerMenuItem } from \"./RichTextTriggerMenuItem.tsx\";\nimport type { RichTextI18nRuntime } from \"../i18n/richTextI18n.ts\";\nimport { RichTextTextareaDecoratedContent } from \"./richTextTextareaDecorations.tsx\";\nimport { getTextareaCaretViewportPoint } from \"./richTextTextareaCaret.ts\";\nimport type { CSSProperties } from \"react\";\n\nexport interface RichTextTriggerTextareaProps {\n value: string;\n onChange: (value: string) => void;\n triggerProviders?: readonly RichTextTriggerProvider[];\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n textareaClassName?: string;\n rows?: number;\n minQueryLength?: number;\n maxResults?: number;\n removeDecorationAriaLabel?: string;\n i18n?: RichTextI18nRuntime;\n textOverrides?: RichTextTriggerTextOverrides;\n overlay?: ReactNode;\n}\n\nexport function RichTextTriggerTextarea({\n value,\n onChange,\n triggerProviders = [],\n placeholder,\n disabled = false,\n className,\n textareaClassName,\n rows,\n minQueryLength = 0,\n maxResults = 8,\n removeDecorationAriaLabel,\n i18n,\n textOverrides,\n overlay\n}: RichTextTriggerTextareaProps): JSX.Element {\n const menuOffset = 6;\n const text = resolveRichTextTriggerText(\n textOverrides,\n removeDecorationAriaLabel,\n i18n\n );\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const [selectionStart, setSelectionStart] = useState(0);\n const [matches, setMatches] = useState<readonly RichTextTriggerQueryMatch[]>(\n []\n );\n const [activeIndex, setActiveIndex] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [menuPoint, setMenuPoint] = useState<{ x: number; y: number } | null>(\n null\n );\n const [scrollPosition, setScrollPosition] = useState({ left: 0, top: 0 });\n const [textareaPresentationStyle, setTextareaPresentationStyle] =\n useState<CSSProperties | null>(null);\n const pendingSelectionRef = useRef<number | null>(null);\n const registry = useMemo(\n () => createRichTextTriggerRegistry(triggerProviders),\n [triggerProviders]\n );\n const activeTriggerConfigs = useMemo(\n () => registry.listTriggerConfigs(),\n [registry]\n );\n const decorationSegments = useMemo(\n () => buildRichTextTextareaDecorationSegments(value),\n [value]\n );\n const hasDecorations = hasRichTextTextareaDecorations(decorationSegments);\n const query = useMemo(\n () =>\n isFocused\n ? findRichTextTriggerQuery(value, selectionStart, activeTriggerConfigs)\n : null,\n [activeTriggerConfigs, isFocused, selectionStart, value]\n );\n const shouldQuery =\n query !== null &&\n query.keyword.length >= minQueryLength &&\n activeTriggerConfigs.length > 0;\n const isMenuOpen =\n isFocused && shouldQuery && (isLoading || matches.length > 0);\n\n useEffect(() => {\n const nextSelection = pendingSelectionRef.current;\n if (nextSelection === null || !textareaRef.current) {\n return;\n }\n textareaRef.current.setSelectionRange(nextSelection, nextSelection);\n pendingSelectionRef.current = null;\n }, [value]);\n\n useEffect(() => {\n if (!shouldQuery || !query) {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n return;\n }\n\n const abortController = new AbortController();\n setIsLoading(true);\n\n void queryRichTextTriggerMatches(registry, {\n abortSignal: abortController.signal,\n keyword: query.keyword,\n maxResults,\n trigger: query.trigger,\n context: {\n documentText: value,\n blockText: value\n }\n })\n .then((nextMatches) => {\n if (abortController.signal.aborted) {\n return;\n }\n setMatches(nextMatches);\n setActiveIndex((current) =>\n nextMatches.length === 0\n ? 0\n : Math.max(0, Math.min(current, nextMatches.length - 1))\n );\n })\n .finally(() => {\n if (!abortController.signal.aborted) {\n setIsLoading(false);\n }\n });\n\n return () => {\n abortController.abort();\n };\n }, [maxResults, query, registry, shouldQuery, value]);\n\n useLayoutEffect(() => {\n if (!textareaRef.current || !hasDecorations) {\n setTextareaPresentationStyle(null);\n return;\n }\n\n const textarea = textareaRef.current;\n setTextareaPresentationStyle(getTextareaPresentationStyle(textarea));\n setScrollPosition({\n left: textarea.scrollLeft,\n top: textarea.scrollTop\n });\n }, [hasDecorations, textareaClassName, value]);\n\n useLayoutEffect(() => {\n if (!isMenuOpen || !query || !textareaRef.current) {\n setMenuPoint(null);\n return;\n }\n\n const caretPoint = getTextareaCaretViewportPoint(\n textareaRef.current,\n query.to\n );\n const textareaRect = textareaRef.current.getBoundingClientRect();\n\n if (!caretPoint) {\n setMenuPoint({\n x: textareaRect.left + 12,\n y: textareaRect.bottom + menuOffset\n });\n return;\n }\n\n setMenuPoint({\n x: caretPoint.x,\n y: caretPoint.y + caretPoint.lineHeight + menuOffset\n });\n }, [isMenuOpen, menuOffset, query, selectionStart, value]);\n\n useEffect(() => {\n if (!isMenuOpen || !query || !textareaRef.current) {\n return;\n }\n\n const textarea = textareaRef.current;\n const updateMenuPoint = () => {\n const caretPoint = getTextareaCaretViewportPoint(textarea, query.to);\n const textareaRect = textarea.getBoundingClientRect();\n\n setMenuPoint(\n caretPoint\n ? {\n x: caretPoint.x,\n y: caretPoint.y + caretPoint.lineHeight + menuOffset\n }\n : {\n x: textareaRect.left + 12,\n y: textareaRect.bottom + menuOffset\n }\n );\n };\n\n const resizeObserver =\n typeof ResizeObserver === \"undefined\"\n ? null\n : new ResizeObserver(() => {\n updateMenuPoint();\n });\n resizeObserver?.observe(textarea);\n textarea.addEventListener(\"scroll\", updateMenuPoint, { passive: true });\n window.addEventListener(\"resize\", updateMenuPoint);\n window.addEventListener(\"scroll\", updateMenuPoint, {\n capture: true,\n passive: true\n });\n\n return () => {\n resizeObserver?.disconnect();\n textarea.removeEventListener(\"scroll\", updateMenuPoint);\n window.removeEventListener(\"resize\", updateMenuPoint);\n window.removeEventListener(\"scroll\", updateMenuPoint, true);\n };\n }, [isMenuOpen, menuOffset, query]);\n\n const closeMenu = () => {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n };\n\n const setSelection = (nextSelection: number) => {\n pendingSelectionRef.current = nextSelection;\n setSelectionStart(nextSelection);\n if (textareaRef.current) {\n textareaRef.current.focus();\n textareaRef.current.setSelectionRange(nextSelection, nextSelection);\n pendingSelectionRef.current = null;\n }\n };\n\n const handleClickDecoration = (\n segment: Extract<(typeof decorationSegments)[number], { type: \"link\" }>,\n event: PointerEvent<HTMLSpanElement>\n ) => {\n event.preventDefault();\n const bounds = event.currentTarget.getBoundingClientRect();\n const nextSelection =\n event.clientX < bounds.left + bounds.width / 2\n ? segment.from\n : segment.to;\n setSelection(nextSelection);\n };\n\n const handleRemoveDecoration = (\n segment: Extract<(typeof decorationSegments)[number], { type: \"link\" }>\n ) => {\n const nextValue = `${value.slice(0, segment.from)}${value.slice(segment.to)}`;\n const nextSelection = Math.min(segment.from, nextValue.length);\n pendingSelectionRef.current = nextSelection;\n onChange(nextValue);\n setSelectionStart(nextSelection);\n window.requestAnimationFrame(() => {\n if (!textareaRef.current) {\n return;\n }\n textareaRef.current.focus();\n textareaRef.current.setSelectionRange(nextSelection, nextSelection);\n pendingSelectionRef.current = null;\n });\n };\n\n const applyMatch = (match: RichTextTriggerQueryMatch) => {\n const currentQuery = findRichTextTriggerQuery(\n value,\n textareaRef.current?.selectionStart ?? selectionStart,\n activeTriggerConfigs\n );\n if (!currentQuery) {\n return;\n }\n const insertedValue = renderRichTextTriggerInsertResult(\n match.providerId,\n match.insertResult\n );\n const nextValue = `${value.slice(0, currentQuery.from)}${insertedValue}${value.slice(currentQuery.to)}`;\n const nextSelection = currentQuery.from + insertedValue.length;\n pendingSelectionRef.current = nextSelection;\n onChange(nextValue);\n closeMenu();\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (isRichTextImeComposing(event)) {\n return;\n }\n\n if (matches.length === 0) {\n return;\n }\n\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n setActiveIndex((current) => (current + 1) % matches.length);\n return;\n }\n\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveIndex(\n (current) => (current - 1 + matches.length) % matches.length\n );\n return;\n }\n\n if (event.key === \"Enter\" || event.key === \"Tab\") {\n const match = matches[activeIndex];\n if (!match) {\n return;\n }\n event.preventDefault();\n applyMatch(match);\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n closeMenu();\n }\n };\n\n return (\n <div className={cn(\"relative min-w-0 w-full\", className)}>\n {hasDecorations && textareaPresentationStyle ? (\n <RichTextTextareaDecoratedContent\n onClickSegment={handleClickDecoration}\n onRemoveSegment={handleRemoveDecoration}\n removeActionAriaLabel={text.removeReferenceActionLabel}\n scrollLeft={scrollPosition.left}\n scrollTop={scrollPosition.top}\n segments={decorationSegments}\n textareaStyle={textareaPresentationStyle}\n />\n ) : null}\n <textarea\n ref={textareaRef}\n className={textareaClassName}\n disabled={disabled}\n placeholder={placeholder}\n rows={rows}\n style={\n hasDecorations\n ? {\n WebkitTextFillColor: \"transparent\",\n caretColor: \"var(--text-primary)\",\n color: \"transparent\",\n position: \"relative\",\n zIndex: 0\n }\n : undefined\n }\n value={value}\n onBlur={() => {\n window.setTimeout(() => {\n setIsFocused(false);\n closeMenu();\n }, 100);\n }}\n onChange={(event) => {\n const rawSelectionStart = event.target.selectionStart ?? 0;\n const nextSelection =\n resolveRichTextTextareaSelectionBoundary(\n decorationSegments,\n rawSelectionStart\n ) ?? rawSelectionStart;\n if (nextSelection !== rawSelectionStart) {\n event.target.setSelectionRange(nextSelection, nextSelection);\n }\n setSelectionStart(nextSelection);\n onChange(event.target.value);\n }}\n onFocus={(event) => {\n setIsFocused(true);\n const rawSelectionStart = event.target.selectionStart ?? 0;\n const nextSelection =\n resolveRichTextTextareaSelectionBoundary(\n decorationSegments,\n rawSelectionStart\n ) ?? rawSelectionStart;\n if (nextSelection !== rawSelectionStart) {\n event.target.setSelectionRange(nextSelection, nextSelection);\n }\n setSelectionStart(nextSelection);\n setScrollPosition({\n left: event.target.scrollLeft,\n top: event.target.scrollTop\n });\n }}\n onKeyDown={handleKeyDown}\n onScroll={(event) => {\n setScrollPosition({\n left: event.currentTarget.scrollLeft,\n top: event.currentTarget.scrollTop\n });\n }}\n onSelect={(event) => {\n const rawSelectionStart = event.currentTarget.selectionStart ?? 0;\n const nextSelection =\n resolveRichTextTextareaSelectionBoundary(\n decorationSegments,\n rawSelectionStart\n ) ?? rawSelectionStart;\n if (nextSelection !== rawSelectionStart) {\n event.currentTarget.setSelectionRange(nextSelection, nextSelection);\n }\n setSelectionStart(nextSelection);\n }}\n />\n {overlay}\n {isMenuOpen && menuPoint ? (\n <ViewportMenuSurface\n open\n className=\"tutti-rich-text-at-menu max-h-64 w-[min(28rem,calc(100vw-24px))] overflow-y-auto p-1\"\n dismissIgnoreRefs={[textareaRef]}\n placement={{\n type: \"point\",\n point: menuPoint,\n alignX: \"start\",\n alignY: \"start\",\n estimatedSize: {\n width: 360,\n height: 256\n }\n }}\n >\n {matches.length > 0 ? (\n matches.map((match, index) => (\n <RichTextTriggerMenuItem\n key={`${match.providerId}:${match.key}`}\n label={match.label}\n selected={index === activeIndex}\n subtitle={match.subtitle}\n iconUrl={match.iconUrl}\n onSelect={() => applyMatch(match)}\n />\n ))\n ) : (\n <div className=\"px-3 py-2 text-[11px] leading-4 text-[var(--text-secondary)]\">\n {isLoading ? text.loadingLabel : text.noMatchesLabel}\n </div>\n )}\n </ViewportMenuSurface>\n ) : null}\n </div>\n );\n}\n","import type { CSSProperties } from \"react\";\nimport { findRichTextMarkdownLinks } from \"../core/richTextMarkdownLinks.ts\";\n\nconst EXTERNAL_LINK_PREFIX = /^(?:[a-z]+:)?\\/\\//i;\nconst MENTION_LINK_PREFIX = /^mention:\\/\\//i;\n\nconst TEXTAREA_PRESENTATION_STYLE_PROPERTIES = [\n { styleName: \"paddingTop\", cssName: \"padding-top\" },\n { styleName: \"paddingRight\", cssName: \"padding-right\" },\n { styleName: \"paddingBottom\", cssName: \"padding-bottom\" },\n { styleName: \"paddingLeft\", cssName: \"padding-left\" },\n { styleName: \"fontFamily\", cssName: \"font-family\" },\n { styleName: \"fontFeatureSettings\", cssName: \"font-feature-settings\" },\n { styleName: \"fontKerning\", cssName: \"font-kerning\" },\n { styleName: \"fontOpticalSizing\", cssName: \"font-optical-sizing\" },\n { styleName: \"fontSize\", cssName: \"font-size\" },\n { styleName: \"fontStretch\", cssName: \"font-stretch\" },\n { styleName: \"fontStyle\", cssName: \"font-style\" },\n { styleName: \"fontVariant\", cssName: \"font-variant\" },\n { styleName: \"fontVariationSettings\", cssName: \"font-variation-settings\" },\n { styleName: \"fontWeight\", cssName: \"font-weight\" },\n { styleName: \"letterSpacing\", cssName: \"letter-spacing\" },\n { styleName: \"lineHeight\", cssName: \"line-height\" },\n { styleName: \"textAlign\", cssName: \"text-align\" },\n { styleName: \"textIndent\", cssName: \"text-indent\" },\n { styleName: \"textTransform\", cssName: \"text-transform\" },\n { styleName: \"tabSize\", cssName: \"tab-size\" },\n { styleName: \"MozTabSize\", cssName: \"-moz-tab-size\" }\n] as const satisfies readonly {\n styleName: keyof CSSProperties;\n cssName: string;\n}[];\n\ntype RichTextTextareaTextDecorationSegment = {\n type: \"text\";\n text: string;\n from: number;\n to: number;\n};\n\ntype RichTextTextareaLinkDecorationSegment = {\n type: \"link\";\n text: string;\n from: number;\n to: number;\n label: string;\n href: string;\n kind: \"file\" | \"folder\";\n};\n\nexport type RichTextTextareaDecorationSegment =\n | RichTextTextareaTextDecorationSegment\n | RichTextTextareaLinkDecorationSegment;\n\nfunction isDecoratableMarkdownHref(href: string): boolean {\n const trimmedHref = href.trim();\n if (!trimmedHref) {\n return false;\n }\n if (\n EXTERNAL_LINK_PREFIX.test(trimmedHref) ||\n MENTION_LINK_PREFIX.test(trimmedHref)\n ) {\n return false;\n }\n return true;\n}\n\nexport function buildRichTextTextareaDecorationSegments(\n value: string\n): RichTextTextareaDecorationSegment[] {\n const segments: RichTextTextareaDecorationSegment[] = [];\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(value)) {\n const label = match.label.trim();\n const href = match.href.trim();\n const { index, source, to } = match;\n\n if (index > cursor) {\n segments.push({\n type: \"text\",\n text: value.slice(cursor, index),\n from: cursor,\n to: index\n });\n }\n\n if (label && href && isDecoratableMarkdownHref(href)) {\n segments.push({\n type: \"link\",\n text: source,\n from: index,\n to,\n label,\n href,\n kind: href.endsWith(\"/\") ? \"folder\" : \"file\"\n });\n } else {\n segments.push({\n type: \"text\",\n text: source,\n from: index,\n to\n });\n }\n\n cursor = to;\n }\n\n if (cursor < value.length) {\n segments.push({\n type: \"text\",\n text: value.slice(cursor),\n from: cursor,\n to: value.length\n });\n }\n\n return segments;\n}\n\nexport function hasRichTextTextareaDecorations(\n segments: readonly RichTextTextareaDecorationSegment[]\n): boolean {\n return segments.some((segment) => segment.type === \"link\");\n}\n\nexport function resolveRichTextTextareaSelectionBoundary(\n segments: readonly RichTextTextareaDecorationSegment[],\n selectionStart: number\n): number | null {\n for (const segment of segments) {\n if (segment.type !== \"link\") {\n continue;\n }\n if (selectionStart <= segment.from || selectionStart >= segment.to) {\n continue;\n }\n const midpoint = segment.from + (segment.to - segment.from) / 2;\n return selectionStart < midpoint ? segment.from : segment.to;\n }\n return null;\n}\n\nfunction setTextareaPresentationStyleValue<K extends keyof CSSProperties>(\n styleRecord: CSSProperties,\n styleName: K,\n value: string\n): void {\n styleRecord[styleName] = value as CSSProperties[K];\n}\n\nexport function getTextareaPresentationStyle(\n textarea: HTMLTextAreaElement\n): CSSProperties {\n const computedStyle = window.getComputedStyle(textarea);\n const styleRecord: CSSProperties = {\n whiteSpace: \"pre-wrap\"\n };\n\n setTextareaPresentationStyleValue(\n styleRecord,\n \"wordBreak\",\n computedStyle.wordBreak\n );\n setTextareaPresentationStyleValue(\n styleRecord,\n \"overflowWrap\",\n computedStyle.overflowWrap\n );\n\n for (const { styleName, cssName } of TEXTAREA_PRESENTATION_STYLE_PROPERTIES) {\n setTextareaPresentationStyleValue(\n styleRecord,\n styleName,\n computedStyle.getPropertyValue(cssName)\n );\n }\n\n return styleRecord;\n}\n","import type { CSSProperties, JSX, PointerEvent } from \"react\";\nimport { MentionPill } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport type { RichTextTextareaDecorationSegment } from \"./richTextTextareaDecorationModel.ts\";\n\nconst richTextWorkspaceReferencePillClassName = \"max-w-[18rem]\";\n\nexport function RichTextTextareaDecoratedContent({\n onClickSegment,\n onRemoveSegment,\n removeActionAriaLabel,\n scrollLeft,\n scrollTop,\n segments,\n textareaStyle\n}: {\n onClickSegment: (\n segment: Extract<RichTextTextareaDecorationSegment, { type: \"link\" }>,\n event: PointerEvent<HTMLSpanElement>\n ) => void;\n onRemoveSegment: (\n segment: Extract<RichTextTextareaDecorationSegment, { type: \"link\" }>\n ) => void;\n removeActionAriaLabel?: string;\n scrollLeft: number;\n scrollTop: number;\n segments: readonly RichTextTextareaDecorationSegment[];\n textareaStyle: CSSProperties;\n}): JSX.Element {\n return (\n <div className=\"pointer-events-none absolute inset-0 z-10 overflow-hidden\">\n <div\n className=\"min-h-full min-w-full\"\n style={{\n ...textareaStyle,\n transform: `translate(${-scrollLeft}px, ${-scrollTop}px)`\n }}\n >\n {segments.map((segment, index) => {\n if (segment.type === \"text\") {\n return <span key={index}>{segment.text}</span>;\n }\n\n return (\n <span key={index} className=\"relative\">\n <span aria-hidden=\"true\" className=\"text-transparent\">\n {segment.text}\n </span>\n <MentionPill\n className={cn(\n \"pointer-events-auto absolute inset-y-0 left-0 pr-1 pl-1.5\",\n richTextWorkspaceReferencePillClassName\n )}\n fileKind={segment.kind}\n kind=\"file\"\n label={segment.label}\n removeButtonProps={{\n \"aria-label\": removeActionAriaLabel,\n onPointerDown: (event) => {\n event.preventDefault();\n event.stopPropagation();\n onRemoveSegment(segment);\n }\n }}\n summary={\n <span\n className={cn(\n \"min-w-0 truncate text-[11px] text-current opacity-80\",\n segment.kind === \"folder\"\n ? \"max-w-[18rem]\"\n : \"max-w-[20rem]\"\n )}\n >\n {segment.href}\n </span>\n }\n onPointerDown={(event) => {\n onClickSegment(segment, event);\n }}\n />\n </span>\n );\n })}\n </div>\n </div>\n );\n}\n","const TEXTAREA_MIRROR_STYLE_PROPERTIES = [\n \"boxSizing\",\n \"width\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"borderTopWidth\",\n \"borderRightWidth\",\n \"borderBottomWidth\",\n \"borderLeftWidth\",\n \"borderTopStyle\",\n \"borderRightStyle\",\n \"borderBottomStyle\",\n \"borderLeftStyle\",\n \"borderTopColor\",\n \"borderRightColor\",\n \"borderBottomColor\",\n \"borderLeftColor\",\n \"borderRadius\",\n \"fontFamily\",\n \"fontFeatureSettings\",\n \"fontKerning\",\n \"fontOpticalSizing\",\n \"fontSize\",\n \"fontStretch\",\n \"fontStyle\",\n \"fontVariant\",\n \"fontVariationSettings\",\n \"fontWeight\",\n \"letterSpacing\",\n \"lineHeight\",\n \"textAlign\",\n \"textDecoration\",\n \"textIndent\",\n \"textTransform\",\n \"wordBreak\",\n \"overflowWrap\",\n \"tabSize\",\n \"MozTabSize\"\n] as const;\n\nexport interface TextareaCaretViewportPoint {\n x: number;\n y: number;\n lineHeight: number;\n}\n\nfunction parsePixelValue(value: string | null | undefined): number | null {\n if (!value || value === \"normal\") {\n return null;\n }\n\n const parsedValue = Number.parseFloat(value);\n return Number.isFinite(parsedValue) ? parsedValue : null;\n}\n\nfunction resolveLineHeight(computedStyle: CSSStyleDeclaration): number {\n const explicitLineHeight = parsePixelValue(computedStyle.lineHeight);\n if (explicitLineHeight !== null) {\n return explicitLineHeight;\n }\n\n const fontSize = parsePixelValue(computedStyle.fontSize);\n return fontSize !== null ? fontSize * 1.4 : 20;\n}\n\nexport function getTextareaCaretViewportPoint(\n textarea: HTMLTextAreaElement,\n selectionStart: number\n): TextareaCaretViewportPoint | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n const safeSelectionStart = Math.max(\n 0,\n Math.min(selectionStart, textarea.value.length)\n );\n const textareaRect = textarea.getBoundingClientRect();\n const computedStyle = window.getComputedStyle(textarea);\n const mirror = document.createElement(\"div\");\n const marker = document.createElement(\"span\");\n\n mirror.setAttribute(\"aria-hidden\", \"true\");\n mirror.style.position = \"fixed\";\n mirror.style.left = `${textareaRect.left}px`;\n mirror.style.top = `${textareaRect.top}px`;\n mirror.style.visibility = \"hidden\";\n mirror.style.pointerEvents = \"none\";\n mirror.style.overflow = \"hidden\";\n\n for (const propertyName of TEXTAREA_MIRROR_STYLE_PROPERTIES) {\n (mirror.style as CSSStyleDeclaration & Record<string, string>)[\n propertyName\n ] =\n (\n computedStyle as CSSStyleDeclaration &\n Record<string, string | undefined>\n )[propertyName] ?? \"\";\n }\n mirror.style.whiteSpace = \"pre-wrap\";\n mirror.style.wordBreak = computedStyle.wordBreak;\n mirror.style.overflowWrap = computedStyle.overflowWrap;\n\n const preSelectionText = textarea.value.slice(0, safeSelectionStart);\n mirror.textContent = preSelectionText.length > 0 ? preSelectionText : \"\";\n if (preSelectionText.endsWith(\"\\n\")) {\n mirror.append(document.createTextNode(\"\\u200b\"));\n }\n\n marker.textContent = \"\\u200b\";\n mirror.append(marker);\n document.body.append(mirror);\n\n try {\n const markerRect = marker.getBoundingClientRect();\n const lineHeight = resolveLineHeight(computedStyle);\n\n return {\n x: markerRect.left - textarea.scrollLeft,\n y: markerRect.top - textarea.scrollTop,\n lineHeight\n };\n } finally {\n mirror.remove();\n }\n}\n","import type { CSSProperties, JSX, MouseEvent, ReactNode } from \"react\";\nimport {\n getRichTextMentionDisplayText,\n resolveRichTextMentionView\n} from \"../plugins/mention.ts\";\nimport type {\n RichTextMentionAttrs,\n RichTextResolvedMention,\n RichTextResolvedMentionView\n} from \"../types/mention.ts\";\n\nexport interface RichTextMentionReadonlyClickPayload<TResolved = unknown> {\n mention: RichTextMentionAttrs;\n resolved: RichTextResolvedMentionView<TResolved>;\n}\n\nexport interface RichTextMentionReadonlyProps<TResolved = unknown> {\n mention: RichTextMentionAttrs;\n resolved?: RichTextResolvedMention<TResolved> | null;\n className?: string;\n title?: string;\n onClick?: (payload: RichTextMentionReadonlyClickPayload<TResolved>) => void;\n renderLabel?: (\n payload: RichTextMentionReadonlyClickPayload<TResolved>\n ) => ReactNode;\n}\n\nconst baseStyle: CSSProperties = {\n alignItems: \"center\",\n border: \"1px solid transparent\",\n borderRadius: \"999px\",\n display: \"inline-flex\",\n fontSize: \"0.95em\",\n gap: \"0.25rem\",\n lineHeight: 1.4,\n maxWidth: \"100%\",\n padding: \"0.05rem 0.45rem\",\n textDecoration: \"none\",\n verticalAlign: \"baseline\",\n whiteSpace: \"nowrap\"\n};\n\nconst stateStyles: Record<RichTextResolvedMentionView[\"state\"], CSSProperties> =\n {\n active: {\n background:\n \"var(--tutti-rich-text-mention-active-bg, color-mix(in srgb, currentColor 12%, transparent))\",\n color: \"var(--tutti-rich-text-mention-active-fg, inherit)\",\n cursor: \"pointer\"\n },\n missing: {\n background:\n \"var(--tutti-rich-text-mention-missing-bg, color-mix(in srgb, currentColor 6%, transparent))\",\n color:\n \"var(--tutti-rich-text-mention-missing-fg, color-mix(in srgb, currentColor 48%, transparent))\",\n cursor: \"default\",\n textDecoration: \"line-through\"\n },\n disabled: {\n background:\n \"var(--tutti-rich-text-mention-disabled-bg, color-mix(in srgb, currentColor 6%, transparent))\",\n color:\n \"var(--tutti-rich-text-mention-disabled-fg, color-mix(in srgb, currentColor 58%, transparent))\",\n cursor: \"not-allowed\",\n opacity: 0.88\n },\n loading: {\n background:\n \"var(--tutti-rich-text-mention-loading-bg, color-mix(in srgb, currentColor 8%, transparent))\",\n color:\n \"var(--tutti-rich-text-mention-loading-fg, color-mix(in srgb, currentColor 82%, transparent))\",\n cursor: \"progress\",\n opacity: 0.92\n }\n };\n\nfunction joinClassNames(\n ...parts: Array<string | null | undefined | false>\n): string | undefined {\n const value = parts.filter(Boolean).join(\" \").trim();\n return value || undefined;\n}\n\nexport function RichTextMentionReadonly<TResolved = unknown>({\n mention,\n resolved,\n className,\n title,\n onClick,\n renderLabel\n}: RichTextMentionReadonlyProps<TResolved>): JSX.Element {\n const view = resolveRichTextMentionView(mention, resolved);\n const payload: RichTextMentionReadonlyClickPayload<TResolved> = {\n mention,\n resolved: view as RichTextResolvedMentionView<TResolved>\n };\n const label =\n renderLabel?.(payload) ??\n getRichTextMentionDisplayText({\n ...mention,\n label: view.label\n });\n const elementTitle = title ?? view.tooltip;\n const handleClick = (event: MouseEvent<HTMLElement>) => {\n if (!view.interactive) {\n event.preventDefault();\n return;\n }\n onClick?.(payload);\n };\n\n const sharedProps = {\n \"aria-busy\": view.state === \"loading\" || undefined,\n \"aria-disabled\": !view.interactive || undefined,\n className: joinClassNames(\n \"tutti-rich-text-mention\",\n `tutti-rich-text-mention--${view.state}`,\n className\n ),\n \"data-provider-id\": mention.providerId,\n \"data-state\": view.state,\n style: {\n ...baseStyle,\n ...stateStyles[view.state]\n },\n title: elementTitle\n } as const;\n\n if (view.interactive && onClick) {\n return (\n <button\n {...sharedProps}\n onClick={(event) => {\n handleClick(event);\n }}\n style={{\n ...sharedProps.style,\n appearance: \"none\",\n font: \"inherit\"\n }}\n type=\"button\"\n >\n {label}\n </button>\n );\n }\n\n return <span {...sharedProps}>{label}</span>;\n}\n","import type { JSX } from \"react\";\nimport {\n MentionPill,\n Tooltip,\n TooltipContent,\n TooltipTrigger\n} from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport {\n isRichTextMentionHref,\n normalizeRichTextContent,\n normalizeRichTextLinkHref,\n parseRichTextMentionHref\n} from \"../core/richTextDocument.ts\";\nimport { getWorkspaceReferencePresentation } from \"../extensions/workspaceReferencePresentation.ts\";\nimport { RichTextMentionReadonly } from \"./RichTextMentionReadonly.tsx\";\nimport { buildRichTextReadonlyInlineSegments } from \"./richTextReadonlyContentModel.ts\";\nimport type { RichTextMentionAttrs } from \"../types/mention.ts\";\n\nexport interface RichTextReadonlyWorkspaceReference {\n kind: \"file\" | \"folder\";\n label: string;\n path: string;\n}\n\nexport interface RichTextReadonlyContentProps {\n value: string;\n className?: string;\n paragraphClassName?: string;\n onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>;\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>;\n}\n\nconst externalHrefPattern = /^(?:[a-z]+:)?\\/\\//i;\nconst richTextWorkspaceReferencePillClassName = \"max-w-[18rem]\";\n\nexport function RichTextReadonlyContent({\n value,\n className,\n paragraphClassName,\n onMentionAction,\n onOpenWorkspaceReference\n}: RichTextReadonlyContentProps): JSX.Element | null {\n const normalizedValue = normalizeRichTextContent(value).trim();\n\n if (!normalizedValue) {\n return null;\n }\n\n const paragraphs = normalizedValue\n .split(/\\n{2,}/)\n .map((paragraph) => paragraph.trim())\n .filter(Boolean);\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n {paragraphs.map((paragraph, paragraphIndex) => (\n <p\n className={cn(\"whitespace-pre-wrap\", paragraphClassName)}\n key={`${paragraphIndex}:${paragraph}`}\n >\n {renderReadonlyInlineMarkdown(\n paragraph,\n onOpenWorkspaceReference,\n onMentionAction\n )}\n </p>\n ))}\n </div>\n );\n}\n\nfunction renderReadonlyInlineMarkdown(\n content: string,\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>,\n onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>\n): JSX.Element[] {\n const parts: JSX.Element[] = [];\n const segments = buildRichTextReadonlyInlineSegments(content);\n\n segments.forEach((segment, index) => {\n if (segment.type === \"text\") {\n parts.push(<span key={`text:${index}`}>{segment.text}</span>);\n return;\n }\n\n parts.push(\n <RichTextReadonlyInlineLink\n href={segment.href}\n key={`link:${index}:${segment.href}`}\n label={segment.label}\n onMentionAction={onMentionAction}\n onOpenWorkspaceReference={onOpenWorkspaceReference}\n />\n );\n });\n\n return parts;\n}\n\nfunction RichTextReadonlyInlineLink({\n href,\n label,\n onMentionAction,\n onOpenWorkspaceReference\n}: {\n href: string;\n label: string;\n onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>;\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>;\n}): JSX.Element {\n const trimmedHref = href.trim();\n const mention = parseRichTextMentionHref(trimmedHref, label);\n\n if (mention) {\n return (\n <RichTextMentionReadonly\n mention={mention}\n onClick={\n onMentionAction\n ? ({ mention }) => {\n void onMentionAction(mention);\n }\n : undefined\n }\n />\n );\n }\n\n if (!trimmedHref) {\n return <span>{label}</span>;\n }\n\n if (\n externalHrefPattern.test(trimmedHref) &&\n !isRichTextMentionHref(trimmedHref)\n ) {\n return (\n <a\n className=\"font-medium text-[var(--text-primary)] underline decoration-[var(--border-1)] underline-offset-4 hover:text-[var(--text-primary-hover)]\"\n href={trimmedHref}\n rel=\"noreferrer\"\n target=\"_blank\"\n >\n {label}\n </a>\n );\n }\n\n const kind = trimmedHref.endsWith(\"/\") ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(trimmedHref, kind);\n\n return (\n <WorkspaceReferenceReadonly\n reference={{\n kind,\n label,\n path\n }}\n onOpenWorkspaceReference={onOpenWorkspaceReference}\n />\n );\n}\n\nfunction WorkspaceReferenceReadonly({\n reference,\n onOpenWorkspaceReference\n}: {\n reference: RichTextReadonlyWorkspaceReference;\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>;\n}): JSX.Element {\n const presentation = getWorkspaceReferencePresentation(\n reference.label,\n reference.path\n );\n const content = (\n <MentionPill\n className={richTextWorkspaceReferencePillClassName}\n fileKind={reference.kind}\n kind=\"file\"\n label={presentation.displayLabel}\n removable={false}\n />\n );\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n {onOpenWorkspaceReference ? (\n <button\n className=\"inline-flex max-w-full appearance-none items-baseline bg-transparent p-0 text-inherit\"\n type=\"button\"\n onClick={() => {\n void onOpenWorkspaceReference(reference);\n }}\n >\n {content}\n </button>\n ) : (\n <span className=\"inline-flex max-w-full align-baseline\">\n {content}\n </span>\n )}\n </TooltipTrigger>\n <TooltipContent\n className=\"max-w-md whitespace-normal break-all\"\n sideOffset={8}\n >\n {presentation.fullPath}\n </TooltipContent>\n </Tooltip>\n );\n}\n","import { findRichTextMarkdownLinks } from \"../core/richTextMarkdownLinks.ts\";\n\nexport type RichTextReadonlyInlineSegment =\n | {\n text: string;\n type: \"text\";\n }\n | {\n href: string;\n label: string;\n type: \"link\";\n };\n\nexport function buildRichTextReadonlyInlineSegments(\n content: string\n): RichTextReadonlyInlineSegment[] {\n const segments: RichTextReadonlyInlineSegment[] = [];\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(content)) {\n if (match.index > cursor) {\n segments.push({\n text: content.slice(cursor, match.index),\n type: \"text\"\n });\n }\n\n segments.push({\n href: match.href,\n label: match.label || match.href,\n type: \"link\"\n });\n cursor = match.to;\n }\n\n if (cursor < content.length) {\n segments.push({\n text: content.slice(cursor),\n type: \"text\"\n });\n }\n\n return segments;\n}\n"],"mappings":"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","names":["useEffect","useState","jsx","mergeAttributes","Node","ReactNodeViewRenderer","NodeViewWrapper","MentionPill","jsx","jsxs","NodeViewWrapper","MentionPill","Node","mergeAttributes","ReactNodeViewRenderer","jsx","jsxs","useState","editor","useEffect","useEffect","useLayoutEffect","useMemo","useRef","useState","ViewportMenuSurface","cn","MentionPill","cn","jsx","jsxs","richTextWorkspaceReferencePillClassName","jsx","jsxs","useRef","useState","useMemo","useEffect","useLayoutEffect","cn","ViewportMenuSurface","jsx","MentionPill","Tooltip","TooltipContent","TooltipTrigger","cn","jsx","jsxs","richTextWorkspaceReferencePillClassName","cn","mention","MentionPill","Tooltip","TooltipTrigger","TooltipContent"]}
|
|
1
|
+
{"version":3,"sources":["../../src/editor/RichTextTriggerEditor.tsx","../../src/editor/richTextTriggerQuery.ts","../../src/editor/richTextIme.ts","../../src/editor/richTextTriggerText.ts","../../src/editor/RichTextTriggerMenuItem.tsx","../../src/extensions/mentionReference.ts","../../src/extensions/MentionReferenceNodeView.tsx","../../src/extensions/workspaceReference.ts","../../src/extensions/WorkspaceReferenceNodeView.tsx","../../src/extensions/workspaceReferencePresentation.ts","../../src/editor/RichTextTriggerTextarea.tsx","../../src/editor/richTextTextareaDecorationModel.ts","../../src/editor/richTextTextareaDecorations.tsx","../../src/editor/richTextTextareaCaret.ts","../../src/editor/RichTextMentionReadonly.tsx","../../src/editor/RichTextReadonlyContent.tsx","../../src/editor/richTextReadonlyContentModel.ts"],"sourcesContent":["import {\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type KeyboardEvent,\n type ReactNode,\n type JSX\n} from \"react\";\nimport Document from \"@tiptap/extension-document\";\nimport HardBreak from \"@tiptap/extension-hard-break\";\nimport Paragraph from \"@tiptap/extension-paragraph\";\nimport Text from \"@tiptap/extension-text\";\nimport type { Editor as TiptapEditor } from \"@tiptap/react\";\nimport { EditorContent, useEditor } from \"@tiptap/react\";\nimport { ViewportMenuSurface } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport { createRichTextMentionAttrs } from \"../plugins/index.ts\";\nimport { createRichTextTriggerRegistry } from \"../plugins/triggerRegistry.ts\";\nimport type {\n RichTextMentionAttrs,\n RichTextMentionPresentation\n} from \"../types/mention.ts\";\nimport type {\n RichTextTriggerInsertResult,\n RichTextTriggerProvider,\n RichTextTriggerQueryMatch,\n RichTextTrigger,\n RichTextTriggerConfig\n} from \"../types/trigger.ts\";\nimport {\n normalizeRichTextContent,\n normalizeRichTextLinkHref,\n parseRichTextContentToDocument,\n serializeRichTextDocumentToContent\n} from \"../core/richTextDocument.ts\";\nimport {\n findRichTextTriggerQuery,\n queryRichTextTriggerMatches\n} from \"./richTextTriggerQuery.ts\";\nimport { isRichTextImeComposing } from \"./richTextIme.ts\";\nimport {\n resolveRichTextTriggerText,\n type RichTextTriggerTextOverrides\n} from \"./richTextTriggerText.ts\";\nimport { RichTextTriggerMenuItem } from \"./RichTextTriggerMenuItem.tsx\";\nimport type { RichTextI18nRuntime } from \"../i18n/richTextI18n.ts\";\nimport { MentionReference } from \"../extensions/mentionReference.ts\";\nimport { WorkspaceReference } from \"../extensions/workspaceReference.ts\";\nimport {\n mentionReferenceNodeName,\n workspaceReferenceNodeName\n} from \"../extensions/names.ts\";\n\nexport interface RichTextTriggerEditorProps {\n value: string;\n onChange: (value: string) => void;\n triggerProviders?: readonly RichTextTriggerProvider[];\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n textareaClassName?: string;\n placeholderClassName?: string;\n minQueryLength?: number;\n maxResults?: number;\n removeDecorationAriaLabel?: string;\n i18n?: RichTextI18nRuntime;\n textOverrides?: RichTextTriggerTextOverrides;\n overlay?: ReactNode;\n focusSignal?: unknown;\n menuZIndex?: string | number;\n}\n\ntype RichTextEditorTriggerQueryState = {\n from: number;\n keyword: string;\n trigger: RichTextTrigger;\n to: number;\n};\n\nconst RICH_TEXT_MENTION_PRESENTATION_KEYS = [\n \"agentProviderId\",\n \"agentIconUrl\",\n \"iconUrl\",\n \"thumbnailUrl\",\n \"subtitle\",\n \"description\",\n \"participant\",\n \"status\",\n \"statusDataStatus\",\n \"statusLabel\",\n \"statusPulse\",\n \"userAvatarPlaceholderUrl\"\n] as const satisfies readonly (keyof RichTextMentionPresentation)[];\n\nexport function RichTextTriggerEditor({\n value,\n onChange,\n triggerProviders = [],\n placeholder,\n disabled = false,\n className,\n textareaClassName,\n placeholderClassName,\n minQueryLength = 0,\n maxResults = 8,\n removeDecorationAriaLabel,\n i18n,\n textOverrides,\n overlay,\n focusSignal,\n menuZIndex\n}: RichTextTriggerEditorProps): JSX.Element {\n const menuOffset = 6;\n const normalizedValue = normalizeRichTextContent(value);\n const text = resolveRichTextTriggerText(\n textOverrides,\n removeDecorationAriaLabel,\n i18n\n );\n const latestOnChangeRef = useRef(onChange);\n const lastSerializedValueRef = useRef(normalizedValue);\n const lastFocusSignalRef = useRef(focusSignal);\n const mentionHydrationRequestRef = useRef(0);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const registry = useMemo(\n () => createRichTextTriggerRegistry(triggerProviders),\n [triggerProviders]\n );\n const activeTriggerConfigs = useMemo(\n () => registry.listTriggerConfigs(),\n [registry]\n );\n const [isFocused, setIsFocused] = useState(false);\n const [query, setQuery] = useState<RichTextEditorTriggerQueryState | null>(\n null\n );\n const [matches, setMatches] = useState<readonly RichTextTriggerQueryMatch[]>(\n []\n );\n const [activeIndex, setActiveIndex] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [menuPoint, setMenuPoint] = useState<{ x: number; y: number } | null>(\n null\n );\n\n latestOnChangeRef.current = onChange;\n\n const editor = useEditor({\n immediatelyRender: false,\n editable: !disabled,\n extensions: [\n Document,\n Paragraph,\n Text,\n HardBreak,\n WorkspaceReference.configure({\n removeActionAriaLabel: text.removeReferenceActionLabel\n }),\n MentionReference\n ],\n content: parseRichTextContentToDocument(normalizedValue),\n editorProps: {\n attributes: {\n class: cn(\n \"w-full whitespace-pre-wrap break-words outline-none\",\n textareaClassName\n )\n }\n },\n onBlur() {\n window.setTimeout(() => {\n setIsFocused(false);\n setQuery(null);\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n }, 100);\n },\n onFocus() {\n setIsFocused(true);\n },\n onUpdate({ editor }) {\n const serialized = serializeRichTextDocumentToContent(editor.getJSON());\n lastSerializedValueRef.current = serialized;\n latestOnChangeRef.current(serialized);\n }\n });\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n if (lastSerializedValueRef.current === normalizedValue) {\n return;\n }\n\n const currentSerialized = serializeRichTextDocumentToContent(\n editor.getJSON()\n );\n if (currentSerialized === normalizedValue) {\n lastSerializedValueRef.current = normalizedValue;\n return;\n }\n\n editor.commands.setContent(\n parseRichTextContentToDocument(normalizedValue),\n {\n emitUpdate: false\n }\n );\n lastSerializedValueRef.current = normalizedValue;\n }, [editor, normalizedValue]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const requestId = mentionHydrationRequestRef.current + 1;\n mentionHydrationRequestRef.current = requestId;\n const mentions = collectHydratableMentionNodes(editor);\n if (mentions.length === 0) {\n return;\n }\n\n for (const mention of mentions) {\n const provider = registry.getProvider(mention.attrs.providerId);\n if (!provider?.resolveMention) {\n continue;\n }\n\n void Promise.resolve(provider.resolveMention(mention.attrs))\n .then((resolved) => {\n if (\n !resolved ||\n mentionHydrationRequestRef.current !== requestId ||\n editor.isDestroyed\n ) {\n return;\n }\n\n applyResolvedMentionAttrs(editor, mention.pos, mention.attrs, {\n label: resolved.label,\n presentation: resolved.presentation\n });\n })\n .catch(() => {\n // Resolver failures keep the fallback label-only mention.\n });\n }\n }, [editor, registry, normalizedValue]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n if (Object.is(lastFocusSignalRef.current, focusSignal)) {\n return;\n }\n\n lastFocusSignalRef.current = focusSignal;\n editor.commands.focus(\"end\");\n }, [editor, focusSignal]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n editor.setEditable(!disabled);\n editor.view.dispatch(\n editor.state.tr.setMeta(\"richTextEditable\", !disabled)\n );\n }, [disabled, editor]);\n\n useEffect(() => {\n if (!editor) {\n return;\n }\n\n const updateQueryState = () => {\n const nextQuery = findEditorAtQuery(editor, activeTriggerConfigs);\n setQuery(nextQuery);\n };\n\n const updateFocus = () => {\n const nextFocused = editor.isFocused;\n setIsFocused(nextFocused);\n updateQueryState();\n };\n\n updateQueryState();\n editor.on(\"selectionUpdate\", updateQueryState);\n editor.on(\"transaction\", updateQueryState);\n editor.on(\"focus\", updateFocus);\n editor.on(\"blur\", updateFocus);\n return () => {\n editor.off(\"selectionUpdate\", updateQueryState);\n editor.off(\"transaction\", updateQueryState);\n editor.off(\"focus\", updateFocus);\n editor.off(\"blur\", updateFocus);\n };\n }, [activeTriggerConfigs, editor]);\n\n useEffect(() => {\n if (!editor || !query || activeTriggerConfigs.length === 0) {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n return;\n }\n\n if (query.keyword.length < minQueryLength) {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n return;\n }\n\n const abortController = new AbortController();\n setIsLoading(true);\n\n void queryRichTextTriggerMatches(registry, {\n abortSignal: abortController.signal,\n keyword: query.keyword,\n maxResults,\n trigger: query.trigger,\n context: {\n blockText: editor.state.selection.$from.parent.textBetween(\n 0,\n editor.state.selection.$from.parent.content.size,\n \"\\n\",\n \"\\uFFFC\"\n ),\n documentText: serializeRichTextDocumentToContent(editor.getJSON())\n }\n })\n .then((nextMatches) => {\n if (abortController.signal.aborted) {\n return;\n }\n setMatches(nextMatches);\n setActiveIndex((current) =>\n nextMatches.length === 0\n ? 0\n : Math.max(0, Math.min(current, nextMatches.length - 1))\n );\n })\n .finally(() => {\n if (!abortController.signal.aborted) {\n setIsLoading(false);\n }\n });\n\n return () => {\n abortController.abort();\n };\n }, [\n editor,\n maxResults,\n minQueryLength,\n activeTriggerConfigs.length,\n query,\n registry\n ]);\n\n useLayoutEffect(() => {\n if (!editor || !query) {\n setMenuPoint(null);\n return;\n }\n\n const updateMenuPoint = () => {\n const coords = editor.view.coordsAtPos(editor.state.selection.from);\n const nextMenuPoint = {\n x: coords.left,\n y: coords.bottom + menuOffset\n };\n setMenuPoint(nextMenuPoint);\n };\n\n updateMenuPoint();\n window.addEventListener(\"resize\", updateMenuPoint);\n window.addEventListener(\"scroll\", updateMenuPoint, {\n capture: true,\n passive: true\n });\n return () => {\n window.removeEventListener(\"resize\", updateMenuPoint);\n window.removeEventListener(\"scroll\", updateMenuPoint, true);\n };\n }, [editor, menuOffset, query]);\n\n const canQueryTrigger =\n !!query &&\n activeTriggerConfigs.length > 0 &&\n query.keyword.length >= minQueryLength;\n const isMenuOpen = canQueryTrigger && (isFocused || !!menuPoint);\n const isEmpty =\n !editor ||\n serializeRichTextDocumentToContent(editor.getJSON()).trim().length === 0;\n\n const applyMatch = (match: RichTextTriggerQueryMatch) => {\n if (!editor || !query) {\n return;\n }\n\n const content = renderInsertResultAsEditorContent(\n match.providerId,\n match.insertResult\n );\n if (!content) {\n return;\n }\n\n editor\n .chain()\n .focus()\n .insertContentAt({ from: query.from, to: query.to }, content)\n .run();\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (isRichTextImeComposing(event)) {\n return;\n }\n\n if (!isMenuOpen) {\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n return;\n }\n\n if (matches.length === 0) {\n return;\n }\n\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n setActiveIndex((current) => (current + 1) % matches.length);\n return;\n }\n\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveIndex(\n (current) => (current - 1 + matches.length) % matches.length\n );\n return;\n }\n\n if (event.key === \"Enter\" || event.key === \"Tab\") {\n const match = matches[activeIndex];\n if (!match) {\n return;\n }\n event.preventDefault();\n applyMatch(match);\n return;\n }\n };\n\n return (\n <div\n className={cn(\"relative min-w-0 w-full\", className)}\n ref={containerRef}\n >\n <div className=\"w-full min-w-0\" onKeyDownCapture={handleKeyDown}>\n <EditorContent editor={editor} />\n </div>\n {isEmpty && placeholder ? (\n <div className=\"pointer-events-none absolute top-0 right-0 left-0 px-0 py-0 text-[var(--text-placeholder)]\">\n <div\n className={cn(\n \"min-w-0 w-full whitespace-pre-wrap\",\n placeholderClassName ?? textareaClassName,\n \"text-[var(--text-placeholder)]\"\n )}\n >\n {placeholder}\n </div>\n </div>\n ) : null}\n {overlay}\n {isMenuOpen && menuPoint ? (\n <ViewportMenuSurface\n open\n className=\"tutti-rich-text-at-menu max-h-64 w-[min(28rem,calc(100vw-24px))] overflow-y-auto p-1\"\n placement={{\n type: \"point\",\n point: menuPoint,\n alignX: \"start\",\n alignY: \"start\",\n estimatedSize: {\n width: 360,\n height: 256\n }\n }}\n style={menuZIndex === undefined ? undefined : { zIndex: menuZIndex }}\n >\n {matches.length > 0 ? (\n matches.map((match, index) => (\n <RichTextTriggerMenuItem\n key={`${match.providerId}:${match.key}`}\n label={match.label}\n selected={index === activeIndex}\n subtitle={match.subtitle}\n iconUrl={match.iconUrl}\n workspaceReferenceFileKind={getWorkspaceReferenceFileKind(\n match.insertResult\n )}\n onSelect={() => applyMatch(match)}\n />\n ))\n ) : (\n <div className=\"px-3 py-2 text-[11px] leading-4 text-[var(--text-secondary)]\">\n {isLoading ? text.loadingLabel : text.noMatchesLabel}\n </div>\n )}\n </ViewportMenuSurface>\n ) : null}\n </div>\n );\n}\n\nfunction findEditorAtQuery(\n editor: TiptapEditor,\n triggers: readonly RichTextTriggerConfig[]\n): RichTextEditorTriggerQueryState | null {\n const query = findEditorTriggerQuery(editor, triggers);\n if (!query) {\n return null;\n }\n return query;\n}\n\nfunction findEditorTriggerQuery(\n editor: TiptapEditor,\n triggers: readonly RichTextTriggerConfig[]\n): RichTextEditorTriggerQueryState | null {\n const { selection } = editor.state;\n if (!selection.empty) {\n return null;\n }\n\n const { $from } = selection;\n if (!$from.parent.isTextblock) {\n return null;\n }\n\n const textBeforeCursor = $from.parent.textBetween(\n 0,\n $from.parentOffset,\n \"\\n\",\n \"\\uFFFC\"\n );\n const query = findRichTextTriggerQuery(\n textBeforeCursor,\n textBeforeCursor.length,\n triggers\n );\n if (!query) {\n return null;\n }\n\n const distanceFromQueryStart = textBeforeCursor.length - query.from;\n return {\n from: selection.from - distanceFromQueryStart,\n keyword: query.keyword,\n trigger: query.trigger,\n to: selection.from\n };\n}\n\nfunction renderInsertResultAsEditorContent(\n providerId: string,\n result: RichTextTriggerInsertResult\n) {\n switch (result.kind) {\n case \"mention\":\n return {\n type: mentionReferenceNodeName,\n attrs: createRichTextMentionAttrs(providerId, result.mention)\n };\n case \"markdown-link\": {\n const kind = result.href.endsWith(\"/\") ? \"folder\" : \"file\";\n return {\n type: workspaceReferenceNodeName,\n attrs: {\n kind,\n label: result.label,\n path: normalizeRichTextLinkHref(result.href, kind)\n }\n };\n }\n case \"text\":\n return result.text;\n default:\n return null;\n }\n}\n\nfunction getWorkspaceReferenceFileKind(\n result: RichTextTriggerInsertResult\n): \"file\" | \"folder\" | undefined {\n if (result.kind !== \"markdown-link\") {\n return undefined;\n }\n return result.href.endsWith(\"/\") ? \"folder\" : \"file\";\n}\n\nfunction collectHydratableMentionNodes(\n editor: TiptapEditor\n): Array<{ attrs: RichTextMentionAttrs; pos: number }> {\n const mentions: Array<{ attrs: RichTextMentionAttrs; pos: number }> = [];\n\n editor.state.doc.descendants((node, pos) => {\n if (node.type.name !== mentionReferenceNodeName) {\n return;\n }\n const attrs = node.attrs as Partial<RichTextMentionAttrs>;\n if (\n attrs.trigger !== \"@\" ||\n typeof attrs.providerId !== \"string\" ||\n !attrs.providerId.trim() ||\n typeof attrs.entityId !== \"string\" ||\n !attrs.entityId.trim() ||\n typeof attrs.label !== \"string\" ||\n !attrs.label.trim()\n ) {\n return;\n }\n\n mentions.push({\n pos,\n attrs: {\n trigger: \"@\",\n providerId: attrs.providerId.trim(),\n entityId: attrs.entityId.trim(),\n label: attrs.label.trim().replace(/^@+/, \"\").trim(),\n scope: normalizeMentionStringRecord(attrs.scope),\n presentation: normalizeMentionPresentation(attrs.presentation)\n }\n });\n });\n\n return mentions;\n}\n\nfunction applyResolvedMentionAttrs(\n editor: TiptapEditor,\n pos: number,\n currentAttrs: RichTextMentionAttrs,\n resolved: {\n label?: string;\n presentation?: RichTextMentionPresentation;\n }\n): void {\n const node = editor.state.doc.nodeAt(pos);\n if (!node || node.type.name !== mentionReferenceNodeName) {\n return;\n }\n\n const attrs = node.attrs as Partial<RichTextMentionAttrs>;\n if (\n attrs.providerId !== currentAttrs.providerId ||\n attrs.entityId !== currentAttrs.entityId ||\n JSON.stringify(normalizeMentionStringRecord(attrs.scope) ?? {}) !==\n JSON.stringify(currentAttrs.scope ?? {})\n ) {\n return;\n }\n\n const nextLabel = resolved.label?.trim().replace(/^@+/, \"\").trim();\n const nextPresentation = normalizeMentionPresentation(resolved.presentation);\n const nextAttrs: RichTextMentionAttrs = {\n trigger: \"@\",\n providerId: currentAttrs.providerId,\n entityId: currentAttrs.entityId,\n label: nextLabel || currentAttrs.label,\n scope: currentAttrs.scope,\n presentation: nextPresentation ?? currentAttrs.presentation\n };\n\n if (\n attrs.label === nextAttrs.label &&\n JSON.stringify(normalizeMentionPresentation(attrs.presentation) ?? {}) ===\n JSON.stringify(nextAttrs.presentation ?? {})\n ) {\n return;\n }\n\n const transaction = editor.state.tr.setNodeMarkup(pos, undefined, nextAttrs);\n transaction.setMeta(\"addToHistory\", false);\n transaction.setMeta(\"preventUpdate\", true);\n editor.view.dispatch(transaction);\n}\n\nfunction normalizeMentionStringRecord(\n value: unknown\n): Readonly<Record<string, string>> | undefined {\n if (!value || typeof value !== \"object\") {\n return undefined;\n }\n const entries = Object.entries(value as Record<string, unknown>)\n .map(\n ([key, entryValue]) =>\n [\n key.trim(),\n typeof entryValue === \"string\" ? entryValue.trim() : \"\"\n ] as const\n )\n .filter(([key, entryValue]) => key.length > 0 && entryValue.length > 0)\n .sort(([left], [right]) => left.localeCompare(right));\n\n return entries.length > 0\n ? Object.freeze(Object.fromEntries(entries))\n : undefined;\n}\n\nfunction normalizeMentionPresentation(\n value: unknown\n): RichTextMentionPresentation | undefined {\n if (!value || typeof value !== \"object\") {\n return undefined;\n }\n const source = value as Record<keyof RichTextMentionPresentation, unknown>;\n const next: RichTextMentionPresentation = {};\n\n for (const key of RICH_TEXT_MENTION_PRESENTATION_KEYS) {\n const fieldValue = source[key];\n if (typeof fieldValue !== \"string\") {\n continue;\n }\n const trimmed = fieldValue.trim();\n if (trimmed) {\n next[key] = trimmed;\n }\n }\n\n return Object.keys(next).length > 0 ? Object.freeze(next) : undefined;\n}\n","import type {\n RichTextTrigger,\n RichTextTriggerBoundary,\n RichTextTriggerConfig,\n RichTextTriggerQueryInput,\n RichTextTriggerQueryMatch,\n RichTextTriggerRegistry\n} from \"../types/trigger.ts\";\n\nexport interface RichTextTriggerQueryState {\n from: number;\n to: number;\n keyword: string;\n trigger: RichTextTrigger;\n}\n\nexport function isRichTextTriggerPrefixBoundary(\n character: string,\n boundary: RichTextTriggerBoundary\n): boolean {\n if (boundary === \"whitespace\") {\n return /\\s/.test(character);\n }\n return /[\\s,;:!?<>{}|\\\\'\"`~()[\\]]/.test(character);\n}\n\nexport function findRichTextTriggerQuery(\n value: string,\n caret: number,\n triggerConfigs: readonly RichTextTriggerConfig[]\n): RichTextTriggerQueryState | null {\n const cursor = Math.max(0, Math.min(caret, value.length));\n if (triggerConfigs.length === 0) {\n return null;\n }\n let segmentStart = cursor;\n while (segmentStart > 0) {\n const previous = value[segmentStart - 1] ?? \"\";\n if (/\\s/.test(previous)) {\n break;\n }\n segmentStart -= 1;\n }\n\n const segment = value.slice(segmentStart, cursor);\n for (let index = segment.length - 1; index >= 0; index -= 1) {\n const trigger = segment[index] as RichTextTrigger;\n const matchingConfigs = triggerConfigs.filter(\n (config) => config.trigger === trigger\n );\n if (matchingConfigs.length === 0) {\n continue;\n }\n const previous = segment[index - 1] ?? \"\";\n if (\n index > 0 &&\n !matchingConfigs.some((config) =>\n isRichTextTriggerPrefixBoundary(previous, config.boundary)\n )\n ) {\n continue;\n }\n\n const candidate = segment.slice(index);\n if (/[[\\]()]/.test(candidate.slice(1))) {\n return null;\n }\n\n return {\n from: segmentStart + index,\n to: cursor,\n trigger,\n keyword: candidate.slice(1)\n };\n }\n\n return null;\n}\n\nexport async function queryRichTextTriggerMatches(\n registry: RichTextTriggerRegistry,\n input: RichTextTriggerQueryInput\n): Promise<readonly RichTextTriggerQueryMatch[]> {\n try {\n return await registry.query(input);\n } catch {\n return [];\n }\n}\n","export interface RichTextImeKeyboardEventLike {\n isComposing?: boolean;\n keyCode?: number;\n nativeEvent?: {\n isComposing?: boolean;\n keyCode?: number;\n which?: number;\n };\n which?: number;\n}\n\nexport function isRichTextImeComposing(\n event: RichTextImeKeyboardEventLike\n): boolean {\n if (event.isComposing || event.nativeEvent?.isComposing) {\n return true;\n }\n\n const keyCode = event.keyCode ?? event.nativeEvent?.keyCode;\n const which = event.which ?? event.nativeEvent?.which;\n return keyCode === 229 || which === 229;\n}\n","import {\n createDefaultRichTextI18nRuntime,\n type RichTextI18nRuntime\n} from \"../i18n/richTextI18n.ts\";\n\nexport interface RichTextTriggerTextOverrides {\n loadingLabel?: string;\n noMatchesLabel?: string;\n removeReferenceActionLabel?: string;\n}\n\nexport interface ResolvedRichTextTriggerText {\n loadingLabel: string;\n noMatchesLabel: string;\n removeReferenceActionLabel: string;\n}\n\nconst defaultRichTextI18n = createDefaultRichTextI18nRuntime();\n\nexport function resolveRichTextTriggerText(\n overrides?: RichTextTriggerTextOverrides,\n removeDecorationAriaLabel?: string,\n i18n: RichTextI18nRuntime = defaultRichTextI18n\n): ResolvedRichTextTriggerText {\n return {\n loadingLabel:\n overrides?.loadingLabel?.trim() || i18n.t(\"richTextAt.loading\"),\n noMatchesLabel:\n overrides?.noMatchesLabel?.trim() || i18n.t(\"richTextAt.noMatches\"),\n removeReferenceActionLabel:\n removeDecorationAriaLabel?.trim() ||\n overrides?.removeReferenceActionLabel?.trim() ||\n i18n.t(\"richTextAt.removeReferenceActionLabel\")\n };\n}\n\nexport const defaultRichTextTriggerText = resolveRichTextTriggerText();\n","import type { JSX, MouseEvent } from \"react\";\nimport { FileIcon, FolderFilledIcon } from \"@tutti-os/ui-system/icons\";\n\ntype RichTextTriggerMenuItemProps = {\n iconUrl?: string;\n label: string;\n selected: boolean;\n subtitle?: string;\n workspaceReferenceFileKind?: \"file\" | \"folder\";\n onSelect: () => void;\n};\n\nexport function RichTextTriggerMenuItem({\n iconUrl,\n label,\n selected,\n subtitle,\n workspaceReferenceFileKind,\n onSelect\n}: RichTextTriggerMenuItemProps): JSX.Element {\n return (\n <button\n aria-selected={selected}\n className={[\n \"flex w-full cursor-pointer items-center gap-2 rounded-md border-0 bg-transparent px-2.5 py-2 text-left text-[var(--text-primary)] outline-0 transition-colors duration-100\",\n selected ? \"bg-[var(--transparency-block)]\" : \"\",\n \"hover:bg-[var(--transparency-block)]\"\n ].join(\" \")}\n type=\"button\"\n onMouseDown={(event: MouseEvent<HTMLButtonElement>) => {\n event.preventDefault();\n onSelect();\n }}\n >\n <RichTextTriggerMenuIcon\n iconUrl={iconUrl}\n workspaceReferenceFileKind={workspaceReferenceFileKind}\n />\n <span className=\"flex min-w-0 flex-auto flex-col items-start gap-0.5\">\n <span className=\"w-full overflow-hidden text-ellipsis whitespace-nowrap text-[13px] leading-5 font-semibold\">\n {label}\n </span>\n {subtitle ? (\n <span className=\"w-full overflow-hidden text-ellipsis whitespace-nowrap text-[11px] leading-4 text-[var(--text-secondary)]\">\n {subtitle}\n </span>\n ) : null}\n </span>\n </button>\n );\n}\n\nfunction RichTextTriggerMenuIcon({\n iconUrl,\n workspaceReferenceFileKind\n}: {\n iconUrl?: string;\n workspaceReferenceFileKind?: \"file\" | \"folder\";\n}): JSX.Element {\n const normalizedIconUrl = iconUrl?.trim() ?? \"\";\n\n if (workspaceReferenceFileKind) {\n const Icon =\n workspaceReferenceFileKind === \"folder\" ? FolderFilledIcon : FileIcon;\n return (\n <span\n aria-hidden=\"true\"\n className=\"inline-grid size-4 flex-none place-items-center text-[var(--folder)]\"\n data-rich-text-trigger-icon=\"true\"\n >\n <Icon className=\"size-4\" />\n </span>\n );\n }\n\n return (\n <span\n aria-hidden=\"true\"\n className=\"inline-grid size-4 flex-none place-items-center overflow-hidden rounded bg-[var(--bg-block,var(--transparency-block))]\"\n data-rich-text-trigger-icon=\"true\"\n >\n {normalizedIconUrl ? (\n <img\n alt=\"\"\n className=\"block size-full object-cover object-center\"\n decoding=\"async\"\n draggable={false}\n loading=\"lazy\"\n src={normalizedIconUrl}\n />\n ) : (\n <span className=\"block size-3 rounded-[3px] bg-[var(--transparency-block)]\" />\n )}\n </span>\n );\n}\n","import { mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport { mentionReferenceNodeName } from \"./names.ts\";\nimport { MentionReferenceNodeView } from \"./MentionReferenceNodeView.tsx\";\n\nexport interface MentionReferenceAttrs {\n entityId: string;\n label: string;\n presentation?: Readonly<Record<string, string>>;\n providerId: string;\n scope?: Readonly<Record<string, string>>;\n trigger: \"@\";\n}\n\nexport const MentionReference = Node.create({\n name: mentionReferenceNodeName,\n group: \"inline\",\n inline: true,\n atom: true,\n selectable: true,\n\n addAttributes() {\n return {\n entityId: {\n default: \"\"\n },\n label: {\n default: \"\"\n },\n presentation: {\n default: null\n },\n providerId: {\n default: \"\"\n },\n scope: {\n default: null\n },\n trigger: {\n default: \"@\"\n }\n };\n },\n\n parseHTML() {\n return [{ tag: \"span[data-rich-text-mention-reference]\" }];\n },\n\n renderHTML({ HTMLAttributes }) {\n const label =\n typeof HTMLAttributes.label === \"string\" ? HTMLAttributes.label : \"\";\n const displayLabel = label.trim().replace(/^@+/, \"\").trim();\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-rich-text-mention-reference\": \"true\",\n class:\n \"inline-flex max-w-full items-center overflow-hidden rounded-md bg-transparency-block px-1.5 py-0.5 align-baseline text-[13px] font-medium text-[var(--text-primary)]\"\n }),\n displayLabel ? `@${displayLabel}` : \"\"\n ];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(MentionReferenceNodeView, {\n as: \"span\",\n className: \"inline-flex max-w-full align-baseline\"\n });\n }\n});\n","import type { JSX } from \"react\";\nimport { NodeViewWrapper, type NodeViewProps } from \"@tiptap/react\";\nimport {\n MentionPill,\n type MentionPillKind\n} from \"@tutti-os/ui-system/components\";\n\nconst richTextMentionReferencePillClassName = \"max-w-[16rem]\";\n\nfunction readStringAttr(value: unknown): string {\n return typeof value === \"string\" ? value.trim() : \"\";\n}\n\nfunction readMentionPresentationUrl(presentation: unknown): string | null {\n if (!presentation || typeof presentation !== \"object\") {\n return null;\n }\n const value =\n (presentation as { iconUrl?: unknown; thumbnailUrl?: unknown }).iconUrl ??\n (presentation as { thumbnailUrl?: unknown }).thumbnailUrl;\n if (typeof value !== \"string\") {\n return null;\n }\n const trimmed = value.trim();\n return trimmed || null;\n}\n\n// 句柄类 mention(如 workspace-reference 项目引用)的图标随 href 的 scope 编码,\n// markdown 带不了 presentation,故回退读 scope.icon,使 chip 与 agent 一样显示来源图标。\nfunction readMentionScopeValue(scope: unknown, key: string): string {\n if (!scope || typeof scope !== \"object\") {\n return \"\";\n }\n return readStringAttr((scope as Record<string, unknown>)[key]);\n}\n\n// providerId(+ workspace-reference 的 source)映射到设计系统 MentionPill 的 kind,\n// 让颜色/图标与 agent GUI 的 mention chip 完全一致。\nfunction resolveMentionPillKind(\n providerId: string,\n scope: unknown\n): MentionPillKind {\n const id = providerId.trim();\n if (id === \"agent-session\" || id === \"session\") {\n return \"session\";\n }\n if (id === \"workspace-app\") {\n return \"app\";\n }\n if (id === \"workspace-issue\") {\n return \"issue\";\n }\n if (id === \"workspace-reference\") {\n return readMentionScopeValue(scope, \"source\") === \"task\" ? \"issue\" : \"app\";\n }\n if (id === \"file\") {\n return \"file\";\n }\n return \"issue\";\n}\n\nexport function MentionReferenceNodeView({\n node,\n selected\n}: NodeViewProps): JSX.Element {\n const label =\n typeof node.attrs.label === \"string\"\n ? node.attrs.label.trim().replace(/^@+/, \"\").trim()\n : \"\";\n const iconUrl =\n readMentionPresentationUrl(node.attrs.presentation) ||\n readMentionScopeValue(node.attrs.scope, \"icon\");\n const kind = resolveMentionPillKind(\n readStringAttr(node.attrs.providerId),\n node.attrs.scope\n );\n\n return (\n <NodeViewWrapper\n as=\"span\"\n className={`inline-flex max-w-full align-baseline${\n selected ? \" is-selected\" : \"\"\n }`}\n contentEditable={false}\n data-rich-text-mention-reference=\"true\"\n >\n <MentionPill\n className={richTextMentionReferencePillClassName}\n iconUrl={iconUrl || undefined}\n kind={kind}\n label={label}\n removable={false}\n />\n </NodeViewWrapper>\n );\n}\n","import { mergeAttributes, Node } from \"@tiptap/core\";\nimport { ReactNodeViewRenderer } from \"@tiptap/react\";\nimport { workspaceReferenceNodeName } from \"./names.ts\";\nimport { WorkspaceReferenceNodeView } from \"./WorkspaceReferenceNodeView.tsx\";\nimport { getWorkspaceReferencePresentation } from \"./workspaceReferencePresentation.ts\";\nimport { defaultRichTextTriggerText } from \"../editor/richTextTriggerText.ts\";\n\nexport interface WorkspaceReferenceAttrs {\n kind: \"file\" | \"folder\";\n label: string;\n path: string;\n}\n\nexport const WorkspaceReference = Node.create({\n name: workspaceReferenceNodeName,\n addOptions() {\n return {\n removeActionAriaLabel:\n defaultRichTextTriggerText.removeReferenceActionLabel\n };\n },\n group: \"inline\",\n inline: true,\n atom: true,\n selectable: true,\n\n addAttributes() {\n return {\n kind: {\n default: \"file\"\n },\n label: {\n default: \"\"\n },\n path: {\n default: \"\"\n }\n } satisfies Record<keyof WorkspaceReferenceAttrs, { default: string }>;\n },\n\n parseHTML() {\n return [{ tag: \"span[data-rich-text-workspace-reference]\" }];\n },\n\n renderHTML({ HTMLAttributes }) {\n const kind = HTMLAttributes.kind === \"folder\" ? \"folder\" : \"file\";\n const label =\n typeof HTMLAttributes.label === \"string\" ? HTMLAttributes.label : \"\";\n const path =\n typeof HTMLAttributes.path === \"string\" ? HTMLAttributes.path : \"\";\n const presentation = getWorkspaceReferencePresentation(label, path);\n const referenceColorClassName =\n kind === \"folder\"\n ? \"text-[var(--rich-text-folder)]\"\n : \"text-[var(--rich-text-mention-file)]\";\n\n return [\n \"span\",\n mergeAttributes(HTMLAttributes, {\n \"data-rich-text-workspace-reference\": \"true\",\n \"data-rich-text-workspace-kind\": kind,\n \"data-agent-file-mention\": \"true\",\n \"data-agent-mention-kind\": \"file\",\n \"data-slot\": \"mention-pill\",\n title: presentation.fullPath,\n class: [\n \"group relative top-[3px] inline-flex max-w-full cursor-default items-center gap-1.5 overflow-hidden rounded-[4px] border border-transparent bg-transparent px-1.5 py-0.5 align-baseline text-[13px] font-medium leading-5 no-underline transition-colors hover:border-transparent hover:bg-[color-mix(in_srgb,currentColor_12%,transparent)]\",\n referenceColorClassName\n ].join(\" \")\n }),\n [\n \"span\",\n {\n \"aria-hidden\": \"true\",\n class: \"grid size-4 shrink-0 place-items-center text-current\"\n },\n kind === \"folder\" ? \"D\" : \"F\"\n ],\n [\n \"span\",\n {\n class: \"min-w-0 max-w-[20rem] truncate text-[13px] font-medium\"\n },\n presentation.displayLabel\n ]\n ];\n },\n\n addNodeView() {\n return ReactNodeViewRenderer(WorkspaceReferenceNodeView);\n }\n});\n","import { useEffect, useState, type JSX, type PointerEvent } from \"react\";\nimport { NodeViewWrapper, type NodeViewProps } from \"@tiptap/react\";\nimport {\n MentionPill,\n Tooltip,\n TooltipContent,\n TooltipTrigger\n} from \"@tutti-os/ui-system/components\";\nimport { getWorkspaceReferencePresentation } from \"./workspaceReferencePresentation.ts\";\nimport { defaultRichTextTriggerText } from \"../editor/richTextTriggerText.ts\";\n\nconst richTextWorkspaceReferencePillClassName = \"max-w-[18rem]\";\n\nexport function WorkspaceReferenceNodeView({\n deleteNode,\n editor,\n extension,\n node,\n selected\n}: NodeViewProps): JSX.Element {\n const [isEditable, setIsEditable] = useState(editor.isEditable);\n const attrs = node.attrs as {\n kind?: string;\n label?: string;\n path?: string;\n };\n const extensionOptions = extension.options as {\n removeActionAriaLabel?: string;\n };\n const kind = attrs.kind === \"folder\" ? \"folder\" : \"file\";\n const label = typeof attrs.label === \"string\" ? attrs.label : \"\";\n const path = typeof attrs.path === \"string\" ? attrs.path : \"\";\n const presentation = getWorkspaceReferencePresentation(label, path);\n const removeActionAriaLabel =\n typeof extensionOptions.removeActionAriaLabel === \"string\"\n ? extensionOptions.removeActionAriaLabel\n : defaultRichTextTriggerText.removeReferenceActionLabel;\n\n useEffect(() => {\n const syncEditable = () => {\n setIsEditable(editor.isEditable);\n };\n\n syncEditable();\n editor.on(\"transaction\", syncEditable);\n editor.on(\"update\", syncEditable);\n return () => {\n editor.off(\"transaction\", syncEditable);\n editor.off(\"update\", syncEditable);\n };\n }, [editor]);\n\n const handleRemove = (event: PointerEvent<HTMLButtonElement>) => {\n event.preventDefault();\n event.stopPropagation();\n if (!editor.isEditable) {\n return;\n }\n deleteNode();\n };\n\n return (\n <NodeViewWrapper\n as=\"span\"\n className={`inline-flex max-w-full align-baseline ${\n selected ? \"is-selected\" : \"\"\n }`}\n contentEditable={false}\n data-rich-text-workspace-reference=\"true\"\n >\n <Tooltip>\n <TooltipTrigger asChild>\n <MentionPill\n className={richTextWorkspaceReferencePillClassName}\n fileKind={kind}\n kind=\"file\"\n label={presentation.displayLabel}\n removable={isEditable}\n removeButtonProps={\n isEditable\n ? {\n \"aria-label\": removeActionAriaLabel,\n onPointerDown: handleRemove,\n tabIndex: -1\n }\n : undefined\n }\n />\n </TooltipTrigger>\n <TooltipContent\n className=\"max-w-md whitespace-normal break-all\"\n sideOffset={8}\n >\n {presentation.fullPath}\n </TooltipContent>\n </Tooltip>\n </NodeViewWrapper>\n );\n}\n","export interface WorkspaceReferencePresentation {\n displayLabel: string;\n fullPath: string;\n}\n\nexport function getWorkspaceReferencePresentation(\n label: string,\n path: string\n): WorkspaceReferencePresentation {\n const displayLabel = normalizeReferenceLabel(label, path);\n const fullPath = normalizeFullPath(path);\n\n return {\n displayLabel,\n fullPath\n };\n}\n\nfunction normalizeReferenceLabel(label: string, path: string): string {\n const trimmedLabel = label.trim();\n\n if (trimmedLabel !== \"\") {\n return trimmedLabel;\n }\n\n return getPathBasename(path) || path.trim();\n}\n\nfunction normalizeFullPath(path: string): string {\n return trimTrailingSeparators(path.trim());\n}\n\nfunction getPathBasename(path: string): string {\n const normalizedPath = trimTrailingSeparators(path.trim());\n\n if (normalizedPath === \"\" || isPathRoot(normalizedPath)) {\n return normalizedPath;\n }\n\n const segments = normalizedPath.split(/[\\\\/]+/).filter(Boolean);\n\n return segments.at(-1) ?? \"\";\n}\n\nfunction trimTrailingSeparators(path: string): string {\n if (path === \"\") {\n return \"\";\n }\n\n if (isPathRoot(path)) {\n return path;\n }\n\n return path.replace(/[\\\\/]+$/, \"\");\n}\n\nfunction isPathRoot(path: string): boolean {\n return (\n path === \"/\" ||\n path === \"\\\\\" ||\n path === \"//\" ||\n path === \"\\\\\\\\\" ||\n /^[A-Za-z]:[\\\\/]?$/.test(path)\n );\n}\n","import {\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type PointerEvent,\n type ReactNode,\n type JSX,\n type KeyboardEvent\n} from \"react\";\nimport { ViewportMenuSurface } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport { createRichTextTriggerRegistry } from \"../plugins/triggerRegistry.ts\";\nimport { renderRichTextTriggerInsertResult } from \"../plugins/trigger.ts\";\nimport type {\n RichTextTriggerProvider,\n RichTextTriggerQueryMatch\n} from \"../types/trigger.ts\";\nimport {\n findRichTextTriggerQuery,\n queryRichTextTriggerMatches\n} from \"./richTextTriggerQuery.ts\";\nimport { isRichTextImeComposing } from \"./richTextIme.ts\";\nimport {\n buildRichTextTextareaDecorationSegments,\n getTextareaPresentationStyle,\n hasRichTextTextareaDecorations,\n resolveRichTextTextareaSelectionBoundary\n} from \"./richTextTextareaDecorationModel.ts\";\nimport {\n resolveRichTextTriggerText,\n type RichTextTriggerTextOverrides\n} from \"./richTextTriggerText.ts\";\nimport { RichTextTriggerMenuItem } from \"./RichTextTriggerMenuItem.tsx\";\nimport type { RichTextI18nRuntime } from \"../i18n/richTextI18n.ts\";\nimport { RichTextTextareaDecoratedContent } from \"./richTextTextareaDecorations.tsx\";\nimport { getTextareaCaretViewportPoint } from \"./richTextTextareaCaret.ts\";\nimport type { CSSProperties } from \"react\";\n\nexport interface RichTextTriggerTextareaProps {\n value: string;\n onChange: (value: string) => void;\n triggerProviders?: readonly RichTextTriggerProvider[];\n placeholder?: string;\n disabled?: boolean;\n className?: string;\n textareaClassName?: string;\n rows?: number;\n minQueryLength?: number;\n maxResults?: number;\n removeDecorationAriaLabel?: string;\n i18n?: RichTextI18nRuntime;\n textOverrides?: RichTextTriggerTextOverrides;\n overlay?: ReactNode;\n}\n\nexport function RichTextTriggerTextarea({\n value,\n onChange,\n triggerProviders = [],\n placeholder,\n disabled = false,\n className,\n textareaClassName,\n rows,\n minQueryLength = 0,\n maxResults = 8,\n removeDecorationAriaLabel,\n i18n,\n textOverrides,\n overlay\n}: RichTextTriggerTextareaProps): JSX.Element {\n const menuOffset = 6;\n const text = resolveRichTextTriggerText(\n textOverrides,\n removeDecorationAriaLabel,\n i18n\n );\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n const [selectionStart, setSelectionStart] = useState(0);\n const [matches, setMatches] = useState<readonly RichTextTriggerQueryMatch[]>(\n []\n );\n const [activeIndex, setActiveIndex] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n const [menuPoint, setMenuPoint] = useState<{ x: number; y: number } | null>(\n null\n );\n const [scrollPosition, setScrollPosition] = useState({ left: 0, top: 0 });\n const [textareaPresentationStyle, setTextareaPresentationStyle] =\n useState<CSSProperties | null>(null);\n const pendingSelectionRef = useRef<number | null>(null);\n const registry = useMemo(\n () => createRichTextTriggerRegistry(triggerProviders),\n [triggerProviders]\n );\n const activeTriggerConfigs = useMemo(\n () => registry.listTriggerConfigs(),\n [registry]\n );\n const decorationSegments = useMemo(\n () => buildRichTextTextareaDecorationSegments(value),\n [value]\n );\n const hasDecorations = hasRichTextTextareaDecorations(decorationSegments);\n const query = useMemo(\n () =>\n isFocused\n ? findRichTextTriggerQuery(value, selectionStart, activeTriggerConfigs)\n : null,\n [activeTriggerConfigs, isFocused, selectionStart, value]\n );\n const shouldQuery =\n query !== null &&\n query.keyword.length >= minQueryLength &&\n activeTriggerConfigs.length > 0;\n const isMenuOpen =\n isFocused && shouldQuery && (isLoading || matches.length > 0);\n\n useEffect(() => {\n const nextSelection = pendingSelectionRef.current;\n if (nextSelection === null || !textareaRef.current) {\n return;\n }\n textareaRef.current.setSelectionRange(nextSelection, nextSelection);\n pendingSelectionRef.current = null;\n }, [value]);\n\n useEffect(() => {\n if (!shouldQuery || !query) {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n return;\n }\n\n const abortController = new AbortController();\n setIsLoading(true);\n\n void queryRichTextTriggerMatches(registry, {\n abortSignal: abortController.signal,\n keyword: query.keyword,\n maxResults,\n trigger: query.trigger,\n context: {\n documentText: value,\n blockText: value\n }\n })\n .then((nextMatches) => {\n if (abortController.signal.aborted) {\n return;\n }\n setMatches(nextMatches);\n setActiveIndex((current) =>\n nextMatches.length === 0\n ? 0\n : Math.max(0, Math.min(current, nextMatches.length - 1))\n );\n })\n .finally(() => {\n if (!abortController.signal.aborted) {\n setIsLoading(false);\n }\n });\n\n return () => {\n abortController.abort();\n };\n }, [maxResults, query, registry, shouldQuery, value]);\n\n useLayoutEffect(() => {\n if (!textareaRef.current || !hasDecorations) {\n setTextareaPresentationStyle(null);\n return;\n }\n\n const textarea = textareaRef.current;\n setTextareaPresentationStyle(getTextareaPresentationStyle(textarea));\n setScrollPosition({\n left: textarea.scrollLeft,\n top: textarea.scrollTop\n });\n }, [hasDecorations, textareaClassName, value]);\n\n useLayoutEffect(() => {\n if (!isMenuOpen || !query || !textareaRef.current) {\n setMenuPoint(null);\n return;\n }\n\n const caretPoint = getTextareaCaretViewportPoint(\n textareaRef.current,\n query.to\n );\n const textareaRect = textareaRef.current.getBoundingClientRect();\n\n if (!caretPoint) {\n setMenuPoint({\n x: textareaRect.left + 12,\n y: textareaRect.bottom + menuOffset\n });\n return;\n }\n\n setMenuPoint({\n x: caretPoint.x,\n y: caretPoint.y + caretPoint.lineHeight + menuOffset\n });\n }, [isMenuOpen, menuOffset, query, selectionStart, value]);\n\n useEffect(() => {\n if (!isMenuOpen || !query || !textareaRef.current) {\n return;\n }\n\n const textarea = textareaRef.current;\n const updateMenuPoint = () => {\n const caretPoint = getTextareaCaretViewportPoint(textarea, query.to);\n const textareaRect = textarea.getBoundingClientRect();\n\n setMenuPoint(\n caretPoint\n ? {\n x: caretPoint.x,\n y: caretPoint.y + caretPoint.lineHeight + menuOffset\n }\n : {\n x: textareaRect.left + 12,\n y: textareaRect.bottom + menuOffset\n }\n );\n };\n\n const resizeObserver =\n typeof ResizeObserver === \"undefined\"\n ? null\n : new ResizeObserver(() => {\n updateMenuPoint();\n });\n resizeObserver?.observe(textarea);\n textarea.addEventListener(\"scroll\", updateMenuPoint, { passive: true });\n window.addEventListener(\"resize\", updateMenuPoint);\n window.addEventListener(\"scroll\", updateMenuPoint, {\n capture: true,\n passive: true\n });\n\n return () => {\n resizeObserver?.disconnect();\n textarea.removeEventListener(\"scroll\", updateMenuPoint);\n window.removeEventListener(\"resize\", updateMenuPoint);\n window.removeEventListener(\"scroll\", updateMenuPoint, true);\n };\n }, [isMenuOpen, menuOffset, query]);\n\n const closeMenu = () => {\n setMatches([]);\n setActiveIndex(0);\n setIsLoading(false);\n setMenuPoint(null);\n };\n\n const setSelection = (nextSelection: number) => {\n pendingSelectionRef.current = nextSelection;\n setSelectionStart(nextSelection);\n if (textareaRef.current) {\n textareaRef.current.focus();\n textareaRef.current.setSelectionRange(nextSelection, nextSelection);\n pendingSelectionRef.current = null;\n }\n };\n\n const handleClickDecoration = (\n segment: Extract<(typeof decorationSegments)[number], { type: \"link\" }>,\n event: PointerEvent<HTMLSpanElement>\n ) => {\n event.preventDefault();\n const bounds = event.currentTarget.getBoundingClientRect();\n const nextSelection =\n event.clientX < bounds.left + bounds.width / 2\n ? segment.from\n : segment.to;\n setSelection(nextSelection);\n };\n\n const handleRemoveDecoration = (\n segment: Extract<(typeof decorationSegments)[number], { type: \"link\" }>\n ) => {\n const nextValue = `${value.slice(0, segment.from)}${value.slice(segment.to)}`;\n const nextSelection = Math.min(segment.from, nextValue.length);\n pendingSelectionRef.current = nextSelection;\n onChange(nextValue);\n setSelectionStart(nextSelection);\n window.requestAnimationFrame(() => {\n if (!textareaRef.current) {\n return;\n }\n textareaRef.current.focus();\n textareaRef.current.setSelectionRange(nextSelection, nextSelection);\n pendingSelectionRef.current = null;\n });\n };\n\n const applyMatch = (match: RichTextTriggerQueryMatch) => {\n const currentQuery = findRichTextTriggerQuery(\n value,\n textareaRef.current?.selectionStart ?? selectionStart,\n activeTriggerConfigs\n );\n if (!currentQuery) {\n return;\n }\n const insertedValue = renderRichTextTriggerInsertResult(\n match.providerId,\n match.insertResult\n );\n const nextValue = `${value.slice(0, currentQuery.from)}${insertedValue}${value.slice(currentQuery.to)}`;\n const nextSelection = currentQuery.from + insertedValue.length;\n pendingSelectionRef.current = nextSelection;\n onChange(nextValue);\n closeMenu();\n };\n\n const handleKeyDown = (event: KeyboardEvent<HTMLTextAreaElement>) => {\n if (isRichTextImeComposing(event)) {\n return;\n }\n\n if (matches.length === 0) {\n return;\n }\n\n if (event.key === \"ArrowDown\") {\n event.preventDefault();\n setActiveIndex((current) => (current + 1) % matches.length);\n return;\n }\n\n if (event.key === \"ArrowUp\") {\n event.preventDefault();\n setActiveIndex(\n (current) => (current - 1 + matches.length) % matches.length\n );\n return;\n }\n\n if (event.key === \"Enter\" || event.key === \"Tab\") {\n const match = matches[activeIndex];\n if (!match) {\n return;\n }\n event.preventDefault();\n applyMatch(match);\n return;\n }\n\n if (event.key === \"Escape\") {\n event.preventDefault();\n closeMenu();\n }\n };\n\n return (\n <div className={cn(\"relative min-w-0 w-full\", className)}>\n {hasDecorations && textareaPresentationStyle ? (\n <RichTextTextareaDecoratedContent\n onClickSegment={handleClickDecoration}\n onRemoveSegment={handleRemoveDecoration}\n removeActionAriaLabel={text.removeReferenceActionLabel}\n scrollLeft={scrollPosition.left}\n scrollTop={scrollPosition.top}\n segments={decorationSegments}\n textareaStyle={textareaPresentationStyle}\n />\n ) : null}\n <textarea\n ref={textareaRef}\n className={textareaClassName}\n disabled={disabled}\n placeholder={placeholder}\n rows={rows}\n style={\n hasDecorations\n ? {\n WebkitTextFillColor: \"transparent\",\n caretColor: \"var(--text-primary)\",\n color: \"transparent\",\n position: \"relative\",\n zIndex: 0\n }\n : undefined\n }\n value={value}\n onBlur={() => {\n window.setTimeout(() => {\n setIsFocused(false);\n closeMenu();\n }, 100);\n }}\n onChange={(event) => {\n const rawSelectionStart = event.target.selectionStart ?? 0;\n const nextSelection =\n resolveRichTextTextareaSelectionBoundary(\n decorationSegments,\n rawSelectionStart\n ) ?? rawSelectionStart;\n if (nextSelection !== rawSelectionStart) {\n event.target.setSelectionRange(nextSelection, nextSelection);\n }\n setSelectionStart(nextSelection);\n onChange(event.target.value);\n }}\n onFocus={(event) => {\n setIsFocused(true);\n const rawSelectionStart = event.target.selectionStart ?? 0;\n const nextSelection =\n resolveRichTextTextareaSelectionBoundary(\n decorationSegments,\n rawSelectionStart\n ) ?? rawSelectionStart;\n if (nextSelection !== rawSelectionStart) {\n event.target.setSelectionRange(nextSelection, nextSelection);\n }\n setSelectionStart(nextSelection);\n setScrollPosition({\n left: event.target.scrollLeft,\n top: event.target.scrollTop\n });\n }}\n onKeyDown={handleKeyDown}\n onScroll={(event) => {\n setScrollPosition({\n left: event.currentTarget.scrollLeft,\n top: event.currentTarget.scrollTop\n });\n }}\n onSelect={(event) => {\n const rawSelectionStart = event.currentTarget.selectionStart ?? 0;\n const nextSelection =\n resolveRichTextTextareaSelectionBoundary(\n decorationSegments,\n rawSelectionStart\n ) ?? rawSelectionStart;\n if (nextSelection !== rawSelectionStart) {\n event.currentTarget.setSelectionRange(nextSelection, nextSelection);\n }\n setSelectionStart(nextSelection);\n }}\n />\n {overlay}\n {isMenuOpen && menuPoint ? (\n <ViewportMenuSurface\n open\n className=\"tutti-rich-text-at-menu max-h-64 w-[min(28rem,calc(100vw-24px))] overflow-y-auto p-1\"\n dismissIgnoreRefs={[textareaRef]}\n placement={{\n type: \"point\",\n point: menuPoint,\n alignX: \"start\",\n alignY: \"start\",\n estimatedSize: {\n width: 360,\n height: 256\n }\n }}\n >\n {matches.length > 0 ? (\n matches.map((match, index) => (\n <RichTextTriggerMenuItem\n key={`${match.providerId}:${match.key}`}\n label={match.label}\n selected={index === activeIndex}\n subtitle={match.subtitle}\n iconUrl={match.iconUrl}\n onSelect={() => applyMatch(match)}\n />\n ))\n ) : (\n <div className=\"px-3 py-2 text-[11px] leading-4 text-[var(--text-secondary)]\">\n {isLoading ? text.loadingLabel : text.noMatchesLabel}\n </div>\n )}\n </ViewportMenuSurface>\n ) : null}\n </div>\n );\n}\n","import type { CSSProperties } from \"react\";\nimport { isRichTextMentionHref } from \"../core/richTextDocument.ts\";\nimport { findRichTextMarkdownLinks } from \"../core/richTextMarkdownLinks.ts\";\n\nconst EXTERNAL_LINK_PREFIX = /^(?:[a-z]+:)?\\/\\//i;\n\nconst TEXTAREA_PRESENTATION_STYLE_PROPERTIES = [\n { styleName: \"paddingTop\", cssName: \"padding-top\" },\n { styleName: \"paddingRight\", cssName: \"padding-right\" },\n { styleName: \"paddingBottom\", cssName: \"padding-bottom\" },\n { styleName: \"paddingLeft\", cssName: \"padding-left\" },\n { styleName: \"fontFamily\", cssName: \"font-family\" },\n { styleName: \"fontFeatureSettings\", cssName: \"font-feature-settings\" },\n { styleName: \"fontKerning\", cssName: \"font-kerning\" },\n { styleName: \"fontOpticalSizing\", cssName: \"font-optical-sizing\" },\n { styleName: \"fontSize\", cssName: \"font-size\" },\n { styleName: \"fontStretch\", cssName: \"font-stretch\" },\n { styleName: \"fontStyle\", cssName: \"font-style\" },\n { styleName: \"fontVariant\", cssName: \"font-variant\" },\n { styleName: \"fontVariationSettings\", cssName: \"font-variation-settings\" },\n { styleName: \"fontWeight\", cssName: \"font-weight\" },\n { styleName: \"letterSpacing\", cssName: \"letter-spacing\" },\n { styleName: \"lineHeight\", cssName: \"line-height\" },\n { styleName: \"textAlign\", cssName: \"text-align\" },\n { styleName: \"textIndent\", cssName: \"text-indent\" },\n { styleName: \"textTransform\", cssName: \"text-transform\" },\n { styleName: \"tabSize\", cssName: \"tab-size\" },\n { styleName: \"MozTabSize\", cssName: \"-moz-tab-size\" }\n] as const satisfies readonly {\n styleName: keyof CSSProperties;\n cssName: string;\n}[];\n\ntype RichTextTextareaTextDecorationSegment = {\n type: \"text\";\n text: string;\n from: number;\n to: number;\n};\n\ntype RichTextTextareaLinkDecorationSegment = {\n type: \"link\";\n text: string;\n from: number;\n to: number;\n label: string;\n href: string;\n kind: \"file\" | \"folder\";\n};\n\nexport type RichTextTextareaDecorationSegment =\n | RichTextTextareaTextDecorationSegment\n | RichTextTextareaLinkDecorationSegment;\n\nfunction isDecoratableMarkdownHref(href: string): boolean {\n const trimmedHref = href.trim();\n if (!trimmedHref) {\n return false;\n }\n if (\n EXTERNAL_LINK_PREFIX.test(trimmedHref) ||\n isRichTextMentionHref(trimmedHref)\n ) {\n return false;\n }\n return true;\n}\n\nexport function buildRichTextTextareaDecorationSegments(\n value: string\n): RichTextTextareaDecorationSegment[] {\n const segments: RichTextTextareaDecorationSegment[] = [];\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(value)) {\n const label = match.label.trim();\n const href = match.href.trim();\n const { index, source, to } = match;\n\n if (index > cursor) {\n segments.push({\n type: \"text\",\n text: value.slice(cursor, index),\n from: cursor,\n to: index\n });\n }\n\n if (label && href && isDecoratableMarkdownHref(href)) {\n segments.push({\n type: \"link\",\n text: source,\n from: index,\n to,\n label,\n href,\n kind: href.endsWith(\"/\") ? \"folder\" : \"file\"\n });\n } else {\n segments.push({\n type: \"text\",\n text: source,\n from: index,\n to\n });\n }\n\n cursor = to;\n }\n\n if (cursor < value.length) {\n segments.push({\n type: \"text\",\n text: value.slice(cursor),\n from: cursor,\n to: value.length\n });\n }\n\n return segments;\n}\n\nexport function hasRichTextTextareaDecorations(\n segments: readonly RichTextTextareaDecorationSegment[]\n): boolean {\n return segments.some((segment) => segment.type === \"link\");\n}\n\nexport function resolveRichTextTextareaSelectionBoundary(\n segments: readonly RichTextTextareaDecorationSegment[],\n selectionStart: number\n): number | null {\n for (const segment of segments) {\n if (segment.type !== \"link\") {\n continue;\n }\n if (selectionStart <= segment.from || selectionStart >= segment.to) {\n continue;\n }\n const midpoint = segment.from + (segment.to - segment.from) / 2;\n return selectionStart < midpoint ? segment.from : segment.to;\n }\n return null;\n}\n\nfunction setTextareaPresentationStyleValue<K extends keyof CSSProperties>(\n styleRecord: CSSProperties,\n styleName: K,\n value: string\n): void {\n styleRecord[styleName] = value as CSSProperties[K];\n}\n\nexport function getTextareaPresentationStyle(\n textarea: HTMLTextAreaElement\n): CSSProperties {\n const computedStyle = window.getComputedStyle(textarea);\n const styleRecord: CSSProperties = {\n whiteSpace: \"pre-wrap\"\n };\n\n setTextareaPresentationStyleValue(\n styleRecord,\n \"wordBreak\",\n computedStyle.wordBreak\n );\n setTextareaPresentationStyleValue(\n styleRecord,\n \"overflowWrap\",\n computedStyle.overflowWrap\n );\n\n for (const { styleName, cssName } of TEXTAREA_PRESENTATION_STYLE_PROPERTIES) {\n setTextareaPresentationStyleValue(\n styleRecord,\n styleName,\n computedStyle.getPropertyValue(cssName)\n );\n }\n\n return styleRecord;\n}\n","import type { CSSProperties, JSX, PointerEvent } from \"react\";\nimport { MentionPill } from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport type { RichTextTextareaDecorationSegment } from \"./richTextTextareaDecorationModel.ts\";\n\nconst richTextWorkspaceReferencePillClassName = \"max-w-[18rem]\";\n\nexport function RichTextTextareaDecoratedContent({\n onClickSegment,\n onRemoveSegment,\n removeActionAriaLabel,\n scrollLeft,\n scrollTop,\n segments,\n textareaStyle\n}: {\n onClickSegment: (\n segment: Extract<RichTextTextareaDecorationSegment, { type: \"link\" }>,\n event: PointerEvent<HTMLSpanElement>\n ) => void;\n onRemoveSegment: (\n segment: Extract<RichTextTextareaDecorationSegment, { type: \"link\" }>\n ) => void;\n removeActionAriaLabel?: string;\n scrollLeft: number;\n scrollTop: number;\n segments: readonly RichTextTextareaDecorationSegment[];\n textareaStyle: CSSProperties;\n}): JSX.Element {\n return (\n <div className=\"pointer-events-none absolute inset-0 z-10 overflow-hidden\">\n <div\n className=\"min-h-full min-w-full\"\n style={{\n ...textareaStyle,\n transform: `translate(${-scrollLeft}px, ${-scrollTop}px)`\n }}\n >\n {segments.map((segment, index) => {\n if (segment.type === \"text\") {\n return <span key={index}>{segment.text}</span>;\n }\n\n return (\n <span key={index} className=\"relative\">\n <span aria-hidden=\"true\" className=\"text-transparent\">\n {segment.text}\n </span>\n <MentionPill\n className={cn(\n \"pointer-events-auto absolute inset-y-0 left-0 pr-1 pl-1.5\",\n richTextWorkspaceReferencePillClassName\n )}\n fileKind={segment.kind}\n kind=\"file\"\n label={segment.label}\n removeButtonProps={{\n \"aria-label\": removeActionAriaLabel,\n onPointerDown: (event) => {\n event.preventDefault();\n event.stopPropagation();\n onRemoveSegment(segment);\n }\n }}\n summary={\n <span\n className={cn(\n \"min-w-0 truncate text-[11px] text-current opacity-80\",\n segment.kind === \"folder\"\n ? \"max-w-[18rem]\"\n : \"max-w-[20rem]\"\n )}\n >\n {segment.href}\n </span>\n }\n onPointerDown={(event) => {\n onClickSegment(segment, event);\n }}\n />\n </span>\n );\n })}\n </div>\n </div>\n );\n}\n","const TEXTAREA_MIRROR_STYLE_PROPERTIES = [\n \"boxSizing\",\n \"width\",\n \"paddingTop\",\n \"paddingRight\",\n \"paddingBottom\",\n \"paddingLeft\",\n \"borderTopWidth\",\n \"borderRightWidth\",\n \"borderBottomWidth\",\n \"borderLeftWidth\",\n \"borderTopStyle\",\n \"borderRightStyle\",\n \"borderBottomStyle\",\n \"borderLeftStyle\",\n \"borderTopColor\",\n \"borderRightColor\",\n \"borderBottomColor\",\n \"borderLeftColor\",\n \"borderRadius\",\n \"fontFamily\",\n \"fontFeatureSettings\",\n \"fontKerning\",\n \"fontOpticalSizing\",\n \"fontSize\",\n \"fontStretch\",\n \"fontStyle\",\n \"fontVariant\",\n \"fontVariationSettings\",\n \"fontWeight\",\n \"letterSpacing\",\n \"lineHeight\",\n \"textAlign\",\n \"textDecoration\",\n \"textIndent\",\n \"textTransform\",\n \"wordBreak\",\n \"overflowWrap\",\n \"tabSize\",\n \"MozTabSize\"\n] as const;\n\nexport interface TextareaCaretViewportPoint {\n x: number;\n y: number;\n lineHeight: number;\n}\n\nfunction parsePixelValue(value: string | null | undefined): number | null {\n if (!value || value === \"normal\") {\n return null;\n }\n\n const parsedValue = Number.parseFloat(value);\n return Number.isFinite(parsedValue) ? parsedValue : null;\n}\n\nfunction resolveLineHeight(computedStyle: CSSStyleDeclaration): number {\n const explicitLineHeight = parsePixelValue(computedStyle.lineHeight);\n if (explicitLineHeight !== null) {\n return explicitLineHeight;\n }\n\n const fontSize = parsePixelValue(computedStyle.fontSize);\n return fontSize !== null ? fontSize * 1.4 : 20;\n}\n\nexport function getTextareaCaretViewportPoint(\n textarea: HTMLTextAreaElement,\n selectionStart: number\n): TextareaCaretViewportPoint | null {\n if (typeof document === \"undefined\") {\n return null;\n }\n\n const safeSelectionStart = Math.max(\n 0,\n Math.min(selectionStart, textarea.value.length)\n );\n const textareaRect = textarea.getBoundingClientRect();\n const computedStyle = window.getComputedStyle(textarea);\n const mirror = document.createElement(\"div\");\n const marker = document.createElement(\"span\");\n\n mirror.setAttribute(\"aria-hidden\", \"true\");\n mirror.style.position = \"fixed\";\n mirror.style.left = `${textareaRect.left}px`;\n mirror.style.top = `${textareaRect.top}px`;\n mirror.style.visibility = \"hidden\";\n mirror.style.pointerEvents = \"none\";\n mirror.style.overflow = \"hidden\";\n\n for (const propertyName of TEXTAREA_MIRROR_STYLE_PROPERTIES) {\n (mirror.style as CSSStyleDeclaration & Record<string, string>)[\n propertyName\n ] =\n (\n computedStyle as CSSStyleDeclaration &\n Record<string, string | undefined>\n )[propertyName] ?? \"\";\n }\n mirror.style.whiteSpace = \"pre-wrap\";\n mirror.style.wordBreak = computedStyle.wordBreak;\n mirror.style.overflowWrap = computedStyle.overflowWrap;\n\n const preSelectionText = textarea.value.slice(0, safeSelectionStart);\n mirror.textContent = preSelectionText.length > 0 ? preSelectionText : \"\";\n if (preSelectionText.endsWith(\"\\n\")) {\n mirror.append(document.createTextNode(\"\\u200b\"));\n }\n\n marker.textContent = \"\\u200b\";\n mirror.append(marker);\n document.body.append(mirror);\n\n try {\n const markerRect = marker.getBoundingClientRect();\n const lineHeight = resolveLineHeight(computedStyle);\n\n return {\n x: markerRect.left - textarea.scrollLeft,\n y: markerRect.top - textarea.scrollTop,\n lineHeight\n };\n } finally {\n mirror.remove();\n }\n}\n","import type { CSSProperties, JSX, MouseEvent, ReactNode } from \"react\";\nimport {\n getRichTextMentionDisplayText,\n resolveRichTextMentionView\n} from \"../plugins/mention.ts\";\nimport type {\n RichTextMentionAttrs,\n RichTextResolvedMention,\n RichTextResolvedMentionView\n} from \"../types/mention.ts\";\n\nexport interface RichTextMentionReadonlyClickPayload<TResolved = unknown> {\n mention: RichTextMentionAttrs;\n resolved: RichTextResolvedMentionView<TResolved>;\n}\n\nexport interface RichTextMentionReadonlyProps<TResolved = unknown> {\n mention: RichTextMentionAttrs;\n resolved?: RichTextResolvedMention<TResolved> | null;\n className?: string;\n title?: string;\n onClick?: (payload: RichTextMentionReadonlyClickPayload<TResolved>) => void;\n renderLabel?: (\n payload: RichTextMentionReadonlyClickPayload<TResolved>\n ) => ReactNode;\n}\n\nconst baseStyle: CSSProperties = {\n alignItems: \"center\",\n border: \"1px solid transparent\",\n borderRadius: \"999px\",\n display: \"inline-flex\",\n fontSize: \"0.95em\",\n gap: \"0.25rem\",\n lineHeight: 1.4,\n maxWidth: \"100%\",\n padding: \"0.05rem 0.45rem\",\n textDecoration: \"none\",\n verticalAlign: \"baseline\",\n whiteSpace: \"nowrap\"\n};\n\nconst stateStyles: Record<RichTextResolvedMentionView[\"state\"], CSSProperties> =\n {\n active: {\n background:\n \"var(--tutti-rich-text-mention-active-bg, color-mix(in srgb, currentColor 12%, transparent))\",\n color: \"var(--tutti-rich-text-mention-active-fg, inherit)\",\n cursor: \"pointer\"\n },\n missing: {\n background:\n \"var(--tutti-rich-text-mention-missing-bg, color-mix(in srgb, currentColor 6%, transparent))\",\n color:\n \"var(--tutti-rich-text-mention-missing-fg, color-mix(in srgb, currentColor 48%, transparent))\",\n cursor: \"default\",\n textDecoration: \"line-through\"\n },\n disabled: {\n background:\n \"var(--tutti-rich-text-mention-disabled-bg, color-mix(in srgb, currentColor 6%, transparent))\",\n color:\n \"var(--tutti-rich-text-mention-disabled-fg, color-mix(in srgb, currentColor 58%, transparent))\",\n cursor: \"not-allowed\",\n opacity: 0.88\n },\n loading: {\n background:\n \"var(--tutti-rich-text-mention-loading-bg, color-mix(in srgb, currentColor 8%, transparent))\",\n color:\n \"var(--tutti-rich-text-mention-loading-fg, color-mix(in srgb, currentColor 82%, transparent))\",\n cursor: \"progress\",\n opacity: 0.92\n }\n };\n\nfunction joinClassNames(\n ...parts: Array<string | null | undefined | false>\n): string | undefined {\n const value = parts.filter(Boolean).join(\" \").trim();\n return value || undefined;\n}\n\nexport function RichTextMentionReadonly<TResolved = unknown>({\n mention,\n resolved,\n className,\n title,\n onClick,\n renderLabel\n}: RichTextMentionReadonlyProps<TResolved>): JSX.Element {\n const view = resolveRichTextMentionView(mention, resolved);\n const payload: RichTextMentionReadonlyClickPayload<TResolved> = {\n mention,\n resolved: view as RichTextResolvedMentionView<TResolved>\n };\n const label =\n renderLabel?.(payload) ??\n getRichTextMentionDisplayText({\n ...mention,\n label: view.label\n });\n const elementTitle = title ?? view.tooltip;\n const handleClick = (event: MouseEvent<HTMLElement>) => {\n if (!view.interactive) {\n event.preventDefault();\n return;\n }\n onClick?.(payload);\n };\n\n const sharedProps = {\n \"aria-busy\": view.state === \"loading\" || undefined,\n \"aria-disabled\": !view.interactive || undefined,\n className: joinClassNames(\n \"tutti-rich-text-mention\",\n `tutti-rich-text-mention--${view.state}`,\n className\n ),\n \"data-provider-id\": mention.providerId,\n \"data-state\": view.state,\n style: {\n ...baseStyle,\n ...stateStyles[view.state]\n },\n title: elementTitle\n } as const;\n\n if (view.interactive && onClick) {\n return (\n <button\n {...sharedProps}\n onClick={(event) => {\n handleClick(event);\n }}\n style={{\n ...sharedProps.style,\n appearance: \"none\",\n font: \"inherit\"\n }}\n type=\"button\"\n >\n {label}\n </button>\n );\n }\n\n return <span {...sharedProps}>{label}</span>;\n}\n","import type { JSX } from \"react\";\nimport {\n MentionPill,\n Tooltip,\n TooltipContent,\n TooltipTrigger\n} from \"@tutti-os/ui-system/components\";\nimport { cn } from \"@tutti-os/ui-system/utils\";\nimport {\n isRichTextMentionHref,\n normalizeRichTextContent,\n normalizeRichTextLinkHref,\n parseRichTextMentionHref\n} from \"../core/richTextDocument.ts\";\nimport { getWorkspaceReferencePresentation } from \"../extensions/workspaceReferencePresentation.ts\";\nimport { RichTextMentionReadonly } from \"./RichTextMentionReadonly.tsx\";\nimport { buildRichTextReadonlyInlineSegments } from \"./richTextReadonlyContentModel.ts\";\nimport type { RichTextMentionAttrs } from \"../types/mention.ts\";\n\nexport interface RichTextReadonlyWorkspaceReference {\n kind: \"file\" | \"folder\";\n label: string;\n path: string;\n}\n\nexport interface RichTextReadonlyContentProps {\n value: string;\n className?: string;\n paragraphClassName?: string;\n onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>;\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>;\n}\n\nconst externalHrefPattern = /^(?:[a-z]+:)?\\/\\//i;\nconst richTextWorkspaceReferencePillClassName = \"max-w-[18rem]\";\n\nexport function RichTextReadonlyContent({\n value,\n className,\n paragraphClassName,\n onMentionAction,\n onOpenWorkspaceReference\n}: RichTextReadonlyContentProps): JSX.Element | null {\n const normalizedValue = normalizeRichTextContent(value).trim();\n\n if (!normalizedValue) {\n return null;\n }\n\n const paragraphs = normalizedValue\n .split(/\\n{2,}/)\n .map((paragraph) => paragraph.trim())\n .filter(Boolean);\n\n return (\n <div className={cn(\"space-y-4\", className)}>\n {paragraphs.map((paragraph, paragraphIndex) => (\n <p\n className={cn(\"whitespace-pre-wrap\", paragraphClassName)}\n key={`${paragraphIndex}:${paragraph}`}\n >\n {renderReadonlyInlineMarkdown(\n paragraph,\n onOpenWorkspaceReference,\n onMentionAction\n )}\n </p>\n ))}\n </div>\n );\n}\n\nfunction renderReadonlyInlineMarkdown(\n content: string,\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>,\n onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>\n): JSX.Element[] {\n const parts: JSX.Element[] = [];\n const segments = buildRichTextReadonlyInlineSegments(content);\n\n segments.forEach((segment, index) => {\n if (segment.type === \"text\") {\n parts.push(<span key={`text:${index}`}>{segment.text}</span>);\n return;\n }\n\n parts.push(\n <RichTextReadonlyInlineLink\n href={segment.href}\n key={`link:${index}:${segment.href}`}\n label={segment.label}\n onMentionAction={onMentionAction}\n onOpenWorkspaceReference={onOpenWorkspaceReference}\n />\n );\n });\n\n return parts;\n}\n\nfunction RichTextReadonlyInlineLink({\n href,\n label,\n onMentionAction,\n onOpenWorkspaceReference\n}: {\n href: string;\n label: string;\n onMentionAction?: (mention: RichTextMentionAttrs) => void | Promise<void>;\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>;\n}): JSX.Element {\n const trimmedHref = href.trim();\n const mention = parseRichTextMentionHref(trimmedHref, label);\n\n if (mention) {\n return (\n <RichTextMentionReadonly\n mention={mention}\n onClick={\n onMentionAction\n ? ({ mention }) => {\n void onMentionAction(mention);\n }\n : undefined\n }\n />\n );\n }\n\n if (!trimmedHref) {\n return <span>{label}</span>;\n }\n\n if (\n externalHrefPattern.test(trimmedHref) &&\n !isRichTextMentionHref(trimmedHref)\n ) {\n return (\n <a\n className=\"font-medium text-[var(--text-primary)] underline decoration-[var(--border-1)] underline-offset-4 hover:text-[var(--text-primary-hover)]\"\n href={trimmedHref}\n rel=\"noreferrer\"\n target=\"_blank\"\n >\n {label}\n </a>\n );\n }\n\n const kind = trimmedHref.endsWith(\"/\") ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(trimmedHref, kind);\n\n return (\n <WorkspaceReferenceReadonly\n reference={{\n kind,\n label,\n path\n }}\n onOpenWorkspaceReference={onOpenWorkspaceReference}\n />\n );\n}\n\nfunction WorkspaceReferenceReadonly({\n reference,\n onOpenWorkspaceReference\n}: {\n reference: RichTextReadonlyWorkspaceReference;\n onOpenWorkspaceReference?: (\n reference: RichTextReadonlyWorkspaceReference\n ) => void | Promise<void>;\n}): JSX.Element {\n const presentation = getWorkspaceReferencePresentation(\n reference.label,\n reference.path\n );\n const content = (\n <MentionPill\n className={richTextWorkspaceReferencePillClassName}\n fileKind={reference.kind}\n kind=\"file\"\n label={presentation.displayLabel}\n removable={false}\n />\n );\n\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n {onOpenWorkspaceReference ? (\n <button\n className=\"inline-flex max-w-full appearance-none items-baseline bg-transparent p-0 text-inherit\"\n type=\"button\"\n onClick={() => {\n void onOpenWorkspaceReference(reference);\n }}\n >\n {content}\n </button>\n ) : (\n <span className=\"inline-flex max-w-full align-baseline\">\n {content}\n </span>\n )}\n </TooltipTrigger>\n <TooltipContent\n className=\"max-w-md whitespace-normal break-all\"\n sideOffset={8}\n >\n {presentation.fullPath}\n </TooltipContent>\n </Tooltip>\n );\n}\n","import { findRichTextMarkdownLinks } from \"../core/richTextMarkdownLinks.ts\";\n\nexport type RichTextReadonlyInlineSegment =\n | {\n text: string;\n type: \"text\";\n }\n | {\n href: string;\n label: string;\n type: \"link\";\n };\n\nexport function buildRichTextReadonlyInlineSegments(\n content: string\n): RichTextReadonlyInlineSegment[] {\n const segments: RichTextReadonlyInlineSegment[] = [];\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(content)) {\n if (match.index > cursor) {\n segments.push({\n text: content.slice(cursor, match.index),\n type: \"text\"\n });\n }\n\n segments.push({\n href: match.href,\n label: match.label || match.href,\n type: \"link\"\n });\n cursor = match.to;\n }\n\n if (cursor < content.length) {\n segments.push({\n text: content.slice(cursor),\n type: \"text\"\n });\n }\n\n return segments;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA,EACE,aAAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAAC;AAAA,OAIK;AACP,OAAO,cAAc;AACrB,OAAO,eAAe;AACtB,OAAO,eAAe;AACtB,OAAO,UAAU;AAEjB,SAAS,eAAe,iBAAiB;AACzC,SAAS,2BAA2B;AACpC,SAAS,UAAU;;;ACDZ,SAAS,gCACd,WACA,UACS;AACT,MAAI,aAAa,cAAc;AAC7B,WAAO,KAAK,KAAK,SAAS;AAAA,EAC5B;AACA,SAAO,4BAA4B,KAAK,SAAS;AACnD;AAEO,SAAS,yBACd,OACA,OACA,gBACkC;AAClC,QAAM,SAAS,KAAK,IAAI,GAAG,KAAK,IAAI,OAAO,MAAM,MAAM,CAAC;AACxD,MAAI,eAAe,WAAW,GAAG;AAC/B,WAAO;AAAA,EACT;AACA,MAAI,eAAe;AACnB,SAAO,eAAe,GAAG;AACvB,UAAM,WAAW,MAAM,eAAe,CAAC,KAAK;AAC5C,QAAI,KAAK,KAAK,QAAQ,GAAG;AACvB;AAAA,IACF;AACA,oBAAgB;AAAA,EAClB;AAEA,QAAM,UAAU,MAAM,MAAM,cAAc,MAAM;AAChD,WAAS,QAAQ,QAAQ,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG;AAC3D,UAAM,UAAU,QAAQ,KAAK;AAC7B,UAAM,kBAAkB,eAAe;AAAA,MACrC,CAAC,WAAW,OAAO,YAAY;AAAA,IACjC;AACA,QAAI,gBAAgB,WAAW,GAAG;AAChC;AAAA,IACF;AACA,UAAM,WAAW,QAAQ,QAAQ,CAAC,KAAK;AACvC,QACE,QAAQ,KACR,CAAC,gBAAgB;AAAA,MAAK,CAAC,WACrB,gCAAgC,UAAU,OAAO,QAAQ;AAAA,IAC3D,GACA;AACA;AAAA,IACF;AAEA,UAAM,YAAY,QAAQ,MAAM,KAAK;AACrC,QAAI,UAAU,KAAK,UAAU,MAAM,CAAC,CAAC,GAAG;AACtC,aAAO;AAAA,IACT;AAEA,WAAO;AAAA,MACL,MAAM,eAAe;AAAA,MACrB,IAAI;AAAA,MACJ;AAAA,MACA,SAAS,UAAU,MAAM,CAAC;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,4BACpB,UACA,OAC+C;AAC/C,MAAI;AACF,WAAO,MAAM,SAAS,MAAM,KAAK;AAAA,EACnC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;;;AC7EO,SAAS,uBACd,OACS;AACT,MAAI,MAAM,eAAe,MAAM,aAAa,aAAa;AACvD,WAAO;AAAA,EACT;AAEA,QAAM,UAAU,MAAM,WAAW,MAAM,aAAa;AACpD,QAAM,QAAQ,MAAM,SAAS,MAAM,aAAa;AAChD,SAAO,YAAY,OAAO,UAAU;AACtC;;;ACJA,IAAM,sBAAsB,iCAAiC;AAEtD,SAAS,2BACd,WACA,2BACA,OAA4B,qBACC;AAC7B,SAAO;AAAA,IACL,cACE,WAAW,cAAc,KAAK,KAAK,KAAK,EAAE,oBAAoB;AAAA,IAChE,gBACE,WAAW,gBAAgB,KAAK,KAAK,KAAK,EAAE,sBAAsB;AAAA,IACpE,4BACE,2BAA2B,KAAK,KAChC,WAAW,4BAA4B,KAAK,KAC5C,KAAK,EAAE,uCAAuC;AAAA,EAClD;AACF;AAEO,IAAM,6BAA6B,2BAA2B;;;ACnCrE,SAAS,UAAU,wBAAwB;AAiCrC,cAIA,YAJA;AAtBC,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA8C;AAC5C,SACE;AAAA,IAAC;AAAA;AAAA,MACC,iBAAe;AAAA,MACf,WAAW;AAAA,QACT;AAAA,QACA,WAAW,mCAAmC;AAAA,QAC9C;AAAA,MACF,EAAE,KAAK,GAAG;AAAA,MACV,MAAK;AAAA,MACL,aAAa,CAAC,UAAyC;AACrD,cAAM,eAAe;AACrB,iBAAS;AAAA,MACX;AAAA,MAEA;AAAA;AAAA,UAAC;AAAA;AAAA,YACC;AAAA,YACA;AAAA;AAAA,QACF;AAAA,QACA,qBAAC,UAAK,WAAU,uDACd;AAAA,8BAAC,UAAK,WAAU,8FACb,iBACH;AAAA,UACC,WACC,oBAAC,UAAK,WAAU,6GACb,oBACH,IACE;AAAA,WACN;AAAA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,wBAAwB;AAAA,EAC/B;AAAA,EACA;AACF,GAGgB;AACd,QAAM,oBAAoB,SAAS,KAAK,KAAK;AAE7C,MAAI,4BAA4B;AAC9B,UAAM,OACJ,+BAA+B,WAAW,mBAAmB;AAC/D,WACE;AAAA,MAAC;AAAA;AAAA,QACC,eAAY;AAAA,QACZ,WAAU;AAAA,QACV,+BAA4B;AAAA,QAE5B,8BAAC,QAAK,WAAU,UAAS;AAAA;AAAA,IAC3B;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAY;AAAA,MACZ,WAAU;AAAA,MACV,+BAA4B;AAAA,MAE3B,8BACC;AAAA,QAAC;AAAA;AAAA,UACC,KAAI;AAAA,UACJ,WAAU;AAAA,UACV,UAAS;AAAA,UACT,WAAW;AAAA,UACX,SAAQ;AAAA,UACR,KAAK;AAAA;AAAA,MACP,IAEA,oBAAC,UAAK,WAAU,6DAA4D;AAAA;AAAA,EAEhF;AAEJ;;;AC/FA,SAAS,iBAAiB,YAAY;AACtC,SAAS,6BAA6B;;;ACAtC,SAAS,uBAA2C;AACpD;AAAA,EACE;AAAA,OAEK;AAiFD,gBAAAC,YAAA;AA/EN,IAAM,wCAAwC;AAE9C,SAAS,eAAe,OAAwB;AAC9C,SAAO,OAAO,UAAU,WAAW,MAAM,KAAK,IAAI;AACpD;AAEA,SAAS,2BAA2B,cAAsC;AACxE,MAAI,CAAC,gBAAgB,OAAO,iBAAiB,UAAU;AACrD,WAAO;AAAA,EACT;AACA,QAAM,QACH,aAA+D,WAC/D,aAA4C;AAC/C,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AACA,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,WAAW;AACpB;AAIA,SAAS,sBAAsB,OAAgB,KAAqB;AAClE,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,SAAO,eAAgB,MAAkC,GAAG,CAAC;AAC/D;AAIA,SAAS,uBACP,YACA,OACiB;AACjB,QAAM,KAAK,WAAW,KAAK;AAC3B,MAAI,OAAO,mBAAmB,OAAO,WAAW;AAC9C,WAAO;AAAA,EACT;AACA,MAAI,OAAO,iBAAiB;AAC1B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,mBAAmB;AAC5B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,uBAAuB;AAChC,WAAO,sBAAsB,OAAO,QAAQ,MAAM,SAAS,UAAU;AAAA,EACvE;AACA,MAAI,OAAO,QAAQ;AACjB,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,yBAAyB;AAAA,EACvC;AAAA,EACA;AACF,GAA+B;AAC7B,QAAM,QACJ,OAAO,KAAK,MAAM,UAAU,WACxB,KAAK,MAAM,MAAM,KAAK,EAAE,QAAQ,OAAO,EAAE,EAAE,KAAK,IAChD;AACN,QAAM,UACJ,2BAA2B,KAAK,MAAM,YAAY,KAClD,sBAAsB,KAAK,MAAM,OAAO,MAAM;AAChD,QAAM,OAAO;AAAA,IACX,eAAe,KAAK,MAAM,UAAU;AAAA,IACpC,KAAK,MAAM;AAAA,EACb;AAEA,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,IAAG;AAAA,MACH,WAAW,wCACT,WAAW,iBAAiB,EAC9B;AAAA,MACA,iBAAiB;AAAA,MACjB,oCAAiC;AAAA,MAEjC,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,UACX,SAAS,WAAW;AAAA,UACpB;AAAA,UACA;AAAA,UACA,WAAW;AAAA;AAAA,MACb;AAAA;AAAA,EACF;AAEJ;;;ADjFO,IAAM,mBAAmB,KAAK,OAAO;AAAA,EAC1C,MAAM;AAAA,EACN,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,YAAY;AAAA,EAEZ,gBAAgB;AACd,WAAO;AAAA,MACL,UAAU;AAAA,QACR,SAAS;AAAA,MACX;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,MACX;AAAA,MACA,cAAc;AAAA,QACZ,SAAS;AAAA,MACX;AAAA,MACA,YAAY;AAAA,QACV,SAAS;AAAA,MACX;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,MACX;AAAA,MACA,SAAS;AAAA,QACP,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY;AACV,WAAO,CAAC,EAAE,KAAK,yCAAyC,CAAC;AAAA,EAC3D;AAAA,EAEA,WAAW,EAAE,eAAe,GAAG;AAC7B,UAAM,QACJ,OAAO,eAAe,UAAU,WAAW,eAAe,QAAQ;AACpE,UAAM,eAAe,MAAM,KAAK,EAAE,QAAQ,OAAO,EAAE,EAAE,KAAK;AAE1D,WAAO;AAAA,MACL;AAAA,MACA,gBAAgB,gBAAgB;AAAA,QAC9B,oCAAoC;AAAA,QACpC,OACE;AAAA,MACJ,CAAC;AAAA,MACD,eAAe,IAAI,YAAY,KAAK;AAAA,IACtC;AAAA,EACF;AAAA,EAEA,cAAc;AACZ,WAAO,sBAAsB,0BAA0B;AAAA,MACrD,IAAI;AAAA,MACJ,WAAW;AAAA,IACb,CAAC;AAAA,EACH;AACF,CAAC;;;AEtED,SAAS,mBAAAC,kBAAiB,QAAAC,aAAY;AACtC,SAAS,yBAAAC,8BAA6B;;;ACDtC,SAAS,WAAW,gBAA6C;AACjE,SAAS,mBAAAC,wBAA2C;AACpD;AAAA,EACE,eAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;;;ACFA,SAAS,kCACd,OACA,MACgC;AAChC,QAAM,eAAe,wBAAwB,OAAO,IAAI;AACxD,QAAM,WAAW,kBAAkB,IAAI;AAEvC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,wBAAwB,OAAe,MAAsB;AACpE,QAAM,eAAe,MAAM,KAAK;AAEhC,MAAI,iBAAiB,IAAI;AACvB,WAAO;AAAA,EACT;AAEA,SAAO,gBAAgB,IAAI,KAAK,KAAK,KAAK;AAC5C;AAEA,SAAS,kBAAkB,MAAsB;AAC/C,SAAO,uBAAuB,KAAK,KAAK,CAAC;AAC3C;AAEA,SAAS,gBAAgB,MAAsB;AAC7C,QAAM,iBAAiB,uBAAuB,KAAK,KAAK,CAAC;AAEzD,MAAI,mBAAmB,MAAM,WAAW,cAAc,GAAG;AACvD,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,eAAe,MAAM,QAAQ,EAAE,OAAO,OAAO;AAE9D,SAAO,SAAS,GAAG,EAAE,KAAK;AAC5B;AAEA,SAAS,uBAAuB,MAAsB;AACpD,MAAI,SAAS,IAAI;AACf,WAAO;AAAA,EACT;AAEA,MAAI,WAAW,IAAI,GAAG;AACpB,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,QAAQ,WAAW,EAAE;AACnC;AAEA,SAAS,WAAW,MAAuB;AACzC,SACE,SAAS,OACT,SAAS,QACT,SAAS,QACT,SAAS,UACT,oBAAoB,KAAK,IAAI;AAEjC;;;ADMM,SAEI,OAAAC,MAFJ,QAAAC,aAAA;AA3DN,IAAM,0CAA0C;AAEzC,SAAS,2BAA2B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA+B;AAC7B,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,OAAO,UAAU;AAC9D,QAAM,QAAQ,KAAK;AAKnB,QAAM,mBAAmB,UAAU;AAGnC,QAAM,OAAO,MAAM,SAAS,WAAW,WAAW;AAClD,QAAM,QAAQ,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ;AAC9D,QAAM,OAAO,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAC3D,QAAM,eAAe,kCAAkC,OAAO,IAAI;AAClE,QAAM,wBACJ,OAAO,iBAAiB,0BAA0B,WAC9C,iBAAiB,wBACjB,2BAA2B;AAEjC,YAAU,MAAM;AACd,UAAM,eAAe,MAAM;AACzB,oBAAc,OAAO,UAAU;AAAA,IACjC;AAEA,iBAAa;AACb,WAAO,GAAG,eAAe,YAAY;AACrC,WAAO,GAAG,UAAU,YAAY;AAChC,WAAO,MAAM;AACX,aAAO,IAAI,eAAe,YAAY;AACtC,aAAO,IAAI,UAAU,YAAY;AAAA,IACnC;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,QAAM,eAAe,CAAC,UAA2C;AAC/D,UAAM,eAAe;AACrB,UAAM,gBAAgB;AACtB,QAAI,CAAC,OAAO,YAAY;AACtB;AAAA,IACF;AACA,eAAW;AAAA,EACb;AAEA,SACE,gBAAAD;AAAA,IAACE;AAAA,IAAA;AAAA,MACC,IAAG;AAAA,MACH,WAAW,yCACT,WAAW,gBAAgB,EAC7B;AAAA,MACA,iBAAiB;AAAA,MACjB,sCAAmC;AAAA,MAEnC,0BAAAD,MAAC,WACC;AAAA,wBAAAD,KAAC,kBAAe,SAAO,MACrB,0BAAAA;AAAA,UAACG;AAAA,UAAA;AAAA,YACC,WAAW;AAAA,YACX,UAAU;AAAA,YACV,MAAK;AAAA,YACL,OAAO,aAAa;AAAA,YACpB,WAAW;AAAA,YACX,mBACE,aACI;AAAA,cACE,cAAc;AAAA,cACd,eAAe;AAAA,cACf,UAAU;AAAA,YACZ,IACA;AAAA;AAAA,QAER,GACF;AAAA,QACA,gBAAAH;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV,YAAY;AAAA,YAEX,uBAAa;AAAA;AAAA,QAChB;AAAA,SACF;AAAA;AAAA,EACF;AAEJ;;;ADrFO,IAAM,qBAAqBI,MAAK,OAAO;AAAA,EAC5C,MAAM;AAAA,EACN,aAAa;AACX,WAAO;AAAA,MACL,uBACE,2BAA2B;AAAA,IAC/B;AAAA,EACF;AAAA,EACA,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,YAAY;AAAA,EAEZ,gBAAgB;AACd,WAAO;AAAA,MACL,MAAM;AAAA,QACJ,SAAS;AAAA,MACX;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,MACX;AAAA,MACA,MAAM;AAAA,QACJ,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA,EAEA,YAAY;AACV,WAAO,CAAC,EAAE,KAAK,2CAA2C,CAAC;AAAA,EAC7D;AAAA,EAEA,WAAW,EAAE,eAAe,GAAG;AAC7B,UAAM,OAAO,eAAe,SAAS,WAAW,WAAW;AAC3D,UAAM,QACJ,OAAO,eAAe,UAAU,WAAW,eAAe,QAAQ;AACpE,UAAM,OACJ,OAAO,eAAe,SAAS,WAAW,eAAe,OAAO;AAClE,UAAM,eAAe,kCAAkC,OAAO,IAAI;AAClE,UAAM,0BACJ,SAAS,WACL,mCACA;AAEN,WAAO;AAAA,MACL;AAAA,MACAC,iBAAgB,gBAAgB;AAAA,QAC9B,sCAAsC;AAAA,QACtC,iCAAiC;AAAA,QACjC,2BAA2B;AAAA,QAC3B,2BAA2B;AAAA,QAC3B,aAAa;AAAA,QACb,OAAO,aAAa;AAAA,QACpB,OAAO;AAAA,UACL;AAAA,UACA;AAAA,QACF,EAAE,KAAK,GAAG;AAAA,MACZ,CAAC;AAAA,MACD;AAAA,QACE;AAAA,QACA;AAAA,UACE,eAAe;AAAA,UACf,OAAO;AAAA,QACT;AAAA,QACA,SAAS,WAAW,MAAM;AAAA,MAC5B;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,UACE,OAAO;AAAA,QACT;AAAA,QACA,aAAa;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA,EAEA,cAAc;AACZ,WAAOC,uBAAsB,0BAA0B;AAAA,EACzD;AACF,CAAC;;;APoYG,SAKI,OAAAC,MALJ,QAAAC,aAAA;AA9YJ,IAAM,sCAAsC;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA,mBAAmB,CAAC;AAAA,EACpB;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4C;AAC1C,QAAM,aAAa;AACnB,QAAM,kBAAkB,yBAAyB,KAAK;AACtD,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,oBAAoB,OAAO,QAAQ;AACzC,QAAM,yBAAyB,OAAO,eAAe;AACrD,QAAM,qBAAqB,OAAO,WAAW;AAC7C,QAAM,6BAA6B,OAAO,CAAC;AAC3C,QAAM,eAAe,OAA8B,IAAI;AACvD,QAAM,WAAW;AAAA,IACf,MAAM,8BAA8B,gBAAgB;AAAA,IACpD,CAAC,gBAAgB;AAAA,EACnB;AACA,QAAM,uBAAuB;AAAA,IAC3B,MAAM,SAAS,mBAAmB;AAAA,IAClC,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,CAAC,WAAW,YAAY,IAAIC,UAAS,KAAK;AAChD,QAAM,CAAC,OAAO,QAAQ,IAAIA;AAAA,IACxB;AAAA,EACF;AACA,QAAM,CAAC,SAAS,UAAU,IAAIA;AAAA,IAC5B,CAAC;AAAA,EACH;AACA,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,CAAC;AAChD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,CAAC,WAAW,YAAY,IAAIA;AAAA,IAChC;AAAA,EACF;AAEA,oBAAkB,UAAU;AAE5B,QAAM,SAAS,UAAU;AAAA,IACvB,mBAAmB;AAAA,IACnB,UAAU,CAAC;AAAA,IACX,YAAY;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,mBAAmB,UAAU;AAAA,QAC3B,uBAAuB,KAAK;AAAA,MAC9B,CAAC;AAAA,MACD;AAAA,IACF;AAAA,IACA,SAAS,+BAA+B,eAAe;AAAA,IACvD,aAAa;AAAA,MACX,YAAY;AAAA,QACV,OAAO;AAAA,UACL;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS;AACP,aAAO,WAAW,MAAM;AACtB,qBAAa,KAAK;AAClB,iBAAS,IAAI;AACb,mBAAW,CAAC,CAAC;AACb,uBAAe,CAAC;AAChB,qBAAa,KAAK;AAClB,qBAAa,IAAI;AAAA,MACnB,GAAG,GAAG;AAAA,IACR;AAAA,IACA,UAAU;AACR,mBAAa,IAAI;AAAA,IACnB;AAAA,IACA,SAAS,EAAE,QAAAC,QAAO,GAAG;AACnB,YAAM,aAAa,mCAAmCA,QAAO,QAAQ,CAAC;AACtE,6BAAuB,UAAU;AACjC,wBAAkB,QAAQ,UAAU;AAAA,IACtC;AAAA,EACF,CAAC;AAED,EAAAC,WAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,QAAI,uBAAuB,YAAY,iBAAiB;AACtD;AAAA,IACF;AAEA,UAAM,oBAAoB;AAAA,MACxB,OAAO,QAAQ;AAAA,IACjB;AACA,QAAI,sBAAsB,iBAAiB;AACzC,6BAAuB,UAAU;AACjC;AAAA,IACF;AAEA,WAAO,SAAS;AAAA,MACd,+BAA+B,eAAe;AAAA,MAC9C;AAAA,QACE,YAAY;AAAA,MACd;AAAA,IACF;AACA,2BAAuB,UAAU;AAAA,EACnC,GAAG,CAAC,QAAQ,eAAe,CAAC;AAE5B,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,UAAM,YAAY,2BAA2B,UAAU;AACvD,+BAA2B,UAAU;AACrC,UAAM,WAAW,8BAA8B,MAAM;AACrD,QAAI,SAAS,WAAW,GAAG;AACzB;AAAA,IACF;AAEA,eAAW,WAAW,UAAU;AAC9B,YAAM,WAAW,SAAS,YAAY,QAAQ,MAAM,UAAU;AAC9D,UAAI,CAAC,UAAU,gBAAgB;AAC7B;AAAA,MACF;AAEA,WAAK,QAAQ,QAAQ,SAAS,eAAe,QAAQ,KAAK,CAAC,EACxD,KAAK,CAAC,aAAa;AAClB,YACE,CAAC,YACD,2BAA2B,YAAY,aACvC,OAAO,aACP;AACA;AAAA,QACF;AAEA,kCAA0B,QAAQ,QAAQ,KAAK,QAAQ,OAAO;AAAA,UAC5D,OAAO,SAAS;AAAA,UAChB,cAAc,SAAS;AAAA,QACzB,CAAC;AAAA,MACH,CAAC,EACA,MAAM,MAAM;AAAA,MAEb,CAAC;AAAA,IACL;AAAA,EACF,GAAG,CAAC,QAAQ,UAAU,eAAe,CAAC;AAEtC,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,QAAI,OAAO,GAAG,mBAAmB,SAAS,WAAW,GAAG;AACtD;AAAA,IACF;AAEA,uBAAmB,UAAU;AAC7B,WAAO,SAAS,MAAM,KAAK;AAAA,EAC7B,GAAG,CAAC,QAAQ,WAAW,CAAC;AAExB,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,WAAO,YAAY,CAAC,QAAQ;AAC5B,WAAO,KAAK;AAAA,MACV,OAAO,MAAM,GAAG,QAAQ,oBAAoB,CAAC,QAAQ;AAAA,IACvD;AAAA,EACF,GAAG,CAAC,UAAU,MAAM,CAAC;AAErB,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,UAAM,mBAAmB,MAAM;AAC7B,YAAM,YAAY,kBAAkB,QAAQ,oBAAoB;AAChE,eAAS,SAAS;AAAA,IACpB;AAEA,UAAM,cAAc,MAAM;AACxB,YAAM,cAAc,OAAO;AAC3B,mBAAa,WAAW;AACxB,uBAAiB;AAAA,IACnB;AAEA,qBAAiB;AACjB,WAAO,GAAG,mBAAmB,gBAAgB;AAC7C,WAAO,GAAG,eAAe,gBAAgB;AACzC,WAAO,GAAG,SAAS,WAAW;AAC9B,WAAO,GAAG,QAAQ,WAAW;AAC7B,WAAO,MAAM;AACX,aAAO,IAAI,mBAAmB,gBAAgB;AAC9C,aAAO,IAAI,eAAe,gBAAgB;AAC1C,aAAO,IAAI,SAAS,WAAW;AAC/B,aAAO,IAAI,QAAQ,WAAW;AAAA,IAChC;AAAA,EACF,GAAG,CAAC,sBAAsB,MAAM,CAAC;AAEjC,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,UAAU,CAAC,SAAS,qBAAqB,WAAW,GAAG;AAC1D,iBAAW,CAAC,CAAC;AACb,qBAAe,CAAC;AAChB,mBAAa,KAAK;AAClB;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,SAAS,gBAAgB;AACzC,iBAAW,CAAC,CAAC;AACb,qBAAe,CAAC;AAChB,mBAAa,KAAK;AAClB;AAAA,IACF;AAEA,UAAM,kBAAkB,IAAI,gBAAgB;AAC5C,iBAAa,IAAI;AAEjB,SAAK,4BAA4B,UAAU;AAAA,MACzC,aAAa,gBAAgB;AAAA,MAC7B,SAAS,MAAM;AAAA,MACf;AAAA,MACA,SAAS,MAAM;AAAA,MACf,SAAS;AAAA,QACP,WAAW,OAAO,MAAM,UAAU,MAAM,OAAO;AAAA,UAC7C;AAAA,UACA,OAAO,MAAM,UAAU,MAAM,OAAO,QAAQ;AAAA,UAC5C;AAAA,UACA;AAAA,QACF;AAAA,QACA,cAAc,mCAAmC,OAAO,QAAQ,CAAC;AAAA,MACnE;AAAA,IACF,CAAC,EACE,KAAK,CAAC,gBAAgB;AACrB,UAAI,gBAAgB,OAAO,SAAS;AAClC;AAAA,MACF;AACA,iBAAW,WAAW;AACtB;AAAA,QAAe,CAAC,YACd,YAAY,WAAW,IACnB,IACA,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,YAAY,SAAS,CAAC,CAAC;AAAA,MAC3D;AAAA,IACF,CAAC,EACA,QAAQ,MAAM;AACb,UAAI,CAAC,gBAAgB,OAAO,SAAS;AACnC,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF,CAAC;AAEH,WAAO,MAAM;AACX,sBAAgB,MAAM;AAAA,IACxB;AAAA,EACF,GAAG;AAAA,IACD;AAAA,IACA;AAAA,IACA;AAAA,IACA,qBAAqB;AAAA,IACrB;AAAA,IACA;AAAA,EACF,CAAC;AAED,kBAAgB,MAAM;AACpB,QAAI,CAAC,UAAU,CAAC,OAAO;AACrB,mBAAa,IAAI;AACjB;AAAA,IACF;AAEA,UAAM,kBAAkB,MAAM;AAC5B,YAAM,SAAS,OAAO,KAAK,YAAY,OAAO,MAAM,UAAU,IAAI;AAClE,YAAM,gBAAgB;AAAA,QACpB,GAAG,OAAO;AAAA,QACV,GAAG,OAAO,SAAS;AAAA,MACrB;AACA,mBAAa,aAAa;AAAA,IAC5B;AAEA,oBAAgB;AAChB,WAAO,iBAAiB,UAAU,eAAe;AACjD,WAAO,iBAAiB,UAAU,iBAAiB;AAAA,MACjD,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AACD,WAAO,MAAM;AACX,aAAO,oBAAoB,UAAU,eAAe;AACpD,aAAO,oBAAoB,UAAU,iBAAiB,IAAI;AAAA,IAC5D;AAAA,EACF,GAAG,CAAC,QAAQ,YAAY,KAAK,CAAC;AAE9B,QAAM,kBACJ,CAAC,CAAC,SACF,qBAAqB,SAAS,KAC9B,MAAM,QAAQ,UAAU;AAC1B,QAAM,aAAa,oBAAoB,aAAa,CAAC,CAAC;AACtD,QAAM,UACJ,CAAC,UACD,mCAAmC,OAAO,QAAQ,CAAC,EAAE,KAAK,EAAE,WAAW;AAEzE,QAAM,aAAa,CAAC,UAAqC;AACvD,QAAI,CAAC,UAAU,CAAC,OAAO;AACrB;AAAA,IACF;AAEA,UAAM,UAAU;AAAA,MACd,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AACA,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,WACG,MAAM,EACN,MAAM,EACN,gBAAgB,EAAE,MAAM,MAAM,MAAM,IAAI,MAAM,GAAG,GAAG,OAAO,EAC3D,IAAI;AACP,eAAW,CAAC,CAAC;AACb,mBAAe,CAAC;AAChB,iBAAa,KAAK;AAClB,iBAAa,IAAI;AAAA,EACnB;AAEA,QAAM,gBAAgB,CAAC,UAAyC;AAC9D,QAAI,uBAAuB,KAAK,GAAG;AACjC;AAAA,IACF;AAEA,QAAI,CAAC,YAAY;AACf;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,UAAU;AAC1B,YAAM,eAAe;AACrB,iBAAW,CAAC,CAAC;AACb,qBAAe,CAAC;AAChB,mBAAa,KAAK;AAClB,mBAAa,IAAI;AACjB;AAAA,IACF;AAEA,QAAI,QAAQ,WAAW,GAAG;AACxB;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,aAAa;AAC7B,YAAM,eAAe;AACrB,qBAAe,CAAC,aAAa,UAAU,KAAK,QAAQ,MAAM;AAC1D;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,WAAW;AAC3B,YAAM,eAAe;AACrB;AAAA,QACE,CAAC,aAAa,UAAU,IAAI,QAAQ,UAAU,QAAQ;AAAA,MACxD;AACA;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,OAAO;AAChD,YAAM,QAAQ,QAAQ,WAAW;AACjC,UAAI,CAAC,OAAO;AACV;AAAA,MACF;AACA,YAAM,eAAe;AACrB,iBAAW,KAAK;AAChB;AAAA,IACF;AAAA,EACF;AAEA,SACE,gBAAAH;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,2BAA2B,SAAS;AAAA,MAClD,KAAK;AAAA,MAEL;AAAA,wBAAAD,KAAC,SAAI,WAAU,kBAAiB,kBAAkB,eAChD,0BAAAA,KAAC,iBAAc,QAAgB,GACjC;AAAA,QACC,WAAW,cACV,gBAAAA,KAAC,SAAI,WAAU,8FACb,0BAAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAW;AAAA,cACT;AAAA,cACA,wBAAwB;AAAA,cACxB;AAAA,YACF;AAAA,YAEC;AAAA;AAAA,QACH,GACF,IACE;AAAA,QACH;AAAA,QACA,cAAc,YACb,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAI;AAAA,YACJ,WAAU;AAAA,YACV,WAAW;AAAA,cACT,MAAM;AAAA,cACN,OAAO;AAAA,cACP,QAAQ;AAAA,cACR,QAAQ;AAAA,cACR,eAAe;AAAA,gBACb,OAAO;AAAA,gBACP,QAAQ;AAAA,cACV;AAAA,YACF;AAAA,YACA,OAAO,eAAe,SAAY,SAAY,EAAE,QAAQ,WAAW;AAAA,YAElE,kBAAQ,SAAS,IAChB,QAAQ,IAAI,CAAC,OAAO,UAClB,gBAAAA;AAAA,cAAC;AAAA;AAAA,gBAEC,OAAO,MAAM;AAAA,gBACb,UAAU,UAAU;AAAA,gBACpB,UAAU,MAAM;AAAA,gBAChB,SAAS,MAAM;AAAA,gBACf,4BAA4B;AAAA,kBAC1B,MAAM;AAAA,gBACR;AAAA,gBACA,UAAU,MAAM,WAAW,KAAK;AAAA;AAAA,cAR3B,GAAG,MAAM,UAAU,IAAI,MAAM,GAAG;AAAA,YASvC,CACD,IAED,gBAAAA,KAAC,SAAI,WAAU,gEACZ,sBAAY,KAAK,eAAe,KAAK,gBACxC;AAAA;AAAA,QAEJ,IACE;AAAA;AAAA;AAAA,EACN;AAEJ;AAEA,SAAS,kBACP,QACA,UACwC;AACxC,QAAM,QAAQ,uBAAuB,QAAQ,QAAQ;AACrD,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,uBACP,QACA,UACwC;AACxC,QAAM,EAAE,UAAU,IAAI,OAAO;AAC7B,MAAI,CAAC,UAAU,OAAO;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,MAAM,IAAI;AAClB,MAAI,CAAC,MAAM,OAAO,aAAa;AAC7B,WAAO;AAAA,EACT;AAEA,QAAM,mBAAmB,MAAM,OAAO;AAAA,IACpC;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,EACF;AACA,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,iBAAiB;AAAA,IACjB;AAAA,EACF;AACA,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAEA,QAAM,yBAAyB,iBAAiB,SAAS,MAAM;AAC/D,SAAO;AAAA,IACL,MAAM,UAAU,OAAO;AAAA,IACvB,SAAS,MAAM;AAAA,IACf,SAAS,MAAM;AAAA,IACf,IAAI,UAAU;AAAA,EAChB;AACF;AAEA,SAAS,kCACP,YACA,QACA;AACA,UAAQ,OAAO,MAAM;AAAA,IACnB,KAAK;AACH,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO,2BAA2B,YAAY,OAAO,OAAO;AAAA,MAC9D;AAAA,IACF,KAAK,iBAAiB;AACpB,YAAM,OAAO,OAAO,KAAK,SAAS,GAAG,IAAI,WAAW;AACpD,aAAO;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,UACL;AAAA,UACA,OAAO,OAAO;AAAA,UACd,MAAM,0BAA0B,OAAO,MAAM,IAAI;AAAA,QACnD;AAAA,MACF;AAAA,IACF;AAAA,IACA,KAAK;AACH,aAAO,OAAO;AAAA,IAChB;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,8BACP,QAC+B;AAC/B,MAAI,OAAO,SAAS,iBAAiB;AACnC,WAAO;AAAA,EACT;AACA,SAAO,OAAO,KAAK,SAAS,GAAG,IAAI,WAAW;AAChD;AAEA,SAAS,8BACP,QACqD;AACrD,QAAM,WAAgE,CAAC;AAEvE,SAAO,MAAM,IAAI,YAAY,CAAC,MAAM,QAAQ;AAC1C,QAAI,KAAK,KAAK,SAAS,0BAA0B;AAC/C;AAAA,IACF;AACA,UAAM,QAAQ,KAAK;AACnB,QACE,MAAM,YAAY,OAClB,OAAO,MAAM,eAAe,YAC5B,CAAC,MAAM,WAAW,KAAK,KACvB,OAAO,MAAM,aAAa,YAC1B,CAAC,MAAM,SAAS,KAAK,KACrB,OAAO,MAAM,UAAU,YACvB,CAAC,MAAM,MAAM,KAAK,GAClB;AACA;AAAA,IACF;AAEA,aAAS,KAAK;AAAA,MACZ;AAAA,MACA,OAAO;AAAA,QACL,SAAS;AAAA,QACT,YAAY,MAAM,WAAW,KAAK;AAAA,QAClC,UAAU,MAAM,SAAS,KAAK;AAAA,QAC9B,OAAO,MAAM,MAAM,KAAK,EAAE,QAAQ,OAAO,EAAE,EAAE,KAAK;AAAA,QAClD,OAAO,6BAA6B,MAAM,KAAK;AAAA,QAC/C,cAAc,6BAA6B,MAAM,YAAY;AAAA,MAC/D;AAAA,IACF,CAAC;AAAA,EACH,CAAC;AAED,SAAO;AACT;AAEA,SAAS,0BACP,QACA,KACA,cACA,UAIM;AACN,QAAM,OAAO,OAAO,MAAM,IAAI,OAAO,GAAG;AACxC,MAAI,CAAC,QAAQ,KAAK,KAAK,SAAS,0BAA0B;AACxD;AAAA,EACF;AAEA,QAAM,QAAQ,KAAK;AACnB,MACE,MAAM,eAAe,aAAa,cAClC,MAAM,aAAa,aAAa,YAChC,KAAK,UAAU,6BAA6B,MAAM,KAAK,KAAK,CAAC,CAAC,MAC5D,KAAK,UAAU,aAAa,SAAS,CAAC,CAAC,GACzC;AACA;AAAA,EACF;AAEA,QAAM,YAAY,SAAS,OAAO,KAAK,EAAE,QAAQ,OAAO,EAAE,EAAE,KAAK;AACjE,QAAM,mBAAmB,6BAA6B,SAAS,YAAY;AAC3E,QAAM,YAAkC;AAAA,IACtC,SAAS;AAAA,IACT,YAAY,aAAa;AAAA,IACzB,UAAU,aAAa;AAAA,IACvB,OAAO,aAAa,aAAa;AAAA,IACjC,OAAO,aAAa;AAAA,IACpB,cAAc,oBAAoB,aAAa;AAAA,EACjD;AAEA,MACE,MAAM,UAAU,UAAU,SAC1B,KAAK,UAAU,6BAA6B,MAAM,YAAY,KAAK,CAAC,CAAC,MACnE,KAAK,UAAU,UAAU,gBAAgB,CAAC,CAAC,GAC7C;AACA;AAAA,EACF;AAEA,QAAM,cAAc,OAAO,MAAM,GAAG,cAAc,KAAK,QAAW,SAAS;AAC3E,cAAY,QAAQ,gBAAgB,KAAK;AACzC,cAAY,QAAQ,iBAAiB,IAAI;AACzC,SAAO,KAAK,SAAS,WAAW;AAClC;AAEA,SAAS,6BACP,OAC8C;AAC9C,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,QAAM,UAAU,OAAO,QAAQ,KAAgC,EAC5D;AAAA,IACC,CAAC,CAAC,KAAK,UAAU,MACf;AAAA,MACE,IAAI,KAAK;AAAA,MACT,OAAO,eAAe,WAAW,WAAW,KAAK,IAAI;AAAA,IACvD;AAAA,EACJ,EACC,OAAO,CAAC,CAAC,KAAK,UAAU,MAAM,IAAI,SAAS,KAAK,WAAW,SAAS,CAAC,EACrE,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MAAM,KAAK,cAAc,KAAK,CAAC;AAEtD,SAAO,QAAQ,SAAS,IACpB,OAAO,OAAO,OAAO,YAAY,OAAO,CAAC,IACzC;AACN;AAEA,SAAS,6BACP,OACyC;AACzC,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO;AAAA,EACT;AACA,QAAM,SAAS;AACf,QAAM,OAAoC,CAAC;AAE3C,aAAW,OAAO,qCAAqC;AACrD,UAAM,aAAa,OAAO,GAAG;AAC7B,QAAI,OAAO,eAAe,UAAU;AAClC;AAAA,IACF;AACA,UAAM,UAAU,WAAW,KAAK;AAChC,QAAI,SAAS;AACX,WAAK,GAAG,IAAI;AAAA,IACd;AAAA,EACF;AAEA,SAAO,OAAO,KAAK,IAAI,EAAE,SAAS,IAAI,OAAO,OAAO,IAAI,IAAI;AAC9D;;;AUrvBA;AAAA,EACE,aAAAK;AAAA,EACA,mBAAAC;AAAA,EACA,WAAAC;AAAA,EACA,UAAAC;AAAA,EACA,YAAAC;AAAA,OAKK;AACP,SAAS,uBAAAC,4BAA2B;AACpC,SAAS,MAAAC,WAAU;;;ACRnB,IAAM,uBAAuB;AAE7B,IAAM,yCAAyC;AAAA,EAC7C,EAAE,WAAW,cAAc,SAAS,cAAc;AAAA,EAClD,EAAE,WAAW,gBAAgB,SAAS,gBAAgB;AAAA,EACtD,EAAE,WAAW,iBAAiB,SAAS,iBAAiB;AAAA,EACxD,EAAE,WAAW,eAAe,SAAS,eAAe;AAAA,EACpD,EAAE,WAAW,cAAc,SAAS,cAAc;AAAA,EAClD,EAAE,WAAW,uBAAuB,SAAS,wBAAwB;AAAA,EACrE,EAAE,WAAW,eAAe,SAAS,eAAe;AAAA,EACpD,EAAE,WAAW,qBAAqB,SAAS,sBAAsB;AAAA,EACjE,EAAE,WAAW,YAAY,SAAS,YAAY;AAAA,EAC9C,EAAE,WAAW,eAAe,SAAS,eAAe;AAAA,EACpD,EAAE,WAAW,aAAa,SAAS,aAAa;AAAA,EAChD,EAAE,WAAW,eAAe,SAAS,eAAe;AAAA,EACpD,EAAE,WAAW,yBAAyB,SAAS,0BAA0B;AAAA,EACzE,EAAE,WAAW,cAAc,SAAS,cAAc;AAAA,EAClD,EAAE,WAAW,iBAAiB,SAAS,iBAAiB;AAAA,EACxD,EAAE,WAAW,cAAc,SAAS,cAAc;AAAA,EAClD,EAAE,WAAW,aAAa,SAAS,aAAa;AAAA,EAChD,EAAE,WAAW,cAAc,SAAS,cAAc;AAAA,EAClD,EAAE,WAAW,iBAAiB,SAAS,iBAAiB;AAAA,EACxD,EAAE,WAAW,WAAW,SAAS,WAAW;AAAA,EAC5C,EAAE,WAAW,cAAc,SAAS,gBAAgB;AACtD;AA0BA,SAAS,0BAA0B,MAAuB;AACxD,QAAM,cAAc,KAAK,KAAK;AAC9B,MAAI,CAAC,aAAa;AAChB,WAAO;AAAA,EACT;AACA,MACE,qBAAqB,KAAK,WAAW,KACrC,sBAAsB,WAAW,GACjC;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,wCACd,OACqC;AACrC,QAAM,WAAgD,CAAC;AACvD,MAAI,SAAS;AAEb,aAAW,SAAS,0BAA0B,KAAK,GAAG;AACpD,UAAM,QAAQ,MAAM,MAAM,KAAK;AAC/B,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,UAAM,EAAE,OAAO,QAAQ,GAAG,IAAI;AAE9B,QAAI,QAAQ,QAAQ;AAClB,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM,MAAM,MAAM,QAAQ,KAAK;AAAA,QAC/B,MAAM;AAAA,QACN,IAAI;AAAA,MACN,CAAC;AAAA,IACH;AAEA,QAAI,SAAS,QAAQ,0BAA0B,IAAI,GAAG;AACpD,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,KAAK,SAAS,GAAG,IAAI,WAAW;AAAA,MACxC,CAAC;AAAA,IACH,OAAO;AACL,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA,QACN,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AAAA,IACH;AAEA,aAAS;AAAA,EACX;AAEA,MAAI,SAAS,MAAM,QAAQ;AACzB,aAAS,KAAK;AAAA,MACZ,MAAM;AAAA,MACN,MAAM,MAAM,MAAM,MAAM;AAAA,MACxB,MAAM;AAAA,MACN,IAAI,MAAM;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,SAAS,+BACd,UACS;AACT,SAAO,SAAS,KAAK,CAAC,YAAY,QAAQ,SAAS,MAAM;AAC3D;AAEO,SAAS,yCACd,UACA,gBACe;AACf,aAAW,WAAW,UAAU;AAC9B,QAAI,QAAQ,SAAS,QAAQ;AAC3B;AAAA,IACF;AACA,QAAI,kBAAkB,QAAQ,QAAQ,kBAAkB,QAAQ,IAAI;AAClE;AAAA,IACF;AACA,UAAM,WAAW,QAAQ,QAAQ,QAAQ,KAAK,QAAQ,QAAQ;AAC9D,WAAO,iBAAiB,WAAW,QAAQ,OAAO,QAAQ;AAAA,EAC5D;AACA,SAAO;AACT;AAEA,SAAS,kCACP,aACA,WACA,OACM;AACN,cAAY,SAAS,IAAI;AAC3B;AAEO,SAAS,6BACd,UACe;AACf,QAAM,gBAAgB,OAAO,iBAAiB,QAAQ;AACtD,QAAM,cAA6B;AAAA,IACjC,YAAY;AAAA,EACd;AAEA;AAAA,IACE;AAAA,IACA;AAAA,IACA,cAAc;AAAA,EAChB;AACA;AAAA,IACE;AAAA,IACA;AAAA,IACA,cAAc;AAAA,EAChB;AAEA,aAAW,EAAE,WAAW,QAAQ,KAAK,wCAAwC;AAC3E;AAAA,MACE;AAAA,MACA;AAAA,MACA,cAAc,iBAAiB,OAAO;AAAA,IACxC;AAAA,EACF;AAEA,SAAO;AACT;;;ACpLA,SAAS,eAAAC,oBAAmB;AAC5B,SAAS,MAAAC,WAAU;AAsCA,gBAAAC,MAIP,QAAAC,aAJO;AAnCnB,IAAMC,2CAA0C;AAEzC,SAAS,iCAAiC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAagB;AACd,SACE,gBAAAF,KAAC,SAAI,WAAU,6DACb,0BAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO;AAAA,QACL,GAAG;AAAA,QACH,WAAW,aAAa,CAAC,UAAU,OAAO,CAAC,SAAS;AAAA,MACtD;AAAA,MAEC,mBAAS,IAAI,CAAC,SAAS,UAAU;AAChC,YAAI,QAAQ,SAAS,QAAQ;AAC3B,iBAAO,gBAAAA,KAAC,UAAkB,kBAAQ,QAAhB,KAAqB;AAAA,QACzC;AAEA,eACE,gBAAAC,MAAC,UAAiB,WAAU,YAC1B;AAAA,0BAAAD,KAAC,UAAK,eAAY,QAAO,WAAU,oBAChC,kBAAQ,MACX;AAAA,UACA,gBAAAA;AAAA,YAACF;AAAA,YAAA;AAAA,cACC,WAAWC;AAAA,gBACT;AAAA,gBACAG;AAAA,cACF;AAAA,cACA,UAAU,QAAQ;AAAA,cAClB,MAAK;AAAA,cACL,OAAO,QAAQ;AAAA,cACf,mBAAmB;AAAA,gBACjB,cAAc;AAAA,gBACd,eAAe,CAAC,UAAU;AACxB,wBAAM,eAAe;AACrB,wBAAM,gBAAgB;AACtB,kCAAgB,OAAO;AAAA,gBACzB;AAAA,cACF;AAAA,cACA,SACE,gBAAAF;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAWD;AAAA,oBACT;AAAA,oBACA,QAAQ,SAAS,WACb,kBACA;AAAA,kBACN;AAAA,kBAEC,kBAAQ;AAAA;AAAA,cACX;AAAA,cAEF,eAAe,CAAC,UAAU;AACxB,+BAAe,SAAS,KAAK;AAAA,cAC/B;AAAA;AAAA,UACF;AAAA,aAnCS,KAoCX;AAAA,MAEJ,CAAC;AAAA;AAAA,EACH,GACF;AAEJ;;;ACtFA,IAAM,mCAAmC;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAQA,SAAS,gBAAgB,OAAiD;AACxE,MAAI,CAAC,SAAS,UAAU,UAAU;AAChC,WAAO;AAAA,EACT;AAEA,QAAM,cAAc,OAAO,WAAW,KAAK;AAC3C,SAAO,OAAO,SAAS,WAAW,IAAI,cAAc;AACtD;AAEA,SAAS,kBAAkB,eAA4C;AACrE,QAAM,qBAAqB,gBAAgB,cAAc,UAAU;AACnE,MAAI,uBAAuB,MAAM;AAC/B,WAAO;AAAA,EACT;AAEA,QAAM,WAAW,gBAAgB,cAAc,QAAQ;AACvD,SAAO,aAAa,OAAO,WAAW,MAAM;AAC9C;AAEO,SAAS,8BACd,UACA,gBACmC;AACnC,MAAI,OAAO,aAAa,aAAa;AACnC,WAAO;AAAA,EACT;AAEA,QAAM,qBAAqB,KAAK;AAAA,IAC9B;AAAA,IACA,KAAK,IAAI,gBAAgB,SAAS,MAAM,MAAM;AAAA,EAChD;AACA,QAAM,eAAe,SAAS,sBAAsB;AACpD,QAAM,gBAAgB,OAAO,iBAAiB,QAAQ;AACtD,QAAM,SAAS,SAAS,cAAc,KAAK;AAC3C,QAAM,SAAS,SAAS,cAAc,MAAM;AAE5C,SAAO,aAAa,eAAe,MAAM;AACzC,SAAO,MAAM,WAAW;AACxB,SAAO,MAAM,OAAO,GAAG,aAAa,IAAI;AACxC,SAAO,MAAM,MAAM,GAAG,aAAa,GAAG;AACtC,SAAO,MAAM,aAAa;AAC1B,SAAO,MAAM,gBAAgB;AAC7B,SAAO,MAAM,WAAW;AAExB,aAAW,gBAAgB,kCAAkC;AAC3D,IAAC,OAAO,MACN,YACF,IAEI,cAEA,YAAY,KAAK;AAAA,EACvB;AACA,SAAO,MAAM,aAAa;AAC1B,SAAO,MAAM,YAAY,cAAc;AACvC,SAAO,MAAM,eAAe,cAAc;AAE1C,QAAM,mBAAmB,SAAS,MAAM,MAAM,GAAG,kBAAkB;AACnE,SAAO,cAAc,iBAAiB,SAAS,IAAI,mBAAmB;AACtE,MAAI,iBAAiB,SAAS,IAAI,GAAG;AACnC,WAAO,OAAO,SAAS,eAAe,QAAQ,CAAC;AAAA,EACjD;AAEA,SAAO,cAAc;AACrB,SAAO,OAAO,MAAM;AACpB,WAAS,KAAK,OAAO,MAAM;AAE3B,MAAI;AACF,UAAM,aAAa,OAAO,sBAAsB;AAChD,UAAM,aAAa,kBAAkB,aAAa;AAElD,WAAO;AAAA,MACL,GAAG,WAAW,OAAO,SAAS;AAAA,MAC9B,GAAG,WAAW,MAAM,SAAS;AAAA,MAC7B;AAAA,IACF;AAAA,EACF,UAAE;AACA,WAAO,OAAO;AAAA,EAChB;AACF;;;AH+OI,SAEI,OAAAI,MAFJ,QAAAC,aAAA;AArTG,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA,mBAAmB,CAAC;AAAA,EACpB;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA8C;AAC5C,QAAM,aAAa;AACnB,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,QAAM,cAAcC,QAAmC,IAAI;AAC3D,QAAM,CAAC,gBAAgB,iBAAiB,IAAIC,UAAS,CAAC;AACtD,QAAM,CAAC,SAAS,UAAU,IAAIA;AAAA,IAC5B,CAAC;AAAA,EACH;AACA,QAAM,CAAC,aAAa,cAAc,IAAIA,UAAS,CAAC;AAChD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,KAAK;AAChD,QAAM,CAAC,WAAW,YAAY,IAAIA;AAAA,IAChC;AAAA,EACF;AACA,QAAM,CAAC,gBAAgB,iBAAiB,IAAIA,UAAS,EAAE,MAAM,GAAG,KAAK,EAAE,CAAC;AACxE,QAAM,CAAC,2BAA2B,4BAA4B,IAC5DA,UAA+B,IAAI;AACrC,QAAM,sBAAsBD,QAAsB,IAAI;AACtD,QAAM,WAAWE;AAAA,IACf,MAAM,8BAA8B,gBAAgB;AAAA,IACpD,CAAC,gBAAgB;AAAA,EACnB;AACA,QAAM,uBAAuBA;AAAA,IAC3B,MAAM,SAAS,mBAAmB;AAAA,IAClC,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,qBAAqBA;AAAA,IACzB,MAAM,wCAAwC,KAAK;AAAA,IACnD,CAAC,KAAK;AAAA,EACR;AACA,QAAM,iBAAiB,+BAA+B,kBAAkB;AACxE,QAAM,QAAQA;AAAA,IACZ,MACE,YACI,yBAAyB,OAAO,gBAAgB,oBAAoB,IACpE;AAAA,IACN,CAAC,sBAAsB,WAAW,gBAAgB,KAAK;AAAA,EACzD;AACA,QAAM,cACJ,UAAU,QACV,MAAM,QAAQ,UAAU,kBACxB,qBAAqB,SAAS;AAChC,QAAM,aACJ,aAAa,gBAAgB,aAAa,QAAQ,SAAS;AAE7D,EAAAC,WAAU,MAAM;AACd,UAAM,gBAAgB,oBAAoB;AAC1C,QAAI,kBAAkB,QAAQ,CAAC,YAAY,SAAS;AAClD;AAAA,IACF;AACA,gBAAY,QAAQ,kBAAkB,eAAe,aAAa;AAClE,wBAAoB,UAAU;AAAA,EAChC,GAAG,CAAC,KAAK,CAAC;AAEV,EAAAA,WAAU,MAAM;AACd,QAAI,CAAC,eAAe,CAAC,OAAO;AAC1B,iBAAW,CAAC,CAAC;AACb,qBAAe,CAAC;AAChB,mBAAa,KAAK;AAClB;AAAA,IACF;AAEA,UAAM,kBAAkB,IAAI,gBAAgB;AAC5C,iBAAa,IAAI;AAEjB,SAAK,4BAA4B,UAAU;AAAA,MACzC,aAAa,gBAAgB;AAAA,MAC7B,SAAS,MAAM;AAAA,MACf;AAAA,MACA,SAAS,MAAM;AAAA,MACf,SAAS;AAAA,QACP,cAAc;AAAA,QACd,WAAW;AAAA,MACb;AAAA,IACF,CAAC,EACE,KAAK,CAAC,gBAAgB;AACrB,UAAI,gBAAgB,OAAO,SAAS;AAClC;AAAA,MACF;AACA,iBAAW,WAAW;AACtB;AAAA,QAAe,CAAC,YACd,YAAY,WAAW,IACnB,IACA,KAAK,IAAI,GAAG,KAAK,IAAI,SAAS,YAAY,SAAS,CAAC,CAAC;AAAA,MAC3D;AAAA,IACF,CAAC,EACA,QAAQ,MAAM;AACb,UAAI,CAAC,gBAAgB,OAAO,SAAS;AACnC,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF,CAAC;AAEH,WAAO,MAAM;AACX,sBAAgB,MAAM;AAAA,IACxB;AAAA,EACF,GAAG,CAAC,YAAY,OAAO,UAAU,aAAa,KAAK,CAAC;AAEpD,EAAAC,iBAAgB,MAAM;AACpB,QAAI,CAAC,YAAY,WAAW,CAAC,gBAAgB;AAC3C,mCAA6B,IAAI;AACjC;AAAA,IACF;AAEA,UAAM,WAAW,YAAY;AAC7B,iCAA6B,6BAA6B,QAAQ,CAAC;AACnE,sBAAkB;AAAA,MAChB,MAAM,SAAS;AAAA,MACf,KAAK,SAAS;AAAA,IAChB,CAAC;AAAA,EACH,GAAG,CAAC,gBAAgB,mBAAmB,KAAK,CAAC;AAE7C,EAAAA,iBAAgB,MAAM;AACpB,QAAI,CAAC,cAAc,CAAC,SAAS,CAAC,YAAY,SAAS;AACjD,mBAAa,IAAI;AACjB;AAAA,IACF;AAEA,UAAM,aAAa;AAAA,MACjB,YAAY;AAAA,MACZ,MAAM;AAAA,IACR;AACA,UAAM,eAAe,YAAY,QAAQ,sBAAsB;AAE/D,QAAI,CAAC,YAAY;AACf,mBAAa;AAAA,QACX,GAAG,aAAa,OAAO;AAAA,QACvB,GAAG,aAAa,SAAS;AAAA,MAC3B,CAAC;AACD;AAAA,IACF;AAEA,iBAAa;AAAA,MACX,GAAG,WAAW;AAAA,MACd,GAAG,WAAW,IAAI,WAAW,aAAa;AAAA,IAC5C,CAAC;AAAA,EACH,GAAG,CAAC,YAAY,YAAY,OAAO,gBAAgB,KAAK,CAAC;AAEzD,EAAAD,WAAU,MAAM;AACd,QAAI,CAAC,cAAc,CAAC,SAAS,CAAC,YAAY,SAAS;AACjD;AAAA,IACF;AAEA,UAAM,WAAW,YAAY;AAC7B,UAAM,kBAAkB,MAAM;AAC5B,YAAM,aAAa,8BAA8B,UAAU,MAAM,EAAE;AACnE,YAAM,eAAe,SAAS,sBAAsB;AAEpD;AAAA,QACE,aACI;AAAA,UACE,GAAG,WAAW;AAAA,UACd,GAAG,WAAW,IAAI,WAAW,aAAa;AAAA,QAC5C,IACA;AAAA,UACE,GAAG,aAAa,OAAO;AAAA,UACvB,GAAG,aAAa,SAAS;AAAA,QAC3B;AAAA,MACN;AAAA,IACF;AAEA,UAAM,iBACJ,OAAO,mBAAmB,cACtB,OACA,IAAI,eAAe,MAAM;AACvB,sBAAgB;AAAA,IAClB,CAAC;AACP,oBAAgB,QAAQ,QAAQ;AAChC,aAAS,iBAAiB,UAAU,iBAAiB,EAAE,SAAS,KAAK,CAAC;AACtE,WAAO,iBAAiB,UAAU,eAAe;AACjD,WAAO,iBAAiB,UAAU,iBAAiB;AAAA,MACjD,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAED,WAAO,MAAM;AACX,sBAAgB,WAAW;AAC3B,eAAS,oBAAoB,UAAU,eAAe;AACtD,aAAO,oBAAoB,UAAU,eAAe;AACpD,aAAO,oBAAoB,UAAU,iBAAiB,IAAI;AAAA,IAC5D;AAAA,EACF,GAAG,CAAC,YAAY,YAAY,KAAK,CAAC;AAElC,QAAM,YAAY,MAAM;AACtB,eAAW,CAAC,CAAC;AACb,mBAAe,CAAC;AAChB,iBAAa,KAAK;AAClB,iBAAa,IAAI;AAAA,EACnB;AAEA,QAAM,eAAe,CAAC,kBAA0B;AAC9C,wBAAoB,UAAU;AAC9B,sBAAkB,aAAa;AAC/B,QAAI,YAAY,SAAS;AACvB,kBAAY,QAAQ,MAAM;AAC1B,kBAAY,QAAQ,kBAAkB,eAAe,aAAa;AAClE,0BAAoB,UAAU;AAAA,IAChC;AAAA,EACF;AAEA,QAAM,wBAAwB,CAC5B,SACA,UACG;AACH,UAAM,eAAe;AACrB,UAAM,SAAS,MAAM,cAAc,sBAAsB;AACzD,UAAM,gBACJ,MAAM,UAAU,OAAO,OAAO,OAAO,QAAQ,IACzC,QAAQ,OACR,QAAQ;AACd,iBAAa,aAAa;AAAA,EAC5B;AAEA,QAAM,yBAAyB,CAC7B,YACG;AACH,UAAM,YAAY,GAAG,MAAM,MAAM,GAAG,QAAQ,IAAI,CAAC,GAAG,MAAM,MAAM,QAAQ,EAAE,CAAC;AAC3E,UAAM,gBAAgB,KAAK,IAAI,QAAQ,MAAM,UAAU,MAAM;AAC7D,wBAAoB,UAAU;AAC9B,aAAS,SAAS;AAClB,sBAAkB,aAAa;AAC/B,WAAO,sBAAsB,MAAM;AACjC,UAAI,CAAC,YAAY,SAAS;AACxB;AAAA,MACF;AACA,kBAAY,QAAQ,MAAM;AAC1B,kBAAY,QAAQ,kBAAkB,eAAe,aAAa;AAClE,0BAAoB,UAAU;AAAA,IAChC,CAAC;AAAA,EACH;AAEA,QAAM,aAAa,CAAC,UAAqC;AACvD,UAAM,eAAe;AAAA,MACnB;AAAA,MACA,YAAY,SAAS,kBAAkB;AAAA,MACvC;AAAA,IACF;AACA,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AACA,UAAM,gBAAgB;AAAA,MACpB,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AACA,UAAM,YAAY,GAAG,MAAM,MAAM,GAAG,aAAa,IAAI,CAAC,GAAG,aAAa,GAAG,MAAM,MAAM,aAAa,EAAE,CAAC;AACrG,UAAM,gBAAgB,aAAa,OAAO,cAAc;AACxD,wBAAoB,UAAU;AAC9B,aAAS,SAAS;AAClB,cAAU;AAAA,EACZ;AAEA,QAAM,gBAAgB,CAAC,UAA8C;AACnE,QAAI,uBAAuB,KAAK,GAAG;AACjC;AAAA,IACF;AAEA,QAAI,QAAQ,WAAW,GAAG;AACxB;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,aAAa;AAC7B,YAAM,eAAe;AACrB,qBAAe,CAAC,aAAa,UAAU,KAAK,QAAQ,MAAM;AAC1D;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,WAAW;AAC3B,YAAM,eAAe;AACrB;AAAA,QACE,CAAC,aAAa,UAAU,IAAI,QAAQ,UAAU,QAAQ;AAAA,MACxD;AACA;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,OAAO;AAChD,YAAM,QAAQ,QAAQ,WAAW;AACjC,UAAI,CAAC,OAAO;AACV;AAAA,MACF;AACA,YAAM,eAAe;AACrB,iBAAW,KAAK;AAChB;AAAA,IACF;AAEA,QAAI,MAAM,QAAQ,UAAU;AAC1B,YAAM,eAAe;AACrB,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,SACE,gBAAAJ,MAAC,SAAI,WAAWM,IAAG,2BAA2B,SAAS,GACpD;AAAA,sBAAkB,4BACjB,gBAAAP;AAAA,MAAC;AAAA;AAAA,QACC,gBAAgB;AAAA,QAChB,iBAAiB;AAAA,QACjB,uBAAuB,KAAK;AAAA,QAC5B,YAAY,eAAe;AAAA,QAC3B,WAAW,eAAe;AAAA,QAC1B,UAAU;AAAA,QACV,eAAe;AAAA;AAAA,IACjB,IACE;AAAA,IACJ,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAW;AAAA,QACX;AAAA,QACA;AAAA,QACA;AAAA,QACA,OACE,iBACI;AAAA,UACE,qBAAqB;AAAA,UACrB,YAAY;AAAA,UACZ,OAAO;AAAA,UACP,UAAU;AAAA,UACV,QAAQ;AAAA,QACV,IACA;AAAA,QAEN;AAAA,QACA,QAAQ,MAAM;AACZ,iBAAO,WAAW,MAAM;AACtB,yBAAa,KAAK;AAClB,sBAAU;AAAA,UACZ,GAAG,GAAG;AAAA,QACR;AAAA,QACA,UAAU,CAAC,UAAU;AACnB,gBAAM,oBAAoB,MAAM,OAAO,kBAAkB;AACzD,gBAAM,gBACJ;AAAA,YACE;AAAA,YACA;AAAA,UACF,KAAK;AACP,cAAI,kBAAkB,mBAAmB;AACvC,kBAAM,OAAO,kBAAkB,eAAe,aAAa;AAAA,UAC7D;AACA,4BAAkB,aAAa;AAC/B,mBAAS,MAAM,OAAO,KAAK;AAAA,QAC7B;AAAA,QACA,SAAS,CAAC,UAAU;AAClB,uBAAa,IAAI;AACjB,gBAAM,oBAAoB,MAAM,OAAO,kBAAkB;AACzD,gBAAM,gBACJ;AAAA,YACE;AAAA,YACA;AAAA,UACF,KAAK;AACP,cAAI,kBAAkB,mBAAmB;AACvC,kBAAM,OAAO,kBAAkB,eAAe,aAAa;AAAA,UAC7D;AACA,4BAAkB,aAAa;AAC/B,4BAAkB;AAAA,YAChB,MAAM,MAAM,OAAO;AAAA,YACnB,KAAK,MAAM,OAAO;AAAA,UACpB,CAAC;AAAA,QACH;AAAA,QACA,WAAW;AAAA,QACX,UAAU,CAAC,UAAU;AACnB,4BAAkB;AAAA,YAChB,MAAM,MAAM,cAAc;AAAA,YAC1B,KAAK,MAAM,cAAc;AAAA,UAC3B,CAAC;AAAA,QACH;AAAA,QACA,UAAU,CAAC,UAAU;AACnB,gBAAM,oBAAoB,MAAM,cAAc,kBAAkB;AAChE,gBAAM,gBACJ;AAAA,YACE;AAAA,YACA;AAAA,UACF,KAAK;AACP,cAAI,kBAAkB,mBAAmB;AACvC,kBAAM,cAAc,kBAAkB,eAAe,aAAa;AAAA,UACpE;AACA,4BAAkB,aAAa;AAAA,QACjC;AAAA;AAAA,IACF;AAAA,IACC;AAAA,IACA,cAAc,YACb,gBAAAA;AAAA,MAACQ;AAAA,MAAA;AAAA,QACC,MAAI;AAAA,QACJ,WAAU;AAAA,QACV,mBAAmB,CAAC,WAAW;AAAA,QAC/B,WAAW;AAAA,UACT,MAAM;AAAA,UACN,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,eAAe;AAAA,YACb,OAAO;AAAA,YACP,QAAQ;AAAA,UACV;AAAA,QACF;AAAA,QAEC,kBAAQ,SAAS,IAChB,QAAQ,IAAI,CAAC,OAAO,UAClB,gBAAAR;AAAA,UAAC;AAAA;AAAA,YAEC,OAAO,MAAM;AAAA,YACb,UAAU,UAAU;AAAA,YACpB,UAAU,MAAM;AAAA,YAChB,SAAS,MAAM;AAAA,YACf,UAAU,MAAM,WAAW,KAAK;AAAA;AAAA,UAL3B,GAAG,MAAM,UAAU,IAAI,MAAM,GAAG;AAAA,QAMvC,CACD,IAED,gBAAAA,KAAC,SAAI,WAAU,gEACZ,sBAAY,KAAK,eAAe,KAAK,gBACxC;AAAA;AAAA,IAEJ,IACE;AAAA,KACN;AAEJ;;;AIvWM,gBAAAS,YAAA;AAvGN,IAAM,YAA2B;AAAA,EAC/B,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,SAAS;AAAA,EACT,UAAU;AAAA,EACV,KAAK;AAAA,EACL,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,YAAY;AACd;AAEA,IAAM,cACJ;AAAA,EACE,QAAQ;AAAA,IACN,YACE;AAAA,IACF,OAAO;AAAA,IACP,QAAQ;AAAA,EACV;AAAA,EACA,SAAS;AAAA,IACP,YACE;AAAA,IACF,OACE;AAAA,IACF,QAAQ;AAAA,IACR,gBAAgB;AAAA,EAClB;AAAA,EACA,UAAU;AAAA,IACR,YACE;AAAA,IACF,OACE;AAAA,IACF,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AAAA,EACA,SAAS;AAAA,IACP,YACE;AAAA,IACF,OACE;AAAA,IACF,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;AACF;AAEF,SAAS,kBACJ,OACiB;AACpB,QAAM,QAAQ,MAAM,OAAO,OAAO,EAAE,KAAK,GAAG,EAAE,KAAK;AACnD,SAAO,SAAS;AAClB;AAEO,SAAS,wBAA6C;AAAA,EAC3D;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAyD;AACvD,QAAM,OAAO,2BAA2B,SAAS,QAAQ;AACzD,QAAM,UAA0D;AAAA,IAC9D;AAAA,IACA,UAAU;AAAA,EACZ;AACA,QAAM,QACJ,cAAc,OAAO,KACrB,8BAA8B;AAAA,IAC5B,GAAG;AAAA,IACH,OAAO,KAAK;AAAA,EACd,CAAC;AACH,QAAM,eAAe,SAAS,KAAK;AACnC,QAAM,cAAc,CAAC,UAAmC;AACtD,QAAI,CAAC,KAAK,aAAa;AACrB,YAAM,eAAe;AACrB;AAAA,IACF;AACA,cAAU,OAAO;AAAA,EACnB;AAEA,QAAM,cAAc;AAAA,IAClB,aAAa,KAAK,UAAU,aAAa;AAAA,IACzC,iBAAiB,CAAC,KAAK,eAAe;AAAA,IACtC,WAAW;AAAA,MACT;AAAA,MACA,4BAA4B,KAAK,KAAK;AAAA,MACtC;AAAA,IACF;AAAA,IACA,oBAAoB,QAAQ;AAAA,IAC5B,cAAc,KAAK;AAAA,IACnB,OAAO;AAAA,MACL,GAAG;AAAA,MACH,GAAG,YAAY,KAAK,KAAK;AAAA,IAC3B;AAAA,IACA,OAAO;AAAA,EACT;AAEA,MAAI,KAAK,eAAe,SAAS;AAC/B,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ,SAAS,CAAC,UAAU;AAClB,sBAAY,KAAK;AAAA,QACnB;AAAA,QACA,OAAO;AAAA,UACL,GAAG,YAAY;AAAA,UACf,YAAY;AAAA,UACZ,MAAM;AAAA,QACR;AAAA,QACA,MAAK;AAAA,QAEJ;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SAAO,gBAAAA,KAAC,UAAM,GAAG,aAAc,iBAAM;AACvC;;;ACnJA;AAAA,EACE,eAAAC;AAAA,EACA,WAAAC;AAAA,EACA,kBAAAC;AAAA,EACA,kBAAAC;AAAA,OACK;AACP,SAAS,MAAAC,WAAU;;;ACMZ,SAAS,oCACd,SACiC;AACjC,QAAM,WAA4C,CAAC;AACnD,MAAI,SAAS;AAEb,aAAW,SAAS,0BAA0B,OAAO,GAAG;AACtD,QAAI,MAAM,QAAQ,QAAQ;AACxB,eAAS,KAAK;AAAA,QACZ,MAAM,QAAQ,MAAM,QAAQ,MAAM,KAAK;AAAA,QACvC,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAEA,aAAS,KAAK;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,OAAO,MAAM,SAAS,MAAM;AAAA,MAC5B,MAAM;AAAA,IACR,CAAC;AACD,aAAS,MAAM;AAAA,EACjB;AAEA,MAAI,SAAS,QAAQ,QAAQ;AAC3B,aAAS,KAAK;AAAA,MACZ,MAAM,QAAQ,MAAM,MAAM;AAAA,MAC1B,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;ADgBQ,gBAAAC,MAuIJ,QAAAC,aAvII;AAxBR,IAAM,sBAAsB;AAC5B,IAAMC,2CAA0C;AAEzC,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAqD;AACnD,QAAM,kBAAkB,yBAAyB,KAAK,EAAE,KAAK;AAE7D,MAAI,CAAC,iBAAiB;AACpB,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,gBAChB,MAAM,QAAQ,EACd,IAAI,CAAC,cAAc,UAAU,KAAK,CAAC,EACnC,OAAO,OAAO;AAEjB,SACE,gBAAAF,KAAC,SAAI,WAAWG,IAAG,aAAa,SAAS,GACtC,qBAAW,IAAI,CAAC,WAAW,mBAC1B,gBAAAH;AAAA,IAAC;AAAA;AAAA,MACC,WAAWG,IAAG,uBAAuB,kBAAkB;AAAA,MAGtD;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA;AAAA,IANK,GAAG,cAAc,IAAI,SAAS;AAAA,EAOrC,CACD,GACH;AAEJ;AAEA,SAAS,6BACP,SACA,0BAGA,iBACe;AACf,QAAM,QAAuB,CAAC;AAC9B,QAAM,WAAW,oCAAoC,OAAO;AAE5D,WAAS,QAAQ,CAAC,SAAS,UAAU;AACnC,QAAI,QAAQ,SAAS,QAAQ;AAC3B,YAAM,KAAK,gBAAAH,KAAC,UAA4B,kBAAQ,QAA1B,QAAQ,KAAK,EAAkB,CAAO;AAC5D;AAAA,IACF;AAEA,UAAM;AAAA,MACJ,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAM,QAAQ;AAAA,UAEd,OAAO,QAAQ;AAAA,UACf;AAAA,UACA;AAAA;AAAA,QAHK,QAAQ,KAAK,IAAI,QAAQ,IAAI;AAAA,MAIpC;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AACT;AAEA,SAAS,2BAA2B;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAOgB;AACd,QAAM,cAAc,KAAK,KAAK;AAC9B,QAAM,UAAU,yBAAyB,aAAa,KAAK;AAE3D,MAAI,SAAS;AACX,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,SACE,kBACI,CAAC,EAAE,SAAAI,SAAQ,MAAM;AACf,eAAK,gBAAgBA,QAAO;AAAA,QAC9B,IACA;AAAA;AAAA,IAER;AAAA,EAEJ;AAEA,MAAI,CAAC,aAAa;AAChB,WAAO,gBAAAJ,KAAC,UAAM,iBAAM;AAAA,EACtB;AAEA,MACE,oBAAoB,KAAK,WAAW,KACpC,CAAC,sBAAsB,WAAW,GAClC;AACA,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,MAAM;AAAA,QACN,KAAI;AAAA,QACJ,QAAO;AAAA,QAEN;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,QAAM,OAAO,YAAY,SAAS,GAAG,IAAI,WAAW;AACpD,QAAM,OAAO,0BAA0B,aAAa,IAAI;AAExD,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA;AAAA,EACF;AAEJ;AAEA,SAAS,2BAA2B;AAAA,EAClC;AAAA,EACA;AACF,GAKgB;AACd,QAAM,eAAe;AAAA,IACnB,UAAU;AAAA,IACV,UAAU;AAAA,EACZ;AACA,QAAM,UACJ,gBAAAA;AAAA,IAACK;AAAA,IAAA;AAAA,MACC,WAAWH;AAAA,MACX,UAAU,UAAU;AAAA,MACpB,MAAK;AAAA,MACL,OAAO,aAAa;AAAA,MACpB,WAAW;AAAA;AAAA,EACb;AAGF,SACE,gBAAAD,MAACK,UAAA,EACC;AAAA,oBAAAN,KAACO,iBAAA,EAAe,SAAO,MACpB,qCACC,gBAAAP;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,MAAK;AAAA,QACL,SAAS,MAAM;AACb,eAAK,yBAAyB,SAAS;AAAA,QACzC;AAAA,QAEC;AAAA;AAAA,IACH,IAEA,gBAAAA,KAAC,UAAK,WAAU,yCACb,mBACH,GAEJ;AAAA,IACA,gBAAAA;AAAA,MAACQ;AAAA,MAAA;AAAA,QACC,WAAU;AAAA,QACV,YAAY;AAAA,QAEX,uBAAa;AAAA;AAAA,IAChB;AAAA,KACF;AAEJ;","names":["useEffect","useState","jsx","mergeAttributes","Node","ReactNodeViewRenderer","NodeViewWrapper","MentionPill","jsx","jsxs","NodeViewWrapper","MentionPill","Node","mergeAttributes","ReactNodeViewRenderer","jsx","jsxs","useState","editor","useEffect","useEffect","useLayoutEffect","useMemo","useRef","useState","ViewportMenuSurface","cn","MentionPill","cn","jsx","jsxs","richTextWorkspaceReferencePillClassName","jsx","jsxs","useRef","useState","useMemo","useEffect","useLayoutEffect","cn","ViewportMenuSurface","jsx","MentionPill","Tooltip","TooltipContent","TooltipTrigger","cn","jsx","jsxs","richTextWorkspaceReferencePillClassName","cn","mention","MentionPill","Tooltip","TooltipTrigger","TooltipContent"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createRichTextMentionHref, createRichTextMentionMarkdown, extractPlainTextFromContent, extractPlainTextWithoutFilesFromContent, extractRichTextMentionsFromContent, isRichTextMentionHref, normalizeRichTextContent, parseRichTextContentToDocument, parseRichTextMentionHref, removeRichTextMentionFromContent, serializeRichTextDocumentToContent } from './core/index.js';
|
|
2
2
|
export { R as RichTextI18nKey, a as RichTextI18nRuntime, c as createDefaultRichTextI18nRuntime, b as createRichTextI18nRuntime, r as richTextI18nModule, d as richTextI18nNamespace, e as richTextI18nResources } from './richTextI18n-CUeqHuEQ.js';
|
|
3
3
|
import '@tiptap/core';
|
|
4
|
-
import './mention-
|
|
4
|
+
import './mention-DJq2OJ4K.js';
|
|
5
5
|
import '@tutti-os/ui-i18n-runtime';
|
package/dist/index.js
CHANGED
|
@@ -36,6 +36,11 @@ interface RichTextMentionPresentation {
|
|
|
36
36
|
statusLabel?: string;
|
|
37
37
|
statusPulse?: string;
|
|
38
38
|
userAvatarPlaceholderUrl?: string;
|
|
39
|
+
/**
|
|
40
|
+
* Optional display hint for surfaces that expose a "show references" affordance
|
|
41
|
+
* on workspace-app mentions. Presentation is not serialized into markdown.
|
|
42
|
+
*/
|
|
43
|
+
referencesListSupported?: string;
|
|
39
44
|
}
|
|
40
45
|
interface RichTextMentionInsert {
|
|
41
46
|
entityId: string;
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RichTextMarkdownLinkInsertResult, RichTextMentionTriggerInsertResult, RichTextTextInsertResult, RichTextTriggerProvider, RichTextTriggerInsertResult, RichTextTriggerRegistry } from '../types/index.js';
|
|
2
|
-
import { b as RichTextMentionInsert, R as RichTextMentionAttrs, c as RichTextMentionPlugin, l as RichTextResolvedMention, m as RichTextResolvedMentionView, h as RichTextMentionRegistry } from '../mention-
|
|
2
|
+
import { b as RichTextMentionInsert, R as RichTextMentionAttrs, c as RichTextMentionPlugin, l as RichTextResolvedMention, m as RichTextResolvedMentionView, h as RichTextMentionRegistry } from '../mention-DJq2OJ4K.js';
|
|
3
3
|
|
|
4
4
|
declare function createRichTextTextInsertResult(text: string): RichTextTextInsertResult;
|
|
5
5
|
declare function createRichTextMarkdownLinkInsertResult(label: string, href: string): RichTextMarkdownLinkInsertResult;
|
package/dist/plugins/index.js
CHANGED
|
@@ -11,8 +11,8 @@ import {
|
|
|
11
11
|
isRichTextMentionAttrs,
|
|
12
12
|
renderRichTextTriggerInsertResult,
|
|
13
13
|
resolveRichTextMentionView
|
|
14
|
-
} from "../chunk-
|
|
15
|
-
import "../chunk-
|
|
14
|
+
} from "../chunk-RHEJPXOW.js";
|
|
15
|
+
import "../chunk-W2IS5BLZ.js";
|
|
16
16
|
export {
|
|
17
17
|
createRichTextMarkdownLinkInsertResult,
|
|
18
18
|
createRichTextMentionAttrs,
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { b as RichTextMentionInsert, a as RichTextMentionIdentity, k as RichTextMentionResolved } from '../mention-
|
|
2
|
-
export { R as RichTextMentionAttrs, c as RichTextMentionPlugin, d as RichTextMentionPluginContext, e as RichTextMentionPresentation, f as RichTextMentionQueryInput, g as RichTextMentionQueryMatch, h as RichTextMentionRegistry, i as RichTextMentionRenderState, j as RichTextMentionResolveInput, l as RichTextResolvedMention, m as RichTextResolvedMentionView, n as RichTextSuggestionTrigger } from '../mention-
|
|
1
|
+
import { b as RichTextMentionInsert, a as RichTextMentionIdentity, k as RichTextMentionResolved } from '../mention-DJq2OJ4K.js';
|
|
2
|
+
export { R as RichTextMentionAttrs, c as RichTextMentionPlugin, d as RichTextMentionPluginContext, e as RichTextMentionPresentation, f as RichTextMentionQueryInput, g as RichTextMentionQueryMatch, h as RichTextMentionRegistry, i as RichTextMentionRenderState, j as RichTextMentionResolveInput, l as RichTextResolvedMention, m as RichTextResolvedMentionView, n as RichTextSuggestionTrigger } from '../mention-DJq2OJ4K.js';
|
|
3
3
|
|
|
4
4
|
type RichTextTrigger = "@" | "/" | "$";
|
|
5
5
|
type RichTextTriggerBoundary = "punctuation" | "whitespace";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tutti-os/ui-rich-text",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.19",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"directory": "packages/ui/rich-text"
|
|
45
45
|
},
|
|
46
46
|
"dependencies": {
|
|
47
|
-
"@tutti-os/ui-i18n-runtime": "0.0.
|
|
48
|
-
"@tutti-os/ui-system": "0.0.
|
|
47
|
+
"@tutti-os/ui-i18n-runtime": "0.0.19",
|
|
48
|
+
"@tutti-os/ui-system": "0.0.19",
|
|
49
49
|
"@tiptap/core": "^3.23.6",
|
|
50
50
|
"@tiptap/extension-document": "^3.23.6",
|
|
51
51
|
"@tiptap/extension-hard-break": "^3.23.6",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/extensions/names.ts","../src/core/richTextMarkdownLinks.ts","../src/core/richTextDocument.ts"],"sourcesContent":["export const workspaceReferenceNodeName = \"workspaceReference\";\nexport const mentionReferenceNodeName = \"mentionReference\";\n","export interface RichTextMarkdownLinkMatch {\n href: string;\n index: number;\n label: string;\n source: string;\n to: number;\n}\n\nexport function* findRichTextMarkdownLinks(\n value: string\n): Generator<RichTextMarkdownLinkMatch> {\n let cursor = 0;\n\n while (cursor < value.length) {\n const labelStart = value.indexOf(\"[\", cursor);\n if (labelStart < 0) {\n return;\n }\n if (labelStart > 0 && value[labelStart - 1] === \"!\") {\n cursor = labelStart + 1;\n continue;\n }\n\n const labelEnd = findMarkdownLabelEnd(value, labelStart + 1);\n if (labelEnd < 0 || value[labelEnd + 1] !== \"(\") {\n cursor = labelStart + 1;\n continue;\n }\n\n const hrefStart = labelEnd + 2;\n const hrefEnd = findMarkdownHrefEnd(value, hrefStart);\n if (hrefEnd < 0) {\n cursor = labelStart + 1;\n continue;\n }\n\n yield {\n href: unescapeMarkdownLinkText(value.slice(hrefStart, hrefEnd)),\n index: labelStart,\n label: unescapeMarkdownLinkText(value.slice(labelStart + 1, labelEnd)),\n source: value.slice(labelStart, hrefEnd + 1),\n to: hrefEnd + 1\n };\n cursor = hrefEnd + 1;\n }\n}\n\nfunction unescapeMarkdownLinkText(value: string): string {\n return value.replace(/\\\\([\\\\[\\]()])/g, \"$1\");\n}\n\nfunction findMarkdownLabelEnd(value: string, cursor: number): number {\n let escaped = false;\n\n for (let index = cursor; index < value.length; index += 1) {\n const char = value[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (char === \"]\") {\n return index;\n }\n }\n\n return -1;\n}\n\nfunction findMarkdownHrefEnd(value: string, cursor: number): number {\n let escaped = false;\n let depth = 0;\n\n for (let index = cursor; index < value.length; index += 1) {\n const char = value[index];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (char === \"\\\\\") {\n escaped = true;\n continue;\n }\n if (char === \"(\") {\n depth += 1;\n continue;\n }\n if (char !== \")\") {\n continue;\n }\n if (depth === 0) {\n return index;\n }\n depth -= 1;\n }\n\n return -1;\n}\n","import type { JSONContent } from \"@tiptap/core\";\nimport {\n mentionReferenceNodeName,\n workspaceReferenceNodeName\n} from \"../extensions/names.ts\";\nimport type {\n RichTextMentionAttrs,\n RichTextMentionIdentity\n} from \"../types/mention.ts\";\nimport {\n findRichTextMarkdownLinks,\n type RichTextMarkdownLinkMatch\n} from \"./richTextMarkdownLinks.ts\";\n\nexport type RichTextLinkRef = {\n name: string;\n path: string;\n href: string;\n kind: \"file\" | \"folder\";\n};\n\nexport type RichTextLinkInput = {\n name?: string | null;\n path: string;\n kind?: \"file\" | \"folder\";\n};\n\nexport type RichTextMentionRef = RichTextMentionAttrs;\nexport type RichTextDocument = JSONContent;\n\nconst MARKDOWN_IMAGE_PATTERN = /!\\[([^\\]]*)\\]\\(([^)\\s]+)\\)/g;\nconst EXTERNAL_LINK_PREFIX = /^(?:[a-z]+:)?\\/\\//i;\nconst MENTION_LINK_PREFIX = /^mention:\\/\\//i;\nconst MENTION_LEGACY_QUERY_KEYS = new Set([\"kind\", \"link\", \"v\", \"version\"]);\n\ntype LegacyJSONContentNode = {\n type?: string;\n text?: string;\n attrs?: Record<string, unknown>;\n content?: LegacyJSONContentNode[];\n};\n\nfunction normalizeLineEndings(value: string): string {\n return value.replace(/\\r\\n?/g, \"\\n\");\n}\n\nfunction normalizeContentString(value?: string | null): string {\n const trimmed = normalizeLineEndings(value ?? \"\").trim();\n if (!trimmed) {\n return \"\";\n }\n const markdown = convertLegacyDocumentString(trimmed);\n return markdown || trimmed;\n}\n\nexport function normalizeRichTextContent(value?: string | null): string {\n return normalizeContentString(value);\n}\n\nfunction convertLegacyDocumentString(value: string): string {\n try {\n const parsed = JSON.parse(value) as LegacyJSONContentNode;\n if (parsed?.type !== \"doc\" || !Array.isArray(parsed.content)) {\n return \"\";\n }\n return renderLegacyNodesToMarkdown(parsed.content).trim();\n } catch {\n return \"\";\n }\n}\n\nfunction renderLegacyNodesToMarkdown(nodes: LegacyJSONContentNode[]): string {\n return nodes\n .map((node) => renderLegacyNodeToMarkdown(node))\n .filter((part) => part.length > 0)\n .join(\"\\n\\n\");\n}\n\nfunction renderLegacyNodeToMarkdown(\n node: LegacyJSONContentNode | null | undefined\n): string {\n if (!node) {\n return \"\";\n }\n if (node.type === \"text\") {\n return node.text ?? \"\";\n }\n if (node.type === \"workspaceFileLink\") {\n const attrs = node.attrs ?? {};\n const kind = attrs.kind === \"folder\" ? \"folder\" : \"file\";\n const hrefValue =\n (typeof attrs.href === \"string\" ? attrs.href : undefined) ||\n (typeof attrs.path === \"string\" ? attrs.path : undefined) ||\n \"\";\n const href = normalizeRichTextLinkHref(hrefValue, kind);\n const label =\n (typeof attrs.name === \"string\" ? attrs.name : undefined)?.trim() ||\n href.split(\"/\").filter(Boolean).at(-1) ||\n href;\n return href && label ? `[${label}](${href})` : label;\n }\n if (Array.isArray(node.content)) {\n const inline = node.content\n .map((child) => renderLegacyNodeToMarkdown(child))\n .filter((part) => part.length > 0)\n .join(\"\")\n .trim();\n if (!inline) {\n return \"\";\n }\n if (node.type === \"paragraph\") {\n return inline;\n }\n return inline;\n }\n return \"\";\n}\n\nfunction normalizeWorkspacePath(\n pathOrHref: string,\n kind: \"file\" | \"folder\"\n): string {\n const trimmed = pathOrHref.trim();\n if (!trimmed) {\n return \"\";\n }\n if (kind === \"folder\" && !trimmed.endsWith(\"/\")) {\n return `${trimmed}/`;\n }\n return trimmed;\n}\n\nfunction isWorkspaceReferenceHref(href: string): boolean {\n const trimmed = href.trim();\n if (\n !trimmed ||\n MENTION_LINK_PREFIX.test(trimmed) ||\n EXTERNAL_LINK_PREFIX.test(trimmed)\n ) {\n return false;\n }\n return true;\n}\n\nexport function isRichTextMentionHref(href: string): boolean {\n return MENTION_LINK_PREFIX.test(href.trim());\n}\n\nfunction normalizeMentionLabel(value: string): string {\n return value.trim().replace(/^@+/, \"\").trim();\n}\n\nfunction createMentionQueryParams(\n mention: RichTextMentionIdentity\n): URLSearchParams {\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(mention.scope ?? {}).sort(\n ([left], [right]) => left.localeCompare(right)\n )) {\n const nextKey = key.trim();\n const nextValue = value.trim();\n if (\n !nextKey ||\n !nextValue ||\n MENTION_LEGACY_QUERY_KEYS.has(nextKey) ||\n nextKey.startsWith(\"meta.\")\n ) {\n continue;\n }\n params.set(nextKey, nextValue);\n }\n return params;\n}\n\nexport function createRichTextMentionHref(\n mention: RichTextMentionIdentity\n): string {\n const providerId = mention.providerId.trim();\n const entityId = mention.entityId.trim();\n const label = normalizeMentionLabel(mention.label);\n if (!providerId || !entityId || !label) {\n return \"\";\n }\n\n const params = createMentionQueryParams(mention);\n const queryString = params.toString();\n const pathname = `${encodeURIComponent(providerId)}/${encodeURIComponent(entityId)}`;\n return queryString\n ? `mention://${pathname}?${queryString}`\n : `mention://${pathname}`;\n}\n\nexport function createRichTextMentionMarkdown(\n mention: RichTextMentionIdentity\n): string {\n const label = normalizeMentionLabel(mention.label);\n const href = createRichTextMentionHref(mention);\n if (!label || !href) {\n return \"\";\n }\n return `[${escapeMarkdownLinkLabel(`@${label}`)}](${escapeMarkdownLinkHref(href)})`;\n}\n\nexport function parseRichTextMentionHref(\n href: string,\n label?: string | null\n): RichTextMentionRef | null {\n const trimmedHref = href.trim();\n if (!isRichTextMentionHref(trimmedHref)) {\n return null;\n }\n\n try {\n const parsed = new URL(trimmedHref);\n const providerId = decodeURIComponent(parsed.hostname).trim();\n const encodedEntityId = parsed.pathname.replace(/^\\/+/, \"\");\n const entityId = decodeURIComponent(encodedEntityId).trim();\n const nextLabel = normalizeMentionLabel(label?.trim() ?? \"\");\n\n if (\n !providerId ||\n !encodedEntityId ||\n encodedEntityId.includes(\"/\") ||\n !entityId ||\n !nextLabel\n ) {\n return null;\n }\n\n const scopeEntries: Array<readonly [string, string]> = [];\n for (const [key, value] of parsed.searchParams.entries()) {\n const scopeKey = key.trim();\n const scopeValue = value.trim();\n if (\n !scopeKey ||\n MENTION_LEGACY_QUERY_KEYS.has(scopeKey) ||\n scopeKey.startsWith(\"meta.\")\n ) {\n return null;\n }\n if (scopeValue) {\n scopeEntries.push([scopeKey, scopeValue]);\n }\n }\n\n const mention: RichTextMentionRef = {\n trigger: \"@\",\n providerId,\n entityId,\n label: nextLabel\n };\n if (scopeEntries.length > 0) {\n mention.scope = Object.fromEntries(scopeEntries);\n }\n return mention;\n } catch {\n return null;\n }\n}\n\nexport function normalizeRichTextLinkHref(\n pathOrHref: string,\n kind: \"file\" | \"folder\" = \"file\"\n): string {\n return normalizeWorkspacePath(pathOrHref, kind);\n}\n\nexport function createRichTextLinkMarkdown(input: RichTextLinkInput): string {\n const kind = input.kind === \"folder\" ? \"folder\" : \"file\";\n const href = normalizeRichTextLinkHref(input.path, kind);\n const displayName =\n input.name?.trim() ||\n href.split(\"/\").filter(Boolean).at(-1) ||\n href ||\n input.path.trim();\n if (!href || !displayName) {\n return \"\";\n }\n return `[${escapeMarkdownLinkLabel(displayName)}](${escapeMarkdownLinkHref(href)})`;\n}\n\nexport function appendRichTextLinksToContent(\n value: string | null | undefined,\n refs: readonly RichTextLinkInput[]\n): string {\n const content = normalizeContentString(value);\n const existing = new Set(\n extractRichTextLinksFromContent(content).map((ref) => ref.path)\n );\n const rendered = refs\n .map((ref) => {\n const kind = ref.kind === \"folder\" ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(ref.path, kind);\n if (!path || existing.has(path)) {\n return \"\";\n }\n existing.add(path);\n return createRichTextLinkMarkdown({ ...ref, path, kind });\n })\n .filter(Boolean);\n\n if (rendered.length === 0) {\n return content;\n }\n return content ? `${content} ${rendered.join(\" \")}` : rendered.join(\" \");\n}\n\nexport function extractRichTextLinksFromContent(\n value: string | null | undefined\n): RichTextLinkRef[] {\n const content = normalizeContentString(value);\n const refs = new Map<string, RichTextLinkRef>();\n for (const match of findRichTextMarkdownLinks(content)) {\n const name = match.label.trim();\n const href = match.href.trim();\n if (!name || !isWorkspaceReferenceHref(href)) {\n continue;\n }\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n const path = normalizeRichTextLinkHref(href, kind);\n if (!path || refs.has(path)) {\n continue;\n }\n refs.set(path, {\n name,\n path,\n href: path,\n kind\n });\n }\n return [...refs.values()];\n}\n\nexport function extractRichTextMentionsFromContent(\n value: string | null | undefined\n): RichTextMentionRef[] {\n const content = normalizeContentString(value);\n const refs = new Map<string, RichTextMentionRef>();\n\n for (const match of findRichTextMarkdownLinks(content)) {\n const label = match.label.trim();\n const href = match.href.trim();\n const mention = parseRichTextMentionHref(href, label);\n if (!mention) {\n continue;\n }\n const mentionKey = [\n mention.providerId,\n mention.entityId,\n JSON.stringify(\n Object.fromEntries(\n Object.entries(mention.scope ?? {}).sort(([left], [right]) =>\n left.localeCompare(right)\n )\n )\n )\n ].join(\":\");\n if (refs.has(mentionKey)) {\n continue;\n }\n refs.set(mentionKey, mention);\n }\n\n return [...refs.values()];\n}\n\nexport function removeRichTextMentionFromContent(\n content: string,\n mention: Pick<RichTextMentionAttrs, \"providerId\" | \"entityId\">\n): string {\n const providerId = mention.providerId.trim();\n const entityId = mention.entityId.trim();\n if (!providerId || !entityId) {\n return normalizeContentString(content);\n }\n\n const normalized = normalizeContentString(content);\n const next = replaceRichTextMarkdownLinks(normalized, (match) => {\n const parsedMention = parseRichTextMentionHref(match.href, match.label);\n if (!parsedMention) {\n return match.source;\n }\n return parsedMention.providerId === providerId &&\n parsedMention.entityId === entityId\n ? \"\"\n : match.source;\n });\n\n return next\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function removeRichTextLinkFromContent(\n content: string,\n path: string\n): string {\n const targetPath = path.trim();\n if (!targetPath) {\n return normalizeContentString(content);\n }\n const normalized = normalizeContentString(content);\n const next = replaceRichTextMarkdownLinks(normalized, (match) => {\n const href = match.href.trim();\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n const refPath = normalizeRichTextLinkHref(href, kind);\n return refPath === targetPath ? \"\" : match.source;\n });\n return next\n .replace(/[ \\t]+\\n/g, \"\\n\")\n .replace(/\\n[ \\t]+/g, \"\\n\")\n .replace(/[ \\t]{2,}/g, \" \")\n .replace(/\\n{3,}/g, \"\\n\\n\")\n .trim();\n}\n\nexport function extractPlainTextFromContent(value?: string | null): string {\n const content = normalizeContentString(value);\n if (!content) {\n return \"\";\n }\n return replaceRichTextMarkdownLinks(\n content.replace(MARKDOWN_IMAGE_PATTERN, \" $1 \"),\n (match) => ` ${match.label} `\n )\n .replace(/^[\\s>*#+-]+/gm, \" \")\n .replace(/`([^`]+)`/g, \" $1 \")\n .replace(/[*_~]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function extractPlainTextWithoutFilesFromContent(\n value?: string | null\n): string {\n const content = normalizeContentString(value);\n if (!content) {\n return \"\";\n }\n return replaceRichTextMarkdownLinks(\n content.replace(MARKDOWN_IMAGE_PATTERN, \" \"),\n () => \" \"\n )\n .replace(/^[\\s>*#+-]+/gm, \" \")\n .replace(/`([^`]+)`/g, \" $1 \")\n .replace(/[*_~]/g, \" \")\n .replace(/\\s+/g, \" \")\n .trim();\n}\n\nexport function parseRichTextContentToDocument(\n value?: string | null\n): RichTextDocument {\n const content = normalizeContentString(value);\n if (!content) {\n return {\n type: \"doc\",\n content: [{ type: \"paragraph\" }]\n };\n }\n\n const paragraphs = content\n .split(/\\n{2,}/)\n .map((paragraph) => createRichTextParagraphNode(paragraph))\n .filter((paragraph) => Array.isArray(paragraph.content));\n\n return {\n type: \"doc\",\n content: paragraphs.length > 0 ? paragraphs : [{ type: \"paragraph\" }]\n };\n}\n\nexport function serializeRichTextDocumentToContent(\n document: RichTextDocument\n): string {\n const paragraphs = (document.content ?? [])\n .map((node) => serializeRichTextBlockNode(node))\n .filter((value) => value.length > 0);\n\n return paragraphs.join(\"\\n\\n\").trim();\n}\n\nfunction createRichTextParagraphNode(paragraph: string): JSONContent {\n return {\n type: \"paragraph\",\n content: createRichTextInlineNodes(paragraph)\n };\n}\n\nfunction createRichTextInlineNodes(text: string): JSONContent[] {\n const content: JSONContent[] = [];\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(text)) {\n const { index, source } = match;\n if (index > cursor) {\n appendPlainTextNodes(content, text.slice(cursor, index));\n }\n\n const label = match.label.trim();\n const href = match.href.trim();\n const mention = parseRichTextMentionHref(href, label);\n if (mention) {\n content.push({\n type: mentionReferenceNodeName,\n attrs: mention\n });\n } else if (label && isWorkspaceReferenceHref(href)) {\n const kind = href.endsWith(\"/\") ? \"folder\" : \"file\";\n content.push({\n type: workspaceReferenceNodeName,\n attrs: {\n kind,\n label,\n path: normalizeRichTextLinkHref(href, kind)\n }\n });\n } else {\n appendPlainTextNodes(content, source);\n }\n\n cursor = match.to;\n }\n\n if (cursor < text.length) {\n appendPlainTextNodes(content, text.slice(cursor));\n }\n\n return content;\n}\n\nfunction replaceRichTextMarkdownLinks(\n value: string,\n replace: (match: RichTextMarkdownLinkMatch) => string\n): string {\n let nextValue = \"\";\n let cursor = 0;\n\n for (const match of findRichTextMarkdownLinks(value)) {\n nextValue += value.slice(cursor, match.index);\n nextValue += replace(match);\n cursor = match.to;\n }\n\n return `${nextValue}${value.slice(cursor)}`;\n}\n\nfunction escapeMarkdownLinkLabel(value: string): string {\n return value.replace(/[\\\\[\\]]/g, \"\\\\$&\");\n}\n\nfunction escapeMarkdownLinkHref(value: string): string {\n return value.replace(/[\\\\()]/g, \"\\\\$&\");\n}\n\nfunction appendPlainTextNodes(content: JSONContent[], text: string): void {\n if (!text) {\n return;\n }\n\n const lines = text.split(\"\\n\");\n lines.forEach((line, index) => {\n if (line.length > 0) {\n content.push({\n type: \"text\",\n text: line\n });\n }\n if (index < lines.length - 1) {\n content.push({ type: \"hardBreak\" });\n }\n });\n}\n\nfunction serializeRichTextBlockNode(node: JSONContent): string {\n if (node.type === \"paragraph\") {\n return serializeRichTextInlineNodes(node.content ?? []);\n }\n return serializeRichTextInlineNodes(node.content ?? []);\n}\n\nfunction serializeRichTextInlineNodes(nodes: readonly JSONContent[]): string {\n return nodes\n .map((node) => {\n if (node.type === \"text\") {\n return typeof node.text === \"string\" ? node.text : \"\";\n }\n if (node.type === \"hardBreak\") {\n return \"\\n\";\n }\n if (node.type === workspaceReferenceNodeName) {\n const attrs = node.attrs ?? {};\n return createRichTextLinkMarkdown({\n kind: attrs.kind === \"folder\" ? \"folder\" : \"file\",\n name: typeof attrs.label === \"string\" ? attrs.label : \"\",\n path: typeof attrs.path === \"string\" ? attrs.path : \"\"\n });\n }\n if (node.type === mentionReferenceNodeName) {\n const attrs = node.attrs ?? {};\n const label = typeof attrs.label === \"string\" ? attrs.label.trim() : \"\";\n const providerId =\n typeof attrs.providerId === \"string\" ? attrs.providerId.trim() : \"\";\n const entityId =\n typeof attrs.entityId === \"string\" ? attrs.entityId.trim() : \"\";\n if (!label || !providerId || !entityId) {\n return \"\";\n }\n const scope =\n attrs.scope && typeof attrs.scope === \"object\"\n ? (attrs.scope as Record<string, string>)\n : undefined;\n return createRichTextMentionMarkdown({\n entityId,\n label,\n providerId,\n scope\n });\n }\n\n if (Array.isArray(node.content)) {\n return serializeRichTextInlineNodes(node.content);\n }\n\n return \"\";\n })\n .join(\"\");\n}\n"],"mappings":"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","names":[]}
|
|
File without changes
|