@tutti-os/ui-rich-text 0.0.53 → 0.0.55

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/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  parseRichTextMentionHref,
19
19
  removeRichTextMentionFromContent,
20
20
  serializeRichTextDocumentToContent
21
- } from "./chunk-HO3WOO7V.js";
21
+ } from "./chunk-5XJXLQYZ.js";
22
22
  export {
23
23
  createDefaultRichTextI18nRuntime,
24
24
  createRichTextI18nRuntime,
@@ -0,0 +1,220 @@
1
+ import { ReactNode } from 'react';
2
+ import { RichTextTriggerQueryMatch } from './types/index.js';
3
+
4
+ type MentionPaletteFilterId = string;
5
+ type MentionPaletteGroupId = string;
6
+ interface MentionPaletteCategory {
7
+ id: MentionPaletteFilterId;
8
+ label: string;
9
+ }
10
+ interface MentionPaletteGroup<TItem> {
11
+ id: MentionPaletteGroupId;
12
+ label?: string;
13
+ items: readonly TItem[];
14
+ totalCount: number;
15
+ visibleCount: number;
16
+ hasMore: boolean;
17
+ emptyLabel?: string;
18
+ /**
19
+ * Optional precomputed label for the "show more" expand control. When omitted
20
+ * the shell falls back to `+<remaining>`. Surfaces that need exact wording
21
+ * (e.g. the agent's translated "show N more") compute this themselves so the
22
+ * shell stays free of surface-specific i18n.
23
+ */
24
+ expandLabel?: string;
25
+ /**
26
+ * Optional extra class names applied to the group `<section>` element. Lets a
27
+ * consumer add bespoke spacing between specific groups (e.g. extra top margin
28
+ * when one group directly follows a related one) without the shell needing to
29
+ * know about surface-specific group relationships.
30
+ */
31
+ sectionClassName?: string;
32
+ /**
33
+ * When true the shell omits the divider it would otherwise render above this
34
+ * group (the divider normally appears before every group after the first).
35
+ * Lets a consumer suppress inter-group chrome in specific contexts (e.g. while
36
+ * showing a flat, ungrouped search result list).
37
+ */
38
+ hideTopDivider?: boolean;
39
+ }
40
+ /**
41
+ * Generic theming hooks so a consumer can keep its own stylesheet class names,
42
+ * test ids, and divider data-attribute when migrating onto the shared shell.
43
+ * Every field is optional and defaults to the shell's own `rich-text-at-*`
44
+ * identifiers, so the shell stays surface-agnostic.
45
+ */
46
+ interface MentionPaletteTheme {
47
+ classNames?: {
48
+ palette?: string;
49
+ header?: string;
50
+ footer?: string;
51
+ tabs?: string;
52
+ scrollRegion?: string;
53
+ scrollbar?: string;
54
+ scrollbarThumb?: string;
55
+ hint?: string;
56
+ hintItem?: string;
57
+ hintButton?: string;
58
+ hintSeparator?: string;
59
+ shortcut?: string;
60
+ shortcutArrow?: string;
61
+ shortcutButton?: string;
62
+ shortcutGroup?: string;
63
+ };
64
+ testIds?: {
65
+ emptyState?: string;
66
+ hint?: string;
67
+ scrollbar?: string;
68
+ loadingSpinner?: string;
69
+ };
70
+ /** data-attribute (without value) used to mark the inter-group divider. */
71
+ groupDividerAttribute?: string;
72
+ }
73
+ type MentionPaletteState<TItem> = {
74
+ status: "idle";
75
+ query: string;
76
+ mode: "browse";
77
+ filter: MentionPaletteFilterId;
78
+ categories: readonly MentionPaletteCategory[];
79
+ groups: readonly MentionPaletteGroup<TItem>[];
80
+ error: null;
81
+ } | {
82
+ status: "loading" | "ready";
83
+ query: string;
84
+ mode: "browse" | "results";
85
+ filter: MentionPaletteFilterId;
86
+ categories: readonly MentionPaletteCategory[];
87
+ groups: readonly MentionPaletteGroup<TItem>[];
88
+ error: null;
89
+ } | {
90
+ status: "error";
91
+ query: string;
92
+ mode: "browse" | "results";
93
+ filter: MentionPaletteFilterId;
94
+ categories: readonly MentionPaletteCategory[];
95
+ groups: readonly MentionPaletteGroup<TItem>[];
96
+ error: string;
97
+ };
98
+ interface MentionPaletteEntry {
99
+ key: string;
100
+ type: "category" | "item" | "expand";
101
+ categoryId?: MentionPaletteFilterId;
102
+ groupId?: MentionPaletteGroupId;
103
+ itemIndex?: number;
104
+ }
105
+ interface MentionPaletteProps<TItem> {
106
+ state: MentionPaletteState<TItem>;
107
+ highlightedKey: string | null;
108
+ getItemKey: (item: TItem, group: MentionPaletteGroup<TItem>) => string;
109
+ renderItem: (item: TItem, ctx: {
110
+ active: boolean;
111
+ group: MentionPaletteGroup<TItem>;
112
+ }) => ReactNode;
113
+ labels: {
114
+ loading: string;
115
+ empty: string;
116
+ error: string;
117
+ tabHint: string;
118
+ /**
119
+ * Accessible name for the listbox container. Defaults to `tabHint` when
120
+ * omitted; consumers that label the whole palette differently from the
121
+ * keyboard-hint bar supply it explicitly.
122
+ */
123
+ listbox?: string;
124
+ };
125
+ hintLabels: {
126
+ cycleFilter: string;
127
+ moveSelection: string;
128
+ navigateHierarchy?: string;
129
+ };
130
+ maxHeightPx: number;
131
+ onHighlightChange: (key: string) => void;
132
+ onSelectItem: (item: TItem, group: MentionPaletteGroup<TItem>) => void;
133
+ onSelectCategory: (categoryId: MentionPaletteFilterId) => void;
134
+ onSelectFilter: (filter: MentionPaletteFilterId) => void;
135
+ onExpandGroup: (groupId: MentionPaletteGroupId) => void;
136
+ onCycleFilter: (delta: 1 | -1) => void;
137
+ onMoveSelection: (delta: 1 | -1) => void;
138
+ onNavigateHierarchy?: (delta: 1 | -1) => void;
139
+ /** Rendered after the groups, before the keyboard hint bar. */
140
+ renderListFooter?: () => ReactNode;
141
+ /**
142
+ * Rendered inside the header, directly under the category tabs, while results
143
+ * are refreshing in-place (i.e. existing results stay visible). Consumers that
144
+ * want an inline "refreshing" banner supply it here; omit for none.
145
+ */
146
+ loadingBanner?: ReactNode;
147
+ /**
148
+ * When true, scrolling the highlighted row into view centers it within the
149
+ * scroll container instead of using the default `block: "nearest"` behavior.
150
+ */
151
+ scrollHighlightedIntoViewCentered?: boolean;
152
+ /** Optional generic theming overrides; defaults to the shell's own styling. */
153
+ theme?: MentionPaletteTheme;
154
+ }
155
+
156
+ interface MentionPaletteModelInput<TItem> {
157
+ activeCategoryId: string;
158
+ categories: readonly MentionPaletteCategory[];
159
+ groups: readonly MentionPaletteGroup<TItem>[];
160
+ loading: boolean;
161
+ query?: string;
162
+ mode?: "browse" | "results";
163
+ }
164
+ interface MentionPaletteSectionConfig<TMatch extends RichTextTriggerQueryMatch = RichTextTriggerQueryMatch> {
165
+ id: string;
166
+ label?: string;
167
+ providerIds?: readonly string[];
168
+ matches?: (match: TMatch) => boolean;
169
+ emptyLabel?: string;
170
+ }
171
+ interface MentionPaletteCategoryConfig<TMatch extends RichTextTriggerQueryMatch = RichTextTriggerQueryMatch> {
172
+ id: string;
173
+ label: string;
174
+ providerIds?: readonly string[];
175
+ matches?: (match: TMatch) => boolean;
176
+ emptyLabel?: string;
177
+ sections?: readonly MentionPaletteSectionConfig<TMatch>[];
178
+ }
179
+ declare function mentionPaletteGroup<TItem>(input: {
180
+ id: string;
181
+ label?: string;
182
+ items: readonly TItem[];
183
+ emptyLabel?: string;
184
+ }): MentionPaletteGroup<TItem>;
185
+ declare function buildMentionPaletteModel<TItem>(input: MentionPaletteModelInput<TItem>): MentionPaletteState<TItem>;
186
+ declare function buildMentionPaletteModelFromTriggerMatches<TMatch extends RichTextTriggerQueryMatch = RichTextTriggerQueryMatch>(input: {
187
+ activeCategoryId: string;
188
+ categories: readonly MentionPaletteCategoryConfig<TMatch>[];
189
+ matches: readonly TMatch[];
190
+ loading: boolean;
191
+ query?: string;
192
+ mode?: "browse" | "results";
193
+ }): MentionPaletteState<TMatch>;
194
+ declare function moveMentionPaletteHighlight<TItem>(input: {
195
+ state: MentionPaletteState<TItem>;
196
+ currentKey: string | null;
197
+ delta: 1 | -1;
198
+ getItemKey: (item: TItem, groupId: string) => string;
199
+ }): string | null;
200
+ declare function repairMentionPaletteHighlight<TItem>(input: {
201
+ state: MentionPaletteState<TItem>;
202
+ currentKey: string | null;
203
+ getItemKey: (item: TItem, groupId: string) => string;
204
+ preferredKey?: string | null;
205
+ }): string | null;
206
+ declare function findMentionPaletteEntry<TItem>(input: {
207
+ state: MentionPaletteState<TItem>;
208
+ key: string | null;
209
+ getItemKey: (item: TItem, groupId: string) => string;
210
+ }): MentionPaletteEntry | null;
211
+ declare function selectedMentionPaletteItem<TItem>(input: {
212
+ state: MentionPaletteState<TItem>;
213
+ key: string | null;
214
+ getItemKey: (item: TItem, groupId: string) => string;
215
+ }): TItem | null;
216
+ declare function nextMentionPaletteCategory<TCategoryId extends string>(categories: readonly {
217
+ id: TCategoryId;
218
+ }[], current: TCategoryId, delta: 1 | -1): TCategoryId;
219
+
220
+ export { type MentionPaletteCategory as M, type MentionPaletteCategoryConfig as a, type MentionPaletteEntry as b, type MentionPaletteFilterId as c, type MentionPaletteGroup as d, type MentionPaletteGroupId as e, type MentionPaletteModelInput as f, type MentionPaletteProps as g, type MentionPaletteSectionConfig as h, type MentionPaletteState as i, type MentionPaletteTheme as j, buildMentionPaletteModel as k, buildMentionPaletteModelFromTriggerMatches as l, findMentionPaletteEntry as m, mentionPaletteGroup as n, moveMentionPaletteHighlight as o, nextMentionPaletteCategory as p, repairMentionPaletteHighlight as r, selectedMentionPaletteItem as s };
@@ -11,8 +11,8 @@ import {
11
11
  isRichTextMentionAttrs,
12
12
  renderRichTextTriggerInsertResult,
13
13
  resolveRichTextMentionView
14
- } from "../chunk-NNPICKW6.js";
15
- import "../chunk-HO3WOO7V.js";
14
+ } from "../chunk-2SYJ5JFT.js";
15
+ import "../chunk-5XJXLQYZ.js";
16
16
  export {
17
17
  createRichTextMarkdownLinkInsertResult,
18
18
  createRichTextMentionAttrs,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tutti-os/ui-rich-text",
3
- "version": "0.0.53",
3
+ "version": "0.0.55",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -52,8 +52,8 @@
52
52
  "directory": "packages/ui/rich-text"
53
53
  },
54
54
  "dependencies": {
55
- "@tutti-os/ui-i18n-runtime": "0.0.53",
56
- "@tutti-os/ui-system": "0.0.53",
55
+ "@tutti-os/ui-i18n-runtime": "0.0.55",
56
+ "@tutti-os/ui-system": "0.0.55",
57
57
  "@tiptap/core": "^3.23.6",
58
58
  "@tiptap/extension-document": "^3.23.6",
59
59
  "@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 RESERVED_MENTION_SCOPE_KEYS = new Set([\n \"appId\",\n \"id\",\n \"kind\",\n \"link\",\n \"provider\",\n \"v\",\n \"version\"\n]);\nconst PRESENTATION_MENTION_CONTEXT_KEYS = new Set([\n \"agentIconUrl\",\n \"iconUrl\",\n \"thumbnailUrl\",\n \"userAvatarPlaceholderUrl\"\n]);\nconst DEFAULT_MENTION_CONTEXT_MAX_VALUE_LENGTH = 2048;\n\nexport interface RichTextMentionAgentContext {\n providerId: string;\n entityId: string;\n label: string;\n scope?: Readonly<Record<string, string>>;\n}\n\nexport interface SanitizeRichTextMentionContextOptions {\n maxValueLength?: number;\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 isPresentationMentionContextKey(key: string): boolean {\n return PRESENTATION_MENTION_CONTEXT_KEYS.has(key);\n}\n\nfunction isUnsafeMentionContextValue(value: string, maxValueLength: number) {\n const normalizedValue = value.toLowerCase();\n return (\n value.length > maxValueLength ||\n normalizedValue.startsWith(\"data:\") ||\n normalizedValue.startsWith(\"blob:\")\n );\n}\n\nexport function sanitizeRichTextMentionScopeForAgentContext(\n scope?: Readonly<Record<string, unknown>> | null,\n options: SanitizeRichTextMentionContextOptions = {}\n): Record<string, string> | undefined {\n if (!scope) {\n return undefined;\n }\n const maxValueLength =\n options.maxValueLength && options.maxValueLength > 0\n ? options.maxValueLength\n : DEFAULT_MENTION_CONTEXT_MAX_VALUE_LENGTH;\n const nextScope: Record<string, string> = {};\n for (const [key, value] of Object.entries(scope).sort(([left], [right]) =>\n left.localeCompare(right)\n )) {\n const nextKey = key.trim();\n if (\n !nextKey ||\n isReservedMentionScopeKey(nextKey) ||\n isPresentationMentionContextKey(nextKey) ||\n typeof value !== \"string\"\n ) {\n continue;\n }\n const nextValue = value.trim();\n if (!nextValue || isUnsafeMentionContextValue(nextValue, maxValueLength)) {\n continue;\n }\n nextScope[nextKey] = nextValue;\n }\n return Object.keys(nextScope).length ? nextScope : undefined;\n}\n\nexport function sanitizeRichTextMentionForAgentContext(\n mention: {\n providerId?: string | null;\n entityId?: string | null;\n label?: string | null;\n scope?: Readonly<Record<string, unknown>> | null;\n },\n options: SanitizeRichTextMentionContextOptions = {}\n): RichTextMentionAgentContext | undefined {\n const providerId = mention.providerId?.trim() ?? \"\";\n const entityId = mention.entityId?.trim() ?? \"\";\n const label = normalizeMentionLabel(mention.label ?? \"\") || entityId;\n if (!providerId || !entityId || !label) {\n return undefined;\n }\n const scope = sanitizeRichTextMentionScopeForAgentContext(\n mention.scope,\n options\n );\n return {\n providerId,\n entityId,\n label,\n ...(scope ? { scope } : {})\n };\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":";AAAO,IAAM,6BAA6B;AACnC,IAAM,2BAA2B;;;ACOjC,UAAU,0BACf,OACsC;AACtC,MAAI,SAAS;AAEb,SAAO,SAAS,MAAM,QAAQ;AAC5B,UAAM,aAAa,MAAM,QAAQ,KAAK,MAAM;AAC5C,QAAI,aAAa,GAAG;AAClB;AAAA,IACF;AACA,QAAI,aAAa,KAAK,MAAM,aAAa,CAAC,MAAM,KAAK;AACnD,eAAS,aAAa;AACtB;AAAA,IACF;AAEA,UAAM,WAAW,qBAAqB,OAAO,aAAa,CAAC;AAC3D,QAAI,WAAW,KAAK,MAAM,WAAW,CAAC,MAAM,KAAK;AAC/C,eAAS,aAAa;AACtB;AAAA,IACF;AAEA,UAAM,YAAY,WAAW;AAC7B,UAAM,UAAU,oBAAoB,OAAO,SAAS;AACpD,QAAI,UAAU,GAAG;AACf,eAAS,aAAa;AACtB;AAAA,IACF;AAEA,UAAM;AAAA,MACJ,MAAM,yBAAyB,MAAM,MAAM,WAAW,OAAO,CAAC;AAAA,MAC9D,OAAO;AAAA,MACP,OAAO,yBAAyB,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;AAAA,MACrE,QAAQ,MAAM,MAAM,YAAY,UAAU,CAAC;AAAA,MAC3C,IAAI,UAAU;AAAA,IAChB;AACA,aAAS,UAAU;AAAA,EACrB;AACF;AAEA,SAAS,yBAAyB,OAAuB;AACvD,SAAO,MAAM,QAAQ,kBAAkB,IAAI;AAC7C;AAEA,SAAS,qBAAqB,OAAe,QAAwB;AACnE,MAAI,UAAU;AAEd,WAAS,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,SAAS,GAAG;AACzD,UAAM,OAAO,MAAM,KAAK;AACxB,QAAI,SAAS;AACX,gBAAU;AACV;AAAA,IACF;AACA,QAAI,SAAS,MAAM;AACjB,gBAAU;AACV;AAAA,IACF;AACA,QAAI,SAAS,KAAK;AAChB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,OAAe,QAAwB;AAClE,MAAI,UAAU;AACd,MAAI,QAAQ;AAEZ,WAAS,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,SAAS,GAAG;AACzD,UAAM,OAAO,MAAM,KAAK;AACxB,QAAI,SAAS;AACX,gBAAU;AACV;AAAA,IACF;AACA,QAAI,SAAS,MAAM;AACjB,gBAAU;AACV;AAAA,IACF;AACA,QAAI,SAAS,KAAK;AAChB,eAAS;AACT;AAAA,IACF;AACA,QAAI,SAAS,KAAK;AAChB;AAAA,IACF;AACA,QAAI,UAAU,GAAG;AACf,aAAO;AAAA,IACT;AACA,aAAS;AAAA,EACX;AAEA,SAAO;AACT;;;ACtEA,IAAM,yBAAyB;AAC/B,IAAM,uBAAuB;AAC7B,IAAM,sBAAsB;AAC5B,IAAM,8BAA8B,oBAAI,IAAI;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,oCAAoC,oBAAI,IAAI;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AACD,IAAM,2CAA2C;AAoBjD,SAAS,qBAAqB,OAAuB;AACnD,SAAO,MAAM,QAAQ,UAAU,IAAI;AACrC;AAEA,SAAS,uBAAuB,OAA+B;AAC7D,QAAM,UAAU,qBAAqB,SAAS,EAAE,EAAE,KAAK;AACvD,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AACA,QAAM,WAAW,4BAA4B,OAAO;AACpD,SAAO,YAAY;AACrB;AAEO,SAAS,yBAAyB,OAA+B;AACtE,SAAO,uBAAuB,KAAK;AACrC;AAEA,SAAS,4BAA4B,OAAuB;AAC1D,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,QAAI,QAAQ,SAAS,SAAS,CAAC,MAAM,QAAQ,OAAO,OAAO,GAAG;AAC5D,aAAO;AAAA,IACT;AACA,WAAO,4BAA4B,OAAO,OAAO,EAAE,KAAK;AAAA,EAC1D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,4BAA4B,OAAwC;AAC3E,SAAO,MACJ,IAAI,CAAC,SAAS,2BAA2B,IAAI,CAAC,EAC9C,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,EAChC,KAAK,MAAM;AAChB;AAEA,SAAS,2BACP,MACQ;AACR,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AACA,MAAI,KAAK,SAAS,QAAQ;AACxB,WAAO,KAAK,QAAQ;AAAA,EACtB;AACA,MAAI,KAAK,SAAS,qBAAqB;AACrC,UAAM,QAAQ,KAAK,SAAS,CAAC;AAC7B,UAAM,OAAO,MAAM,SAAS,WAAW,WAAW;AAClD,UAAM,aACH,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO,YAC9C,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO,WAC/C;AACF,UAAM,OAAO,0BAA0B,WAAW,IAAI;AACtD,UAAM,SACH,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO,SAAY,KAAK,KAChE,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,GAAG,EAAE,KACrC;AACF,WAAO,QAAQ,QAAQ,IAAI,KAAK,KAAK,IAAI,MAAM;AAAA,EACjD;AACA,MAAI,MAAM,QAAQ,KAAK,OAAO,GAAG;AAC/B,UAAM,SAAS,KAAK,QACjB,IAAI,CAAC,UAAU,2BAA2B,KAAK,CAAC,EAChD,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,EAChC,KAAK,EAAE,EACP,KAAK;AACR,QAAI,CAAC,QAAQ;AACX,aAAO;AAAA,IACT;AACA,QAAI,KAAK,SAAS,aAAa;AAC7B,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEA,SAAS,uBACP,YACA,MACQ;AACR,QAAM,UAAU,WAAW,KAAK;AAChC,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AACA,MAAI,SAAS,YAAY,CAAC,QAAQ,SAAS,GAAG,GAAG;AAC/C,WAAO,GAAG,OAAO;AAAA,EACnB;AACA,SAAO;AACT;AAEA,SAAS,yBAAyB,MAAuB;AACvD,QAAM,UAAU,KAAK,KAAK;AAC1B,MACE,CAAC,WACD,oBAAoB,KAAK,OAAO,KAChC,qBAAqB,KAAK,OAAO,GACjC;AACA,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAEO,SAAS,sBAAsB,MAAuB;AAC3D,SAAO,oBAAoB,KAAK,KAAK,KAAK,CAAC;AAC7C;AAEA,SAAS,sBAAsB,OAAuB;AACpD,SAAO,MAAM,KAAK,EAAE,QAAQ,OAAO,EAAE,EAAE,KAAK;AAC9C;AAEA,SAAS,0BAA0B,KAAsB;AACvD,SAAO,4BAA4B,IAAI,GAAG,KAAK,IAAI,WAAW,OAAO;AACvE;AAEA,SAAS,gCAAgC,KAAsB;AAC7D,SAAO,kCAAkC,IAAI,GAAG;AAClD;AAEA,SAAS,4BAA4B,OAAe,gBAAwB;AAC1E,QAAM,kBAAkB,MAAM,YAAY;AAC1C,SACE,MAAM,SAAS,kBACf,gBAAgB,WAAW,OAAO,KAClC,gBAAgB,WAAW,OAAO;AAEtC;AAEO,SAAS,4CACd,OACA,UAAiD,CAAC,GACd;AACpC,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AACA,QAAM,iBACJ,QAAQ,kBAAkB,QAAQ,iBAAiB,IAC/C,QAAQ,iBACR;AACN,QAAM,YAAoC,CAAC;AAC3C,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,EAAE;AAAA,IAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MACnE,KAAK,cAAc,KAAK;AAAA,EAC1B,GAAG;AACD,UAAM,UAAU,IAAI,KAAK;AACzB,QACE,CAAC,WACD,0BAA0B,OAAO,KACjC,gCAAgC,OAAO,KACvC,OAAO,UAAU,UACjB;AACA;AAAA,IACF;AACA,UAAM,YAAY,MAAM,KAAK;AAC7B,QAAI,CAAC,aAAa,4BAA4B,WAAW,cAAc,GAAG;AACxE;AAAA,IACF;AACA,cAAU,OAAO,IAAI;AAAA,EACvB;AACA,SAAO,OAAO,KAAK,SAAS,EAAE,SAAS,YAAY;AACrD;AAEO,SAAS,uCACd,SAMA,UAAiD,CAAC,GACT;AACzC,QAAM,aAAa,QAAQ,YAAY,KAAK,KAAK;AACjD,QAAM,WAAW,QAAQ,UAAU,KAAK,KAAK;AAC7C,QAAM,QAAQ,sBAAsB,QAAQ,SAAS,EAAE,KAAK;AAC5D,MAAI,CAAC,cAAc,CAAC,YAAY,CAAC,OAAO;AACtC,WAAO;AAAA,EACT;AACA,QAAM,QAAQ;AAAA,IACZ,QAAQ;AAAA,IACR;AAAA,EACF;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,EAC3B;AACF;AAEA,SAAS,yBACP,SACiB;AACjB,QAAM,SAAS,IAAI,gBAAgB;AACnC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,EAAE;AAAA,IAC7D,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MAAM,KAAK,cAAc,KAAK;AAAA,EAC/C,GAAG;AACD,UAAM,UAAU,IAAI,KAAK;AACzB,UAAM,YAAY,MAAM,KAAK;AAC7B,QAAI,CAAC,WAAW,CAAC,aAAa,0BAA0B,OAAO,GAAG;AAChE;AAAA,IACF;AACA,WAAO,IAAI,SAAS,SAAS;AAAA,EAC/B;AACA,SAAO;AACT;AAEO,SAAS,0BACd,SACQ;AACR,QAAM,aAAa,QAAQ,WAAW,KAAK;AAC3C,QAAM,WAAW,QAAQ,SAAS,KAAK;AACvC,QAAM,QAAQ,sBAAsB,QAAQ,KAAK;AACjD,MAAI,CAAC,cAAc,CAAC,YAAY,CAAC,OAAO;AACtC,WAAO;AAAA,EACT;AAEA,QAAM,SAAS,yBAAyB,OAAO;AAC/C,QAAM,cAAc,OAAO,SAAS;AACpC,QAAM,WAAW,GAAG,mBAAmB,UAAU,CAAC,IAAI,mBAAmB,QAAQ,CAAC;AAClF,SAAO,cACH,aAAa,QAAQ,IAAI,WAAW,KACpC,aAAa,QAAQ;AAC3B;AAEO,SAAS,8BACd,SACQ;AACR,QAAM,QAAQ,sBAAsB,QAAQ,KAAK;AACjD,QAAM,OAAO,0BAA0B,OAAO;AAC9C,MAAI,CAAC,SAAS,CAAC,MAAM;AACnB,WAAO;AAAA,EACT;AACA,SAAO,IAAI,wBAAwB,IAAI,KAAK,EAAE,CAAC,KAAK,uBAAuB,IAAI,CAAC;AAClF;AAEO,SAAS,yBACd,MACA,OAC2B;AAC3B,QAAM,cAAc,KAAK,KAAK;AAC9B,MAAI,CAAC,sBAAsB,WAAW,GAAG;AACvC,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,SAAS,IAAI,IAAI,WAAW;AAClC,UAAM,aAAa,mBAAmB,OAAO,QAAQ,EAAE,KAAK;AAC5D,UAAM,kBAAkB,OAAO,SAAS,QAAQ,QAAQ,EAAE;AAC1D,UAAM,WAAW,mBAAmB,eAAe,EAAE,KAAK;AAC1D,UAAM,WAAW,sBAAsB,OAAO,KAAK,KAAK,EAAE;AAE1D,QACE,CAAC,cACD,CAAC,mBACD,gBAAgB,SAAS,GAAG,KAC5B,CAAC,UACD;AACA,aAAO;AAAA,IACT;AAEA,UAAM,YAAY,YAAY;AAE9B,UAAM,eAAiD,CAAC;AACxD,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,aAAa,QAAQ,GAAG;AACxD,YAAM,WAAW,IAAI,KAAK;AAC1B,YAAM,aAAa,MAAM,KAAK;AAC9B,UAAI,CAAC,YAAY,0BAA0B,QAAQ,GAAG;AACpD,eAAO;AAAA,MACT;AACA,UAAI,YAAY;AACd,qBAAa,KAAK,CAAC,UAAU,UAAU,CAAC;AAAA,MAC1C;AAAA,IACF;AAEA,UAAM,UAA8B;AAAA,MAClC,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA,OAAO;AAAA,IACT;AACA,QAAI,aAAa,SAAS,GAAG;AAC3B,cAAQ,QAAQ,OAAO,YAAY,YAAY;AAAA,IACjD;AACA,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,0BACd,YACA,OAA0B,QAClB;AACR,SAAO,uBAAuB,YAAY,IAAI;AAChD;AAEO,SAAS,2BAA2B,OAAkC;AAC3E,QAAM,OAAO,MAAM,SAAS,WAAW,WAAW;AAClD,QAAM,OAAO,0BAA0B,MAAM,MAAM,IAAI;AACvD,QAAM,cACJ,MAAM,MAAM,KAAK,KACjB,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO,EAAE,GAAG,EAAE,KACrC,QACA,MAAM,KAAK,KAAK;AAClB,MAAI,CAAC,QAAQ,CAAC,aAAa;AACzB,WAAO;AAAA,EACT;AACA,SAAO,IAAI,wBAAwB,WAAW,CAAC,KAAK,uBAAuB,IAAI,CAAC;AAClF;AAEO,SAAS,6BACd,OACA,MACQ;AACR,QAAM,UAAU,uBAAuB,KAAK;AAC5C,QAAM,WAAW,IAAI;AAAA,IACnB,gCAAgC,OAAO,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI;AAAA,EAChE;AACA,QAAM,WAAW,KACd,IAAI,CAAC,QAAQ;AACZ,UAAM,OAAO,IAAI,SAAS,WAAW,WAAW;AAChD,UAAM,OAAO,0BAA0B,IAAI,MAAM,IAAI;AACrD,QAAI,CAAC,QAAQ,SAAS,IAAI,IAAI,GAAG;AAC/B,aAAO;AAAA,IACT;AACA,aAAS,IAAI,IAAI;AACjB,WAAO,2BAA2B,EAAE,GAAG,KAAK,MAAM,KAAK,CAAC;AAAA,EAC1D,CAAC,EACA,OAAO,OAAO;AAEjB,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO;AAAA,EACT;AACA,SAAO,UAAU,GAAG,OAAO,IAAI,SAAS,KAAK,GAAG,CAAC,KAAK,SAAS,KAAK,GAAG;AACzE;AAEO,SAAS,gCACd,OACmB;AACnB,QAAM,UAAU,uBAAuB,KAAK;AAC5C,QAAM,OAAO,oBAAI,IAA6B;AAC9C,aAAW,SAAS,0BAA0B,OAAO,GAAG;AACtD,UAAM,OAAO,MAAM,MAAM,KAAK;AAC9B,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,QAAI,CAAC,QAAQ,CAAC,yBAAyB,IAAI,GAAG;AAC5C;AAAA,IACF;AACA,UAAM,OAAO,KAAK,SAAS,GAAG,IAAI,WAAW;AAC7C,UAAM,OAAO,0BAA0B,MAAM,IAAI;AACjD,QAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,GAAG;AAC3B;AAAA,IACF;AACA,SAAK,IAAI,MAAM;AAAA,MACb;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN;AAAA,IACF,CAAC;AAAA,EACH;AACA,SAAO,CAAC,GAAG,KAAK,OAAO,CAAC;AAC1B;AAEO,SAAS,mCACd,OACsB;AACtB,QAAM,UAAU,uBAAuB,KAAK;AAC5C,QAAM,OAAO,oBAAI,IAAgC;AAEjD,aAAW,SAAS,0BAA0B,OAAO,GAAG;AACtD,UAAM,QAAQ,MAAM,MAAM,KAAK;AAC/B,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,UAAM,UAAU,yBAAyB,MAAM,KAAK;AACpD,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AACA,UAAM,aAAa;AAAA,MACjB,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,KAAK;AAAA,QACH,OAAO;AAAA,UACL,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,EAAE;AAAA,YAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MACtD,KAAK,cAAc,KAAK;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAAA,IACF,EAAE,KAAK,GAAG;AACV,QAAI,KAAK,IAAI,UAAU,GAAG;AACxB;AAAA,IACF;AACA,SAAK,IAAI,YAAY,OAAO;AAAA,EAC9B;AAEA,SAAO,CAAC,GAAG,KAAK,OAAO,CAAC;AAC1B;AAEO,SAAS,iCACd,SACA,SACQ;AACR,QAAM,aAAa,QAAQ,WAAW,KAAK;AAC3C,QAAM,WAAW,QAAQ,SAAS,KAAK;AACvC,MAAI,CAAC,cAAc,CAAC,UAAU;AAC5B,WAAO,uBAAuB,OAAO;AAAA,EACvC;AAEA,QAAM,aAAa,uBAAuB,OAAO;AACjD,QAAM,OAAO,6BAA6B,YAAY,CAAC,UAAU;AAC/D,UAAM,gBAAgB,yBAAyB,MAAM,MAAM,MAAM,KAAK;AACtE,QAAI,CAAC,eAAe;AAClB,aAAO,MAAM;AAAA,IACf;AACA,WAAO,cAAc,eAAe,cAClC,cAAc,aAAa,WACzB,KACA,MAAM;AAAA,EACZ,CAAC;AAED,SAAO,KACJ,QAAQ,aAAa,IAAI,EACzB,QAAQ,WAAW,MAAM,EACzB,KAAK;AACV;AAEO,SAAS,8BACd,SACA,MACQ;AACR,QAAM,aAAa,KAAK,KAAK;AAC7B,MAAI,CAAC,YAAY;AACf,WAAO,uBAAuB,OAAO;AAAA,EACvC;AACA,QAAM,aAAa,uBAAuB,OAAO;AACjD,QAAM,OAAO,6BAA6B,YAAY,CAAC,UAAU;AAC/D,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,UAAM,OAAO,KAAK,SAAS,GAAG,IAAI,WAAW;AAC7C,UAAM,UAAU,0BAA0B,MAAM,IAAI;AACpD,WAAO,YAAY,aAAa,KAAK,MAAM;AAAA,EAC7C,CAAC;AACD,SAAO,KACJ,QAAQ,aAAa,IAAI,EACzB,QAAQ,aAAa,IAAI,EACzB,QAAQ,cAAc,GAAG,EACzB,QAAQ,WAAW,MAAM,EACzB,KAAK;AACV;AAEO,SAAS,4BAA4B,OAA+B;AACzE,QAAM,UAAU,uBAAuB,KAAK;AAC5C,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,QAAQ,QAAQ,wBAAwB,MAAM;AAAA,IAC9C,CAAC,UAAU,IAAI,MAAM,KAAK;AAAA,EAC5B,EACG,QAAQ,iBAAiB,GAAG,EAC5B,QAAQ,cAAc,MAAM,EAC5B,QAAQ,UAAU,GAAG,EACrB,QAAQ,QAAQ,GAAG,EACnB,KAAK;AACV;AAEO,SAAS,wCACd,OACQ;AACR,QAAM,UAAU,uBAAuB,KAAK;AAC5C,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,EACT;AACA,SAAO;AAAA,IACL,QAAQ,QAAQ,wBAAwB,GAAG;AAAA,IAC3C,MAAM;AAAA,EACR,EACG,QAAQ,iBAAiB,GAAG,EAC5B,QAAQ,cAAc,MAAM,EAC5B,QAAQ,UAAU,GAAG,EACrB,QAAQ,QAAQ,GAAG,EACnB,KAAK;AACV;AAEO,SAAS,+BACd,OACkB;AAClB,QAAM,UAAU,uBAAuB,KAAK;AAC5C,MAAI,CAAC,SAAS;AACZ,WAAO;AAAA,MACL,MAAM;AAAA,MACN,SAAS,CAAC,EAAE,MAAM,YAAY,CAAC;AAAA,IACjC;AAAA,EACF;AAEA,QAAM,aAAa,QAChB,MAAM,QAAQ,EACd,IAAI,CAAC,cAAc,4BAA4B,SAAS,CAAC,EACzD,OAAO,CAAC,cAAc,MAAM,QAAQ,UAAU,OAAO,CAAC;AAEzD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,WAAW,SAAS,IAAI,aAAa,CAAC,EAAE,MAAM,YAAY,CAAC;AAAA,EACtE;AACF;AAEO,SAAS,mCACd,UACQ;AACR,QAAM,cAAc,SAAS,WAAW,CAAC,GACtC,IAAI,CAAC,SAAS,2BAA2B,IAAI,CAAC,EAC9C,OAAO,CAAC,UAAU,MAAM,SAAS,CAAC;AAErC,SAAO,WAAW,KAAK,MAAM,EAAE,KAAK;AACtC;AAEA,SAAS,4BAA4B,WAAgC;AACnE,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,0BAA0B,SAAS;AAAA,EAC9C;AACF;AAEA,SAAS,0BAA0B,MAA6B;AAC9D,QAAM,UAAyB,CAAC;AAChC,MAAI,SAAS;AAEb,aAAW,SAAS,0BAA0B,IAAI,GAAG;AACnD,UAAM,EAAE,OAAO,OAAO,IAAI;AAC1B,QAAI,QAAQ,QAAQ;AAClB,2BAAqB,SAAS,KAAK,MAAM,QAAQ,KAAK,CAAC;AAAA,IACzD;AAEA,UAAM,QAAQ,MAAM,MAAM,KAAK;AAC/B,UAAM,OAAO,MAAM,KAAK,KAAK;AAC7B,UAAM,UAAU,yBAAyB,MAAM,KAAK;AACpD,QAAI,SAAS;AACX,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,OAAO;AAAA,MACT,CAAC;AAAA,IACH,WAAW,SAAS,yBAAyB,IAAI,GAAG;AAClD,YAAM,OAAO,KAAK,SAAS,GAAG,IAAI,WAAW;AAC7C,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA,MAAM,0BAA0B,MAAM,IAAI;AAAA,QAC5C;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,2BAAqB,SAAS,MAAM;AAAA,IACtC;AAEA,aAAS,MAAM;AAAA,EACjB;AAEA,MAAI,SAAS,KAAK,QAAQ;AACxB,yBAAqB,SAAS,KAAK,MAAM,MAAM,CAAC;AAAA,EAClD;AAEA,SAAO;AACT;AAEA,SAAS,6BACP,OACA,SACQ;AACR,MAAI,YAAY;AAChB,MAAI,SAAS;AAEb,aAAW,SAAS,0BAA0B,KAAK,GAAG;AACpD,iBAAa,MAAM,MAAM,QAAQ,MAAM,KAAK;AAC5C,iBAAa,QAAQ,KAAK;AAC1B,aAAS,MAAM;AAAA,EACjB;AAEA,SAAO,GAAG,SAAS,GAAG,MAAM,MAAM,MAAM,CAAC;AAC3C;AAEA,SAAS,wBAAwB,OAAuB;AACtD,SAAO,MAAM,QAAQ,YAAY,MAAM;AACzC;AAEA,SAAS,uBAAuB,OAAuB;AACrD,SAAO,MAAM,QAAQ,WAAW,MAAM;AACxC;AAEA,SAAS,qBAAqB,SAAwB,MAAoB;AACxE,MAAI,CAAC,MAAM;AACT;AAAA,EACF;AAEA,QAAM,QAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,QAAQ,CAAC,MAAM,UAAU;AAC7B,QAAI,KAAK,SAAS,GAAG;AACnB,cAAQ,KAAK;AAAA,QACX,MAAM;AAAA,QACN,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AACA,QAAI,QAAQ,MAAM,SAAS,GAAG;AAC5B,cAAQ,KAAK,EAAE,MAAM,YAAY,CAAC;AAAA,IACpC;AAAA,EACF,CAAC;AACH;AAEA,SAAS,2BAA2B,MAA2B;AAC7D,MAAI,KAAK,SAAS,aAAa;AAC7B,WAAO,6BAA6B,KAAK,WAAW,CAAC,CAAC;AAAA,EACxD;AACA,SAAO,6BAA6B,KAAK,WAAW,CAAC,CAAC;AACxD;AAEA,SAAS,6BAA6B,OAAuC;AAC3E,SAAO,MACJ,IAAI,CAAC,SAAS;AACb,QAAI,KAAK,SAAS,QAAQ;AACxB,aAAO,OAAO,KAAK,SAAS,WAAW,KAAK,OAAO;AAAA,IACrD;AACA,QAAI,KAAK,SAAS,aAAa;AAC7B,aAAO;AAAA,IACT;AACA,QAAI,KAAK,SAAS,4BAA4B;AAC5C,YAAM,QAAQ,KAAK,SAAS,CAAC;AAC7B,aAAO,2BAA2B;AAAA,QAChC,MAAM,MAAM,SAAS,WAAW,WAAW;AAAA,QAC3C,MAAM,OAAO,MAAM,UAAU,WAAW,MAAM,QAAQ;AAAA,QACtD,MAAM,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAAA,MACtD,CAAC;AAAA,IACH;AACA,QAAI,KAAK,SAAS,0BAA0B;AAC1C,YAAM,QAAQ,KAAK,SAAS,CAAC;AAC7B,YAAM,QAAQ,OAAO,MAAM,UAAU,WAAW,MAAM,MAAM,KAAK,IAAI;AACrE,YAAM,aACJ,OAAO,MAAM,eAAe,WAAW,MAAM,WAAW,KAAK,IAAI;AACnE,YAAM,WACJ,OAAO,MAAM,aAAa,WAAW,MAAM,SAAS,KAAK,IAAI;AAC/D,UAAI,CAAC,SAAS,CAAC,cAAc,CAAC,UAAU;AACtC,eAAO;AAAA,MACT;AACA,YAAM,QACJ,MAAM,SAAS,OAAO,MAAM,UAAU,WACjC,MAAM,QACP;AACN,aAAO,8BAA8B;AAAA,QACnC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAAA,IACH;AAEA,QAAI,MAAM,QAAQ,KAAK,OAAO,GAAG;AAC/B,aAAO,6BAA6B,KAAK,OAAO;AAAA,IAClD;AAEA,WAAO;AAAA,EACT,CAAC,EACA,KAAK,EAAE;AACZ;","names":[]}