@blue-patterns/richtext 0.0.0-stage → 0.7.18

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.
Files changed (201) hide show
  1. package/CHANGELOG.md +275 -0
  2. package/LICENSE +22 -0
  3. package/README.md +88 -2
  4. package/astryx.integration.mjs +11 -0
  5. package/blocks/RichTextEditorShowcase.template.mjs +13 -0
  6. package/blocks/RichTextEditorShowcase.tsx +19 -0
  7. package/dist/RichTextEditor.d.ts +282 -0
  8. package/dist/RichTextEditor.d.ts.map +1 -0
  9. package/dist/RichTextEditor.js +657 -0
  10. package/dist/RichTextEditorAutoLinkPlugin.d.ts +83 -0
  11. package/dist/RichTextEditorAutoLinkPlugin.d.ts.map +1 -0
  12. package/dist/RichTextEditorAutoLinkPlugin.js +99 -0
  13. package/dist/RichTextEditorToolbar.d.ts +186 -0
  14. package/dist/RichTextEditorToolbar.d.ts.map +1 -0
  15. package/dist/RichTextEditorToolbar.js +688 -0
  16. package/dist/RichTextView.d.ts +92 -0
  17. package/dist/RichTextView.d.ts.map +1 -0
  18. package/dist/RichTextView.js +267 -0
  19. package/dist/codeLanguages.d.ts +14 -0
  20. package/dist/codeLanguages.d.ts.map +1 -0
  21. package/dist/codeLanguages.js +34 -0
  22. package/dist/codeLineTokens.d.ts +53 -0
  23. package/dist/codeLineTokens.d.ts.map +1 -0
  24. package/dist/codeLineTokens.js +188 -0
  25. package/dist/editorNodes.d.ts +8 -0
  26. package/dist/editorNodes.d.ts.map +1 -0
  27. package/dist/editorNodes.js +30 -0
  28. package/dist/editorTheme.d.ts +7 -0
  29. package/dist/editorTheme.d.ts.map +1 -0
  30. package/dist/editorTheme.js +328 -0
  31. package/dist/index.d.ts +31 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +28 -0
  34. package/dist/internal/CodeBackspacePlugin.d.ts +2 -0
  35. package/dist/internal/CodeBackspacePlugin.d.ts.map +1 -0
  36. package/dist/internal/CodeBackspacePlugin.js +70 -0
  37. package/dist/internal/CodeBlockHeaderPlugin.d.ts +11 -0
  38. package/dist/internal/CodeBlockHeaderPlugin.d.ts.map +1 -0
  39. package/dist/internal/CodeBlockHeaderPlugin.js +204 -0
  40. package/dist/internal/CodePastePlugin.d.ts +5 -0
  41. package/dist/internal/CodePastePlugin.d.ts.map +1 -0
  42. package/dist/internal/CodePastePlugin.js +104 -0
  43. package/dist/internal/CodeSyntaxPlugin.d.ts +8 -0
  44. package/dist/internal/CodeSyntaxPlugin.d.ts.map +1 -0
  45. package/dist/internal/CodeSyntaxPlugin.js +397 -0
  46. package/dist/internal/CodeTabPlugin.d.ts +2 -0
  47. package/dist/internal/CodeTabPlugin.d.ts.map +1 -0
  48. package/dist/internal/CodeTabPlugin.js +256 -0
  49. package/dist/internal/DisabledLinkGuardPlugin.d.ts +4 -0
  50. package/dist/internal/DisabledLinkGuardPlugin.d.ts.map +1 -0
  51. package/dist/internal/DisabledLinkGuardPlugin.js +93 -0
  52. package/dist/internal/ImageSourceCaretPlugin.d.ts +3 -0
  53. package/dist/internal/ImageSourceCaretPlugin.d.ts.map +1 -0
  54. package/dist/internal/ImageSourceCaretPlugin.js +105 -0
  55. package/dist/internal/ListItemShortcutsPlugin.d.ts +6 -0
  56. package/dist/internal/ListItemShortcutsPlugin.d.ts.map +1 -0
  57. package/dist/internal/ListItemShortcutsPlugin.js +314 -0
  58. package/dist/internal/MarkdownExtensionsPlugin.d.ts +17 -0
  59. package/dist/internal/MarkdownExtensionsPlugin.d.ts.map +1 -0
  60. package/dist/internal/MarkdownExtensionsPlugin.js +185 -0
  61. package/dist/internal/SelectAllScopePlugin.d.ts +2 -0
  62. package/dist/internal/SelectAllScopePlugin.d.ts.map +1 -0
  63. package/dist/internal/SelectAllScopePlugin.js +67 -0
  64. package/dist/internal/TableColumnFloorPlugin.d.ts +12 -0
  65. package/dist/internal/TableColumnFloorPlugin.d.ts.map +1 -0
  66. package/dist/internal/TableColumnFloorPlugin.js +84 -0
  67. package/dist/internal/TablePastePlugin.d.ts +9 -0
  68. package/dist/internal/TablePastePlugin.d.ts.map +1 -0
  69. package/dist/internal/TablePastePlugin.js +183 -0
  70. package/dist/internal/TableScrollRegionPlugin.d.ts +9 -0
  71. package/dist/internal/TableScrollRegionPlugin.d.ts.map +1 -0
  72. package/dist/internal/TableScrollRegionPlugin.js +95 -0
  73. package/dist/internal/TaskCheckboxPlugin.d.ts +7 -0
  74. package/dist/internal/TaskCheckboxPlugin.d.ts.map +1 -0
  75. package/dist/internal/TaskCheckboxPlugin.js +193 -0
  76. package/dist/internal/ToolbarLinkPopover.d.ts +74 -0
  77. package/dist/internal/ToolbarLinkPopover.d.ts.map +1 -0
  78. package/dist/internal/ToolbarLinkPopover.js +292 -0
  79. package/dist/linkEditing.d.ts +6 -0
  80. package/dist/linkEditing.d.ts.map +1 -0
  81. package/dist/linkEditing.js +20 -0
  82. package/dist/linkForm.d.ts +28 -0
  83. package/dist/linkForm.d.ts.map +1 -0
  84. package/dist/linkForm.js +137 -0
  85. package/dist/linkUtils.d.ts +27 -0
  86. package/dist/linkUtils.d.ts.map +1 -0
  87. package/dist/linkUtils.js +101 -0
  88. package/dist/markdown.d.ts +17 -0
  89. package/dist/markdown.d.ts.map +1 -0
  90. package/dist/markdown.js +17 -0
  91. package/dist/markdownCharacterReferences.d.ts +135 -0
  92. package/dist/markdownCharacterReferences.d.ts.map +1 -0
  93. package/dist/markdownCharacterReferences.js +1127 -0
  94. package/dist/markdownCodeFence.d.ts +4 -0
  95. package/dist/markdownCodeFence.d.ts.map +1 -0
  96. package/dist/markdownCodeFence.js +167 -0
  97. package/dist/markdownExtensionNode.d.ts +88 -0
  98. package/dist/markdownExtensionNode.d.ts.map +1 -0
  99. package/dist/markdownExtensionNode.js +248 -0
  100. package/dist/markdownExtensions.d.ts +115 -0
  101. package/dist/markdownExtensions.d.ts.map +1 -0
  102. package/dist/markdownExtensions.js +392 -0
  103. package/dist/markdownHardLineBreak.d.ts +25 -0
  104. package/dist/markdownHardLineBreak.d.ts.map +1 -0
  105. package/dist/markdownHardLineBreak.js +59 -0
  106. package/dist/markdownHeading.d.ts +20 -0
  107. package/dist/markdownHeading.d.ts.map +1 -0
  108. package/dist/markdownHeading.js +30 -0
  109. package/dist/markdownLink.d.ts +5 -0
  110. package/dist/markdownLink.d.ts.map +1 -0
  111. package/dist/markdownLink.js +80 -0
  112. package/dist/markdownListExport.d.ts +3 -0
  113. package/dist/markdownListExport.d.ts.map +1 -0
  114. package/dist/markdownListExport.js +68 -0
  115. package/dist/markdownListIndentation.d.ts +8 -0
  116. package/dist/markdownListIndentation.d.ts.map +1 -0
  117. package/dist/markdownListIndentation.js +101 -0
  118. package/dist/markdownOrderedList.d.ts +3 -0
  119. package/dist/markdownOrderedList.d.ts.map +1 -0
  120. package/dist/markdownOrderedList.js +51 -0
  121. package/dist/markdownQuote.d.ts +22 -0
  122. package/dist/markdownQuote.d.ts.map +1 -0
  123. package/dist/markdownQuote.js +32 -0
  124. package/dist/markdownSerializers.d.ts +49 -0
  125. package/dist/markdownSerializers.d.ts.map +1 -0
  126. package/dist/markdownSerializers.js +83 -0
  127. package/dist/markdownSource.d.ts +71 -0
  128. package/dist/markdownSource.d.ts.map +1 -0
  129. package/dist/markdownSource.js +804 -0
  130. package/dist/markdownSpaceRuns.d.ts +24 -0
  131. package/dist/markdownSpaceRuns.d.ts.map +1 -0
  132. package/dist/markdownSpaceRuns.js +147 -0
  133. package/dist/markdownTable.d.ts +35 -0
  134. package/dist/markdownTable.d.ts.map +1 -0
  135. package/dist/markdownTable.js +227 -0
  136. package/dist/markdownTaskList.d.ts +48 -0
  137. package/dist/markdownTaskList.d.ts.map +1 -0
  138. package/dist/markdownTaskList.js +166 -0
  139. package/dist/markdownThematicBreak.d.ts +3 -0
  140. package/dist/markdownThematicBreak.d.ts.map +1 -0
  141. package/dist/markdownThematicBreak.js +55 -0
  142. package/dist/privateAttributes/layerPortalBoundary.stylex.d.ts +12 -0
  143. package/dist/privateAttributes/layerPortalBoundary.stylex.d.ts.map +1 -0
  144. package/dist/privateAttributes/layerPortalBoundary.stylex.js +16 -0
  145. package/dist/richtext.css +213 -0
  146. package/dist/textSemantics.d.ts +3 -0
  147. package/dist/textSemantics.d.ts.map +1 -0
  148. package/dist/textSemantics.js +87 -0
  149. package/package.json +158 -3
  150. package/src/RichTextEditor.doc.mjs +308 -0
  151. package/src/RichTextEditor.tsx +1109 -0
  152. package/src/RichTextEditorAutoLinkPlugin.doc.mjs +43 -0
  153. package/src/RichTextEditorAutoLinkPlugin.tsx +126 -0
  154. package/src/RichTextEditorToolbar.doc.mjs +92 -0
  155. package/src/RichTextEditorToolbar.tsx +871 -0
  156. package/src/RichTextView.doc.mjs +101 -0
  157. package/src/RichTextView.tsx +351 -0
  158. package/src/codeLanguages.ts +42 -0
  159. package/src/codeLineTokens.ts +241 -0
  160. package/src/doc-mjs.d.ts +23 -0
  161. package/src/editorNodes.ts +44 -0
  162. package/src/editorTheme.ts +550 -0
  163. package/src/index.ts +59 -0
  164. package/src/internal/CodeBackspacePlugin.tsx +96 -0
  165. package/src/internal/CodeBlockHeaderPlugin.tsx +282 -0
  166. package/src/internal/CodePastePlugin.tsx +144 -0
  167. package/src/internal/CodeSyntaxPlugin.tsx +493 -0
  168. package/src/internal/CodeTabPlugin.tsx +298 -0
  169. package/src/internal/DisabledLinkGuardPlugin.tsx +93 -0
  170. package/src/internal/ImageSourceCaretPlugin.tsx +159 -0
  171. package/src/internal/ListItemShortcutsPlugin.tsx +404 -0
  172. package/src/internal/MarkdownExtensionsPlugin.tsx +289 -0
  173. package/src/internal/SelectAllScopePlugin.tsx +86 -0
  174. package/src/internal/TableColumnFloorPlugin.tsx +99 -0
  175. package/src/internal/TablePastePlugin.tsx +223 -0
  176. package/src/internal/TableScrollRegionPlugin.tsx +107 -0
  177. package/src/internal/TaskCheckboxPlugin.tsx +246 -0
  178. package/src/internal/ToolbarLinkPopover.tsx +392 -0
  179. package/src/linkEditing.ts +20 -0
  180. package/src/linkForm.tsx +156 -0
  181. package/src/linkUtils.ts +106 -0
  182. package/src/markdown.ts +25 -0
  183. package/src/markdownCharacterReferences.ts +1137 -0
  184. package/src/markdownCodeFence.ts +216 -0
  185. package/src/markdownExtensionNode.ts +339 -0
  186. package/src/markdownExtensions.ts +496 -0
  187. package/src/markdownHardLineBreak.ts +73 -0
  188. package/src/markdownHeading.ts +33 -0
  189. package/src/markdownLink.ts +86 -0
  190. package/src/markdownListExport.ts +85 -0
  191. package/src/markdownListIndentation.ts +105 -0
  192. package/src/markdownOrderedList.ts +60 -0
  193. package/src/markdownQuote.ts +35 -0
  194. package/src/markdownSerializers.ts +108 -0
  195. package/src/markdownSource.ts +1045 -0
  196. package/src/markdownSpaceRuns.ts +164 -0
  197. package/src/markdownTable.ts +309 -0
  198. package/src/markdownTaskList.ts +222 -0
  199. package/src/markdownThematicBreak.ts +66 -0
  200. package/src/privateAttributes/layerPortalBoundary.stylex.ts +18 -0
  201. package/src/textSemantics.ts +104 -0
@@ -0,0 +1,4 @@
1
+ import { type MultilineElementTransformer } from '@lexical/markdown';
2
+ export declare const BACKTICK_CODE: MultilineElementTransformer;
3
+ export declare const TILDE_CODE: MultilineElementTransformer;
4
+ //# sourceMappingURL=markdownCodeFence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownCodeFence.d.ts","sourceRoot":"","sources":["../src/markdownCodeFence.ts"],"names":[],"mappings":"AAyBA,OAAO,EAGL,KAAK,2BAA2B,EACjC,MAAM,mBAAmB,CAAC;AAuJ3B,eAAO,MAAM,aAAa,EAAE,2BAqB3B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,2BAYxB,CAAC"}
@@ -0,0 +1,167 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file markdownCodeFence.ts
5
+ * @input Uses @lexical/markdown (CODE) and @lexical/code.
6
+ * @output Exports BACKTICK_CODE and TILDE_CODE, the transformers for fenced
7
+ * code blocks opened with backticks and with tildes.
8
+ * @position Part of DEFAULT_TRANSFORMERS (markdownTable.ts): BACKTICK_CODE
9
+ * stands in for Lexical's CODE, and TILDE_CODE reads the `~~~` fences CODE
10
+ * does not (CommonMark 0.31 §4.5, spec:AST-061 FR5). Both read the opening
11
+ * line as core Markdown does: the rest of the line after the fence is the
12
+ * info string, never code; the language is its first word, after any
13
+ * spaces (so `~~~ c++` reads `c++`), as core and CommonMark read it. A
14
+ * block closes at
15
+ * a fence of its own character at least as long, or at the end of the
16
+ * document, and its code is exactly the lines between, blank lines
17
+ * included, each less as much indentation as the opening fence has (up to
18
+ * three spaces), as core reads it. Each keeps its fence and info
19
+ * string (spec:AST-062): an edited block exports them as written, with its
20
+ * language first when that was changed, and its fence lengthened when its
21
+ * code holds a run of the fence's character that long.
22
+ * A one-line backtick block (```` ```code``` ````) stays Lexical's.
23
+ */
24
+
25
+ import { $createCodeNode, $isCodeNode } from '@lexical/code';
26
+ import { CODE } from '@lexical/markdown';
27
+ import { $createTextNode, $getState, $setState, createState } from 'lexical';
28
+
29
+ /**
30
+ * The tilde fence a code block was opened with; null for a backtick block.
31
+ * Lexical's own fence state holds only backtick fences.
32
+ */
33
+ const tildeFence = createState('astryxTildeFence', {
34
+ parse: value => typeof value === 'string' && /^~{3,}$/.test(value) ? value : null
35
+ });
36
+
37
+ /**
38
+ * The backtick fence a code block was opened with, when longer than three:
39
+ * Lexical's own fence state is set only by its transformer, which this file
40
+ * does not use to build blocks.
41
+ */
42
+ const backtickFence = createState('astryxBacktickFence', {
43
+ parse: value => typeof value === 'string' && /^`{4,}$/.test(value) ? value : null
44
+ });
45
+
46
+ /** The info string a code block's opening fence carried, as written. */
47
+ const fenceInfo = createState('astryxFenceInfo', {
48
+ parse: value => typeof value === 'string' && value !== '' ? value : null
49
+ });
50
+
51
+ /** The language core Markdown reads from an info string, or null. */
52
+ function languageOf(info) {
53
+ return /^\S+/.exec(info.trimStart())?.[0] ?? null;
54
+ }
55
+
56
+ /** An opening fence line: its indentation, its fence, and the info string. */
57
+
58
+ /**
59
+ * Reads an opening fence line: up to three spaces of indentation, then the
60
+ * fence (CommonMark 0.31 §4.5), as core Markdown reads it.
61
+ */
62
+ function readOpening(line) {
63
+ const match = /^( {0,3})(`{3,}|~{3,})(.*)$/.exec(line);
64
+ if (match == null) {
65
+ return null;
66
+ }
67
+ const [, indentation, fence, info] = match;
68
+ // A backtick fence's info string holds no backtick.
69
+ return fence.startsWith('`') && info.includes('`') ? null : {
70
+ indentation: indentation.length,
71
+ fence,
72
+ info
73
+ };
74
+ }
75
+
76
+ /** The longest run of three or more of `character` in `text`, or 0. */
77
+ function longestFenceRun(text, character) {
78
+ return Math.max(0, ...(text.match(character === '`' ? /`{3,}/g : /~{3,}/g) ?? []).map(run => run.length));
79
+ }
80
+
81
+ /**
82
+ * Builds the code block an opening line starts, from the lines after it up
83
+ * to its closing fence, and returns the index of the last line it used.
84
+ */
85
+ function $importFencedCode(rootNode, lines, startLineIndex, opening) {
86
+ const {
87
+ indentation,
88
+ fence,
89
+ info
90
+ } = opening;
91
+ const closing = new RegExp(`^ {0,3}${fence[0] === '`' ? '`' : '~'}{${fence.length},}[ \\t]*$`);
92
+ // Each code line loses as much indentation as the opening fence has.
93
+ const fenceIndentation = new RegExp(`^ {0,${indentation}}`);
94
+ let end = startLineIndex + 1;
95
+ while (end < lines.length && !closing.test(lines[end])) {
96
+ end++;
97
+ }
98
+ // A fence left open runs to the end of the document, whose final line
99
+ // ending starts no line of code (CommonMark 0.31 §4.5), as core reads it.
100
+ const codeEnd = end === lines.length && end > startLineIndex + 1 && lines[end - 1] === '' ? end - 1 : end;
101
+ // The code is the lines between the fences, exactly: Lexical's own
102
+ // transformer trims a space from the first line and drops blank first and
103
+ // last lines, adjustments meant for its own reading of the opening line.
104
+ const block = $createCodeNode(languageOf(info) ?? undefined);
105
+ block.append($createTextNode(lines.slice(startLineIndex + 1, codeEnd).map(line => line.replace(fenceIndentation, '')).join('\n')));
106
+ rootNode.append(block);
107
+ if (fence.startsWith('~')) {
108
+ $setState(block, tildeFence, fence);
109
+ } else if (fence.length > 3) {
110
+ $setState(block, backtickFence, fence);
111
+ }
112
+ $setState(block, fenceInfo, info.trimEnd());
113
+ return Math.min(end, lines.length - 1);
114
+ }
115
+
116
+ /** Writes a code block that keeps its fence or info string; null otherwise. */
117
+ const exportFencedCode = node => {
118
+ if (!$isCodeNode(node)) {
119
+ return null;
120
+ }
121
+ const tilde = $getState(node, tildeFence);
122
+ const backticks = $getState(node, backtickFence);
123
+ const info = $getState(node, fenceInfo);
124
+ if (tilde == null && backticks == null && info == null) {
125
+ return null;
126
+ }
127
+ const text = node.getTextContent();
128
+ const language = node.getLanguage() ?? '';
129
+ let written = info ?? '';
130
+ if ((languageOf(written) ?? '') !== language) {
131
+ // The language changed: it leads, before the rest of the info string.
132
+ const previous = languageOf(written);
133
+ const rest = previous == null ? '' : written.trimStart().slice(previous.length).trim();
134
+ written = rest === '' ? language : `${language} ${rest}`;
135
+ }
136
+ // A fence outlasts any run of its character in the code.
137
+ const fence = tilde != null ? '~'.repeat(Math.max(tilde.length, longestFenceRun(text, '~') + 1)) : '`'.repeat(Math.max((backticks ?? '```').length, longestFenceRun(text, '`') + 1));
138
+ return `${fence}${written}${text === '' ? '' : `\n${text}`}\n${fence}`;
139
+ };
140
+ export const BACKTICK_CODE = {
141
+ ...CODE,
142
+ handleImportAfterStartMatch: args => {
143
+ const opening = readOpening(args.lines[args.startLineIndex]);
144
+ if (opening == null) {
145
+ return CODE.handleImportAfterStartMatch?.(args) ?? null;
146
+ }
147
+ return [true, $importFencedCode(args.rootNode, args.lines, args.startLineIndex, opening)];
148
+ },
149
+ export: (node, exportChildren) => exportFencedCode(node, exportChildren) ?? CODE.export?.(node, exportChildren) ?? null
150
+ };
151
+ export const TILDE_CODE = {
152
+ ...CODE,
153
+ regExpStart: /^( {0,3}~{3,})(.*)$/,
154
+ regExpEnd: {
155
+ optional: true,
156
+ regExp: /^ {0,3}~{3,}[ \t]*$/
157
+ },
158
+ handleImportAfterStartMatch: ({
159
+ lines,
160
+ rootNode,
161
+ startLineIndex
162
+ }) => {
163
+ const opening = readOpening(lines[startLineIndex]);
164
+ return opening == null ? null : [true, $importFencedCode(rootNode, lines, startLineIndex, opening)];
165
+ },
166
+ export: (node, exportChildren) => exportFencedCode(node, exportChildren) ?? null
167
+ };
@@ -0,0 +1,88 @@
1
+ /**
2
+ * @file markdownExtensionNode.ts
3
+ * @input Uses lexical (DecoratorNode, node serialization, text formats).
4
+ * @output Exports RichTextExtensionNode, the editor node for one Markdown
5
+ * plugin node, with $createRichTextExtensionNode and
6
+ * $isRichTextExtensionNode.
7
+ * @position Registered with every RichText surface and serializer
8
+ * (editorNodes.ts), so stored state holding plugin nodes always loads. A
9
+ * node is atomic — the editor cannot type into it — and keeps the exact
10
+ * source it was read from, which is what it exports (spec:AST-064 FR7,
11
+ * FR10). Stored state keeps that source, the plugin's name and protocol
12
+ * version, the data the plugin derived for rendering (FR11), and the text
13
+ * formats the node sits inside, so a node inside emphasis, strong, or
14
+ * strikethrough stays inside it. Imports no React: the client surfaces
15
+ * register how an editor draws plugin nodes.
16
+ */
17
+ import { DecoratorNode, type DOMConversionMap, type DOMExportOutput, type EditorConfig, type LexicalEditor, type LexicalNode, type NodeKey, type NodeSelection, type RangeSelection, type TextNode, type SerializedLexicalNode, type Spread, type TextFormatType } from 'lexical';
18
+ import type { MarkdownPluginData } from '@blue-patterns/core/Markdown/plugins';
19
+ /** What one plugin node is: the parsed node's identity, data, and source. */
20
+ export interface RichTextExtensionNodeFacts {
21
+ readonly plugin: string;
22
+ readonly apiVersion: number;
23
+ readonly name: string;
24
+ readonly display: 'inline' | 'block';
25
+ readonly data: MarkdownPluginData;
26
+ readonly source: string;
27
+ }
28
+ export type SerializedRichTextExtensionNode = Spread<RichTextExtensionNodeFacts & {
29
+ /** The text formats the node sits inside, as a text node's format bits. */
30
+ readonly format: number;
31
+ }, SerializedLexicalNode>;
32
+ /** Reads stored facts defensively: a missing field becomes an empty value. */
33
+ export declare function factsFrom(value: Record<string, unknown>): RichTextExtensionNodeFacts;
34
+ /**
35
+ * Draws a plugin node's content in one editor, inside the text formats the
36
+ * node sits in; `nodeKey` lets it select the node. The client surfaces
37
+ * register one (MarkdownExtensionsPlugin); without one, a node shows its
38
+ * source.
39
+ */
40
+ export type RichTextExtensionNodeDecorator = (facts: RichTextExtensionNodeFacts, format: number, nodeKey: NodeKey) => unknown;
41
+ /** Sets how `editor` draws plugin nodes; returns a function that unsets it. */
42
+ export declare function setRichTextExtensionNodeDecorator(editor: LexicalEditor, decorator: RichTextExtensionNodeDecorator): () => void;
43
+ export declare class RichTextExtensionNode extends DecoratorNode<unknown> {
44
+ __facts: RichTextExtensionNodeFacts;
45
+ /**
46
+ * The text formats the node sits inside, as a text node's format bits. Only
47
+ * inline nodes carry any.
48
+ */
49
+ __format: number;
50
+ static getType(): string;
51
+ static clone(node: RichTextExtensionNode): RichTextExtensionNode;
52
+ static importJSON(serialized: SerializedLexicalNode & Record<string, unknown>): RichTextExtensionNode;
53
+ static importDOM(): DOMConversionMap;
54
+ constructor(facts?: RichTextExtensionNodeFacts, format?: number, key?: NodeKey);
55
+ exportJSON(): SerializedRichTextExtensionNode;
56
+ /** The node's identity, data, and source. */
57
+ getFacts(): RichTextExtensionNodeFacts;
58
+ /** The exact Markdown the node was read from. */
59
+ getSource(): string;
60
+ /** The text formats the node sits inside, as a text node's format bits. */
61
+ getFormat(): number;
62
+ hasFormat(type: TextFormatType): boolean;
63
+ /** Puts the node inside, or takes it out of, one text format. */
64
+ setFormatFlag(type: TextFormatType, isOn: boolean): this;
65
+ createDOM(config: EditorConfig): HTMLElement;
66
+ exportDOM(): DOMExportOutput;
67
+ updateDOM(prevNode: RichTextExtensionNode, dom: HTMLElement): false;
68
+ isInline(): boolean;
69
+ /** The node's text is its source, so plain-text copies and search see it. */
70
+ getTextContent(): string;
71
+ decorate(editor: LexicalEditor): unknown;
72
+ }
73
+ export declare function $createRichTextExtensionNode(facts: RichTextExtensionNodeFacts, format?: number): RichTextExtensionNode;
74
+ export declare function $isRichTextExtensionNode(node: LexicalNode | null | undefined): node is RichTextExtensionNode;
75
+ /**
76
+ * The first text node a range selects characters of, as Lexical's formatText
77
+ * reads it: a range that starts at the end of a text node starts in the next.
78
+ * Null when the range selects no text, only nodes.
79
+ */
80
+ export declare function $firstSelectedText(selection: RangeSelection): TextNode | null;
81
+ /**
82
+ * The inline plugin nodes a selection holds when it holds nothing else: a
83
+ * range that selects no text, only nodes, or a node selection of plugin
84
+ * nodes alone. Null otherwise. A format shown or toggled then belongs to
85
+ * them.
86
+ */
87
+ export declare function $selectedExtensionNodesOnly(selection: RangeSelection | NodeSelection): RichTextExtensionNode[] | null;
88
+ //# sourceMappingURL=markdownExtensionNode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownExtensionNode.d.ts","sourceRoot":"","sources":["../src/markdownExtensionNode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,248 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file markdownExtensionNode.ts
5
+ * @input Uses lexical (DecoratorNode, node serialization, text formats).
6
+ * @output Exports RichTextExtensionNode, the editor node for one Markdown
7
+ * plugin node, with $createRichTextExtensionNode and
8
+ * $isRichTextExtensionNode.
9
+ * @position Registered with every RichText surface and serializer
10
+ * (editorNodes.ts), so stored state holding plugin nodes always loads. A
11
+ * node is atomic — the editor cannot type into it — and keeps the exact
12
+ * source it was read from, which is what it exports (spec:AST-064 FR7,
13
+ * FR10). Stored state keeps that source, the plugin's name and protocol
14
+ * version, the data the plugin derived for rendering (FR11), and the text
15
+ * formats the node sits inside, so a node inside emphasis, strong, or
16
+ * strikethrough stays inside it. Imports no React: the client surfaces
17
+ * register how an editor draws plugin nodes.
18
+ */
19
+
20
+ import { $isNodeSelection, $isTextNode, DecoratorNode, TEXT_TYPE_TO_FORMAT } from 'lexical';
21
+
22
+ /** What one plugin node is: the parsed node's identity, data, and source. */
23
+
24
+ /** Reads stored facts defensively: a missing field becomes an empty value. */
25
+ export function factsFrom(value) {
26
+ const {
27
+ plugin,
28
+ apiVersion,
29
+ name,
30
+ display,
31
+ data,
32
+ source
33
+ } = value;
34
+ return {
35
+ plugin: typeof plugin === 'string' ? plugin : '',
36
+ apiVersion: typeof apiVersion === 'number' ? apiVersion : 0,
37
+ name: typeof name === 'string' ? name : '',
38
+ display: display === 'block' ? 'block' : 'inline',
39
+ data: data ?? null,
40
+ source: typeof source === 'string' ? source : ''
41
+ };
42
+ }
43
+
44
+ /**
45
+ * Draws a plugin node's content in one editor, inside the text formats the
46
+ * node sits in; `nodeKey` lets it select the node. The client surfaces
47
+ * register one (MarkdownExtensionsPlugin); without one, a node shows its
48
+ * source.
49
+ */
50
+
51
+ const decorators = new WeakMap();
52
+
53
+ /** Sets how `editor` draws plugin nodes; returns a function that unsets it. */
54
+ export function setRichTextExtensionNodeDecorator(editor, decorator) {
55
+ decorators.set(editor, decorator);
56
+ return () => {
57
+ if (decorators.get(editor) === decorator) {
58
+ decorators.delete(editor);
59
+ }
60
+ };
61
+ }
62
+
63
+ /**
64
+ * The attribute that carries a node's facts and formats in its element, so
65
+ * copying it as HTML — the browser's own copy, or the editor's HTML export —
66
+ * and pasting it into any RichText editor brings back the same node with the
67
+ * same source and marks.
68
+ */
69
+ const FACTS_ATTRIBUTE = 'data-markdown-extension';
70
+ function factsAttribute(node) {
71
+ return JSON.stringify({
72
+ ...node.__facts,
73
+ format: node.__format
74
+ });
75
+ }
76
+ function convertExtensionElement(element) {
77
+ let node = null;
78
+ try {
79
+ const parsed = JSON.parse(element.getAttribute(FACTS_ATTRIBUTE) ?? '');
80
+ if (parsed != null && typeof parsed === 'object') {
81
+ const value = parsed;
82
+ node = $createRichTextExtensionNode(factsFrom(value), typeof value.format === 'number' ? value.format : 0);
83
+ }
84
+ } catch {
85
+ node = null;
86
+ }
87
+ return {
88
+ node,
89
+ // The element's content is the node's rendering, not more document.
90
+ forChild: () => null
91
+ };
92
+ }
93
+ const importExtensionElement = element => element.hasAttribute(FACTS_ATTRIBUTE) ? {
94
+ conversion: convertExtensionElement,
95
+ priority: 4
96
+ } : null;
97
+ export class RichTextExtensionNode extends DecoratorNode {
98
+ /**
99
+ * The text formats the node sits inside, as a text node's format bits. Only
100
+ * inline nodes carry any.
101
+ */
102
+
103
+ static getType() {
104
+ return 'astryx-markdown-extension';
105
+ }
106
+ static clone(node) {
107
+ return new RichTextExtensionNode(node.__facts, node.__format, node.__key);
108
+ }
109
+ static importJSON(serialized) {
110
+ // Stored state is read defensively, so a damaged node still loads.
111
+ const {
112
+ format
113
+ } = serialized;
114
+ return $createRichTextExtensionNode(factsFrom(serialized), typeof format === 'number' ? format : 0).updateFromJSON(serialized);
115
+ }
116
+ static importDOM() {
117
+ return {
118
+ span: importExtensionElement,
119
+ div: importExtensionElement
120
+ };
121
+ }
122
+
123
+ // The Yjs binding and `$create` call the constructor with no arguments.
124
+ // The binding reads each class's default properties from that node.
125
+ // With no facts, the node gets the values that damaged stored facts get.
126
+ constructor(facts = factsFrom({}), format = 0, key) {
127
+ super(key);
128
+ this.__facts = facts;
129
+ this.__format = facts.display === 'inline' ? format : 0;
130
+ }
131
+ exportJSON() {
132
+ const latest = this.getLatest();
133
+ return {
134
+ ...super.exportJSON(),
135
+ ...latest.__facts,
136
+ format: latest.__format
137
+ };
138
+ }
139
+
140
+ /** The node's identity, data, and source. */
141
+ getFacts() {
142
+ return this.getLatest().__facts;
143
+ }
144
+
145
+ /** The exact Markdown the node was read from. */
146
+ getSource() {
147
+ return this.getLatest().__facts.source;
148
+ }
149
+
150
+ /** The text formats the node sits inside, as a text node's format bits. */
151
+ getFormat() {
152
+ return this.getLatest().__format;
153
+ }
154
+ hasFormat(type) {
155
+ return (this.getFormat() & TEXT_TYPE_TO_FORMAT[type]) !== 0;
156
+ }
157
+
158
+ /** Puts the node inside, or takes it out of, one text format. */
159
+ setFormatFlag(type, isOn) {
160
+ const writable = this.getWritable();
161
+ const flag = TEXT_TYPE_TO_FORMAT[type];
162
+ writable.__format = isOn ? writable.__format | flag : writable.__format & ~flag;
163
+ return writable;
164
+ }
165
+ createDOM(config) {
166
+ const element = document.createElement(this.__facts.display === 'inline' ? 'span' : 'div');
167
+ element.setAttribute(FACTS_ATTRIBUTE, factsAttribute(this));
168
+ if (this.__facts.display === 'block') {
169
+ // A block node is spaced and measured as Markdown spaces its block.
170
+ const className = config.theme.markdownExtensionBlock;
171
+ if (typeof className === 'string' && className !== '') {
172
+ element.className = className;
173
+ }
174
+ }
175
+ return element;
176
+ }
177
+ exportDOM() {
178
+ const element = document.createElement(this.__facts.display === 'inline' ? 'span' : 'div');
179
+ element.setAttribute(FACTS_ATTRIBUTE, factsAttribute(this));
180
+ element.textContent = this.__facts.source;
181
+ return {
182
+ element
183
+ };
184
+ }
185
+ updateDOM(prevNode, dom) {
186
+ // A mark toggled on the node changes what its element carries.
187
+ if (prevNode.__format !== this.__format) {
188
+ dom.setAttribute(FACTS_ATTRIBUTE, factsAttribute(this));
189
+ }
190
+ return false;
191
+ }
192
+ isInline() {
193
+ return this.__facts.display === 'inline';
194
+ }
195
+
196
+ /** The node's text is its source, so plain-text copies and search see it. */
197
+ getTextContent() {
198
+ return this.getLatest().__facts.source;
199
+ }
200
+ decorate(editor) {
201
+ return decorators.get(editor)?.(this.__facts, this.__format, this.__key) ?? this.__facts.source;
202
+ }
203
+ }
204
+ export function $createRichTextExtensionNode(facts, format = 0) {
205
+ return new RichTextExtensionNode(facts, format);
206
+ }
207
+ export function $isRichTextExtensionNode(node) {
208
+ return node instanceof RichTextExtensionNode;
209
+ }
210
+
211
+ /**
212
+ * The first text node a range selects characters of, as Lexical's formatText
213
+ * reads it: a range that starts at the end of a text node starts in the next.
214
+ * Null when the range selects no text, only nodes.
215
+ */
216
+ export function $firstSelectedText(selection) {
217
+ const texts = selection.getNodes().filter($isTextNode);
218
+ const isBackward = selection.isBackward();
219
+ const start = isBackward ? selection.focus : selection.anchor;
220
+ const end = isBackward ? selection.anchor : selection.focus;
221
+ let first = texts[0];
222
+ let startOffset = start.type === 'element' ? 0 : start.offset;
223
+ if (first != null && start.type === 'text' && startOffset === first.getTextContentSize()) {
224
+ first = texts[1];
225
+ startOffset = 0;
226
+ }
227
+ const last = texts[texts.length - 1];
228
+ if (first == null || last == null) {
229
+ return null;
230
+ }
231
+ const endOffset = end.type === 'text' ? end.offset : last.getTextContentSize();
232
+ return first.is(last) && startOffset === endOffset ? null : first;
233
+ }
234
+
235
+ /**
236
+ * The inline plugin nodes a selection holds when it holds nothing else: a
237
+ * range that selects no text, only nodes, or a node selection of plugin
238
+ * nodes alone. Null otherwise. A format shown or toggled then belongs to
239
+ * them.
240
+ */
241
+ export function $selectedExtensionNodesOnly(selection) {
242
+ if ($isNodeSelection(selection)) {
243
+ const selected = selection.getNodes();
244
+ return selected.length > 0 && selected.every(node => $isRichTextExtensionNode(node) && node.isInline()) ? selected : null;
245
+ }
246
+ const nodes = selection.getNodes().filter(node => $isRichTextExtensionNode(node) && node.isInline());
247
+ return nodes.length > 0 && $firstSelectedText(selection) == null ? nodes : null;
248
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * @file markdownExtensions.ts
3
+ * @input Uses core's server-safe plugin protocol (getMarkdownPluginCapabilities)
4
+ * and parser (parseMarkdownAst), lexical, and RichTextExtensionNode.
5
+ * @output Exports createRichTextExtension, RichTextExtensionError, and the
6
+ * RichTextMarkdownExtension type; and, for RichText's own Markdown import and
7
+ * export, the configuration check, the source shielding and restoring that
8
+ * puts core-recognized plugin nodes into the editor, and the transformers
9
+ * that export them.
10
+ * @position Implements spec:AST-064 FR1–FR6 and FR10 for RichText's Markdown
11
+ * import and export. Server-safe: imports no React, DOM, or client module.
12
+ *
13
+ * A plugin is the entry core's createMarkdownPlugin returns; RichText adopts it
14
+ * as it is (FR1), refusing a plugin that declares a transform (FR4, DEC-3).
15
+ * Before Lexical imports a chunk of Markdown, core's parser finds the adopted
16
+ * plugins' nodes in it, and each node's exact source becomes a private-use
17
+ * stand-in that Lexical's transformers read as plain text (FR5, DEC-4). Core
18
+ * reports where a top-level block node sits but not an inline one, so each
19
+ * node is placed at the occurrence of its source that core itself recognizes:
20
+ * replacing that occurrence, and only that one, removes exactly that node from
21
+ * core's parse. After the import, each stand-in becomes an atomic
22
+ * RichTextExtensionNode holding the node's source and data.
23
+ */
24
+ import type { Transformer } from '@lexical/markdown';
25
+ import { TextNode, type ElementNode } from 'lexical';
26
+ import { type MarkdownExtensionNode, type MarkdownPluginEntry } from '@blue-patterns/core/Markdown/plugins';
27
+ import { RichTextExtensionNode } from './markdownExtensionNode.js';
28
+ declare const extensionPlugin: unique symbol;
29
+ /**
30
+ * One Markdown plugin adopted by RichText. Opaque: create it with
31
+ * `createRichTextExtension`, and pass it to the surfaces and serializers that
32
+ * should recognize the plugin's syntax.
33
+ */
34
+ export interface RichTextMarkdownExtension {
35
+ /** The adopted plugin's name. */
36
+ readonly name: string;
37
+ readonly [extensionPlugin]: MarkdownPluginEntry;
38
+ }
39
+ /** Why RichText refused a plugin or a configuration (spec:AST-064 FR4, FR6). */
40
+ export declare class RichTextExtensionError extends Error {
41
+ /** The plugin RichText refused, or that a configuration claims twice. */
42
+ readonly plugin: string;
43
+ /** What RichText cannot honor: `transform`, or what was claimed twice. */
44
+ readonly capability: string;
45
+ /** The transformer or second extension that claims the same thing. */
46
+ readonly claimant: string | null;
47
+ constructor(plugin: string, capability: string, claimant: string | null);
48
+ }
49
+ /**
50
+ * Adopts a Markdown plugin for RichText (spec:AST-064 FR1, FR4). RichText
51
+ * recognizes the plugin's syntax with core's parser and keeps each node's
52
+ * source; it never runs the plugin's immutable transform, so a plugin that
53
+ * declares one is refused with a `RichTextExtensionError` here, before any
54
+ * surface uses it.
55
+ *
56
+ * @example
57
+ * ```
58
+ * const mentions = createRichTextExtension(mentionsPlugin);
59
+ * markdownToEditorStateJSON(markdown, {extensions: [mentions]});
60
+ * ```
61
+ */
62
+ export declare function createRichTextExtension(plugin: MarkdownPluginEntry): RichTextMarkdownExtension;
63
+ /**
64
+ * The plugins behind `extensions`, after checking that the configuration is
65
+ * one RichText can honor (spec:AST-064 FR6): no plugin adopted twice, and no
66
+ * transformer that imports or exports plugin nodes.
67
+ */
68
+ export declare function pluginsOf(extensions: ReadonlyArray<RichTextMarkdownExtension>, transformers: ReadonlyArray<Transformer>): ReadonlyArray<MarkdownPluginEntry>;
69
+ /** A plugin node core recognized, and the stand-in that holds its place. */
70
+ export interface ShieldedNode {
71
+ readonly node: MarkdownExtensionNode;
72
+ readonly apiVersion: number;
73
+ }
74
+ export interface ShieldedMarkdown {
75
+ /** The Markdown with a stand-in in place of each recognized node. */
76
+ readonly markdown: string;
77
+ /** What each stand-in holds the place of. */
78
+ readonly standIns: ReadonlyMap<string, ShieldedNode>;
79
+ }
80
+ /** Private-use characters that do not occur in `text`, in order. */
81
+ export declare function absentCharacters(text: string): Generator<string>;
82
+ /**
83
+ * Replaces the source of every plugin node core recognizes in `markdown` with
84
+ * a stand-in, so Lexical's transformers never read plugin source as base
85
+ * Markdown (spec:AST-064 FR5). A node whose source core does not recognize at
86
+ * any one occurrence — a span split across a container's line markers — stays
87
+ * text.
88
+ */
89
+ export declare function shieldExtensionSources(markdown: string, plugins: ReadonlyArray<MarkdownPluginEntry>): ShieldedMarkdown;
90
+ /**
91
+ * Puts a RichTextExtensionNode in place of every stand-in Lexical imported
92
+ * into `holder`: inline nodes where their stand-in is, and a block node in
93
+ * place of the paragraph that holds only its stand-in.
94
+ */
95
+ export declare function $restoreExtensionSources(holder: ElementNode, standIns: ReadonlyMap<string, ShieldedNode>): void;
96
+ /**
97
+ * Exports every plugin node as its exact source (spec:AST-064 FR10). Always
98
+ * part of RichText's export, whatever transformers the caller passes, so no
99
+ * transformer set can drop a plugin node's source.
100
+ */
101
+ export declare const EXTENSION_EXPORT_TRANSFORMERS: ReadonlyArray<Transformer>;
102
+ /**
103
+ * A text view of an inline plugin node for Lexical's exporter: it reads as
104
+ * text holding `placeholder`, with the node's formats, so emphasis, strong, or
105
+ * strikethrough around the node wraps it instead of closing before it. The
106
+ * caller writes the node's source in place of the placeholder.
107
+ */
108
+ export declare function extensionTextView(node: RichTextExtensionNode, placeholder: string): TextNode;
109
+ /**
110
+ * `transformers` with the plugin node export first, the same array for the
111
+ * same transformers so callers that cache by transformer list keep hitting.
112
+ */
113
+ export declare function withExtensionExport(transformers: ReadonlyArray<Transformer>): Array<Transformer>;
114
+ export {};
115
+ //# sourceMappingURL=markdownExtensions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdownExtensions.d.ts","sourceRoot":"","sources":["../src/markdownExtensions.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAKL,QAAQ,EACR,KAAK,WAAW,EAGjB,MAAM,SAAS,CAAC;AACjB,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACzB,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAGL,qBAAqB,EACtB,MAAM,yBAAyB,CAAC;AAEjC,QAAA,MAAM,eAAe,eAA6C,CAAC;AAEnE;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,iCAAiC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,CAAC,eAAe,CAAC,EAAE,mBAAmB,CAAC;CACjD;AAED,gFAAgF;AAChF,qBAAa,sBAAuB,SAAQ,KAAK;IAC/C,yEAAyE;IACzE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0EAA0E;IAC1E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;gBAErB,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;CAWxE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,mBAAmB,GAC1B,yBAAyB,CAM3B;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CACvB,UAAU,EAAE,aAAa,CAAC,yBAAyB,CAAC,EACpD,YAAY,EAAE,aAAa,CAAC,WAAW,CAAC,GACvC,aAAa,CAAC,mBAAmB,CAAC,CA4BpC;AAMD,4EAA4E;AAC5E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,qBAAqB,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;CACtD;AAQD,oEAAoE;AACpE,wBAAiB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAUjE;AAgDD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,aAAa,CAAC,mBAAmB,CAAC,GAC1C,gBAAgB,CAuDlB;AAgCD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,YAAY,CAAC,GAC1C,IAAI,CAON;AA2FD;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,EAAE,aAAa,CAAC,WAAW,CAsBpE,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,qBAAqB,EAC3B,WAAW,EAAE,MAAM,GAClB,QAAQ,CAOV;AAOD;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,aAAa,CAAC,WAAW,CAAC,GACvC,KAAK,CAAC,WAAW,CAAC,CAOpB"}