chaeditor 0.1.0

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 (40) hide show
  1. package/LICENSE.txt +21 -0
  2. package/README.ko.md +250 -0
  3. package/README.md +242 -0
  4. package/dist/core.cjs +1034 -0
  5. package/dist/core.d.mts +347 -0
  6. package/dist/core.d.ts +347 -0
  7. package/dist/core.mjs +988 -0
  8. package/dist/default-host.cjs +243 -0
  9. package/dist/default-host.d.mts +52 -0
  10. package/dist/default-host.d.ts +52 -0
  11. package/dist/default-host.mjs +239 -0
  12. package/dist/default-markdown-primitive-registry-B3PGEkqs.d.mts +12 -0
  13. package/dist/default-markdown-primitive-registry-CqzwhHj2.d.ts +12 -0
  14. package/dist/image-upload-kind-BJqItE_C.d.mts +18 -0
  15. package/dist/image-upload-kind-BJqItE_C.d.ts +18 -0
  16. package/dist/index.cjs +8736 -0
  17. package/dist/index.d.mts +7 -0
  18. package/dist/index.d.ts +7 -0
  19. package/dist/index.mjs +8668 -0
  20. package/dist/markdown-editor-B1qvE40Z.d.mts +460 -0
  21. package/dist/markdown-editor-Ce6DpnQk.d.ts +460 -0
  22. package/dist/markdown-primitive-contract-BXsqbKwY.d.mts +124 -0
  23. package/dist/markdown-primitive-contract-BXsqbKwY.d.ts +124 -0
  24. package/dist/panda-primitives.cjs +1299 -0
  25. package/dist/panda-primitives.d.mts +21127 -0
  26. package/dist/panda-primitives.d.ts +21127 -0
  27. package/dist/panda-primitives.mjs +1285 -0
  28. package/dist/react.cjs +8558 -0
  29. package/dist/react.d.mts +35 -0
  30. package/dist/react.d.ts +35 -0
  31. package/dist/react.mjs +8531 -0
  32. package/dist/toolbar-preset-B9ttTEol.d.ts +236 -0
  33. package/dist/toolbar-preset-DIsQN390.d.mts +236 -0
  34. package/package.json +151 -0
  35. package/recipes/host-presets/README.md +16 -0
  36. package/recipes/host-presets/emotion-host-preset.tsx.template +109 -0
  37. package/recipes/host-presets/styled-components-host-preset.tsx.template +102 -0
  38. package/recipes/host-presets/tailwind-host-preset.tsx.template +116 -0
  39. package/recipes/host-presets/vanilla-extract-host-preset.tsx.template +116 -0
  40. package/styled-system/styles.css +3370 -0
package/dist/core.cjs ADDED
@@ -0,0 +1,1034 @@
1
+ 'use strict';
2
+
3
+ // src/entities/editor-core/model/editor-attachment-policy.ts
4
+ var MB = 1024 * 1024;
5
+ var EDITOR_ATTACHMENT_MAX_FILE_SIZE = 50 * MB;
6
+ var EDITOR_ATTACHMENT_ALLOWED_EXTENSIONS = [
7
+ "csv",
8
+ "doc",
9
+ "docx",
10
+ "hwp",
11
+ "hwpx",
12
+ "md",
13
+ "pdf",
14
+ "ppt",
15
+ "pptx",
16
+ "txt",
17
+ "xls",
18
+ "xlsx",
19
+ "zip"
20
+ ];
21
+ var EDITOR_ATTACHMENT_ALLOWED_MIME_TYPES = [
22
+ "application/msword",
23
+ "application/hwp+zip",
24
+ "application/pdf",
25
+ "application/vnd.hancom.hwpx",
26
+ "application/x-hwp+zip",
27
+ "application/vnd.ms-excel",
28
+ "application/vnd.ms-powerpoint",
29
+ "application/vnd.openxmlformats-officedocument.presentationml.presentation",
30
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
31
+ "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
32
+ "application/x-hwp",
33
+ "application/x-zip-compressed",
34
+ "application/zip",
35
+ "text/csv",
36
+ "text/markdown",
37
+ "text/plain"
38
+ ];
39
+ var EDITOR_ATTACHMENT_FILE_INPUT_ACCEPT = EDITOR_ATTACHMENT_ALLOWED_EXTENSIONS.map(
40
+ (extension) => `.${extension}`
41
+ ).join(",");
42
+ var isAllowedEditorAttachmentExtension = (fileName) => {
43
+ const baseName = fileName.trim().split("/").pop()?.split("\\").pop()?.trim() ?? "";
44
+ const lastDotIndex = baseName.lastIndexOf(".");
45
+ if (lastDotIndex <= 0 || lastDotIndex === baseName.length - 1) return false;
46
+ const extension = baseName.slice(lastDotIndex + 1).toLowerCase();
47
+ return EDITOR_ATTACHMENT_ALLOWED_EXTENSIONS.includes(
48
+ extension
49
+ );
50
+ };
51
+ var isAllowedEditorAttachmentFile = (file) => {
52
+ if (!file.name.trim() || file.size <= 0 || file.size > EDITOR_ATTACHMENT_MAX_FILE_SIZE) {
53
+ return false;
54
+ }
55
+ if (!isAllowedEditorAttachmentExtension(file.name)) {
56
+ return false;
57
+ }
58
+ if (!file.type) {
59
+ return true;
60
+ }
61
+ return EDITOR_ATTACHMENT_ALLOWED_MIME_TYPES.includes(
62
+ file.type
63
+ );
64
+ };
65
+
66
+ // src/entities/editor-core/model/editor-video-policy.ts
67
+ var MB2 = 1024 * 1024;
68
+ var EDITOR_VIDEO_MAX_FILE_SIZE = 500 * MB2;
69
+ var EDITOR_VIDEO_ALLOWED_EXTENSIONS = ["m4v", "mov", "mp4", "webm"];
70
+ var EDITOR_VIDEO_ALLOWED_MIME_TYPES = [
71
+ "video/mp4",
72
+ "video/quicktime",
73
+ "video/webm",
74
+ "video/x-m4v",
75
+ "application/octet-stream"
76
+ ];
77
+ var EDITOR_VIDEO_FILE_INPUT_ACCEPT = [
78
+ ...EDITOR_VIDEO_ALLOWED_EXTENSIONS.map((extension) => `.${extension}`),
79
+ ...EDITOR_VIDEO_ALLOWED_MIME_TYPES
80
+ ].join(",");
81
+ var isAllowedEditorVideoExtension = (fileName) => {
82
+ const baseName = fileName.trim().split("/").pop()?.split("\\").pop()?.trim() ?? "";
83
+ const lastDotIndex = baseName.lastIndexOf(".");
84
+ if (lastDotIndex <= 0 || lastDotIndex === baseName.length - 1) return false;
85
+ const extension = baseName.slice(lastDotIndex + 1).toLowerCase();
86
+ return EDITOR_VIDEO_ALLOWED_EXTENSIONS.includes(
87
+ extension
88
+ );
89
+ };
90
+ var isAllowedEditorVideoFile = (file) => {
91
+ if (!file.name.trim() || file.size <= 0 || file.size > EDITOR_VIDEO_MAX_FILE_SIZE) {
92
+ return false;
93
+ }
94
+ if (!isAllowedEditorVideoExtension(file.name)) {
95
+ return false;
96
+ }
97
+ if (!file.type) {
98
+ return true;
99
+ }
100
+ return EDITOR_VIDEO_ALLOWED_MIME_TYPES.includes(
101
+ file.type
102
+ );
103
+ };
104
+
105
+ // src/shared/lib/markdown/rich-markdown-inline.ts
106
+ var htmlLineBreakPattern = /<br\s*\/?>/gi;
107
+ var htmlHorizontalRulePattern = /<hr\s*\/?>/gi;
108
+ var markdownLineBreakPlaceholder = "__MD_LINE_BREAK__";
109
+ var markdownHorizontalRulePlaceholder = "__MD_HORIZONTAL_RULE__";
110
+ var inlineStyledSpanPattern = /<span style="([^"]+)">([\s\S]*?)<\/span>/g;
111
+ var inlineUnderlinePattern = /<u>([\s\S]*?)<\/u>/g;
112
+ var inlineSpoilerPattern = /\|\|([^|]+?)\|\|/g;
113
+ var inlineMathPattern = /<Math>([\s\S]*?)<\/Math>/g;
114
+ var fenceBoundaryPattern = /^\s*(`{3,}|~{3,})/;
115
+ var getFenceBoundary = (line, activeFence) => {
116
+ const match = line.match(fenceBoundaryPattern);
117
+ if (!match) return null;
118
+ const delimiter = match[1][0];
119
+ const size = match[1].length;
120
+ if (!activeFence) {
121
+ return {
122
+ delimiter,
123
+ size
124
+ };
125
+ }
126
+ if (activeFence.delimiter !== delimiter || size < activeFence.size) {
127
+ return null;
128
+ }
129
+ return {
130
+ delimiter,
131
+ size
132
+ };
133
+ };
134
+ var transformMarkdownOutsideCode = (markdown, transform) => {
135
+ const lines = markdown.split("\n");
136
+ let activeFence = null;
137
+ return lines.map((line) => {
138
+ const fenceBoundary = getFenceBoundary(line, activeFence);
139
+ if (fenceBoundary) {
140
+ activeFence = activeFence ? null : fenceBoundary;
141
+ return line;
142
+ }
143
+ if (activeFence) {
144
+ return line;
145
+ }
146
+ let transformedLine = "";
147
+ for (let cursor = 0; cursor < line.length; ) {
148
+ if (line[cursor] !== "`") {
149
+ const nextBacktickIndex = line.indexOf("`", cursor);
150
+ const proseSegment = line.slice(
151
+ cursor,
152
+ nextBacktickIndex === -1 ? line.length : nextBacktickIndex
153
+ );
154
+ transformedLine += transform(proseSegment);
155
+ cursor = nextBacktickIndex === -1 ? line.length : nextBacktickIndex;
156
+ continue;
157
+ }
158
+ let tickCount = 1;
159
+ while (line[cursor + tickCount] === "`") {
160
+ tickCount += 1;
161
+ }
162
+ const delimiter = "`".repeat(tickCount);
163
+ const codeStart = cursor;
164
+ const codeEnd = line.indexOf(delimiter, cursor + tickCount);
165
+ if (codeEnd === -1) {
166
+ transformedLine += transform(line.slice(cursor));
167
+ break;
168
+ }
169
+ transformedLine += line.slice(codeStart, codeEnd + tickCount);
170
+ cursor = codeEnd + tickCount;
171
+ }
172
+ return transformedLine;
173
+ }).join("\n");
174
+ };
175
+ var escapeMarkdownLinkLabel = (value) => value.replace(/\\/g, "\\\\").replace(/\[/g, "\\[").replace(/\]/g, "\\]");
176
+ var parseInlineStyle = (style) => {
177
+ const declarations = style.split(";").map((entry) => entry.trim()).filter(Boolean);
178
+ const styleMap = /* @__PURE__ */ new Map();
179
+ declarations.forEach((entry) => {
180
+ const [property, rawValue] = entry.split(":");
181
+ if (!property || !rawValue) return;
182
+ styleMap.set(property.trim().toLowerCase(), rawValue.trim());
183
+ });
184
+ const color = styleMap.get("color");
185
+ const background = styleMap.get("background-color");
186
+ const colorHex = color?.match(/^#[0-9A-Fa-f]{6}$/)?.[0];
187
+ const backgroundHex = background?.match(/^#[0-9A-Fa-f]{6}$/)?.[0];
188
+ return {
189
+ backgroundHex,
190
+ colorHex
191
+ };
192
+ };
193
+ var preprocessMarkdownInlineSyntax = (markdown) => transformMarkdownOutsideCode(
194
+ markdown,
195
+ (value) => value.replace(inlineStyledSpanPattern, (_, rawStyle, text) => {
196
+ const escapedText = escapeMarkdownLinkLabel(text.trim() || "Text");
197
+ const { backgroundHex, colorHex } = parseInlineStyle(rawStyle);
198
+ if (backgroundHex && colorHex) {
199
+ return `[${escapedText}](#md-style:color=${colorHex};background=${backgroundHex})`;
200
+ }
201
+ if (backgroundHex) {
202
+ return `[${escapedText}](#md-bg:${backgroundHex})`;
203
+ }
204
+ if (colorHex) {
205
+ return `[${escapedText}](#md-color:${colorHex})`;
206
+ }
207
+ return text;
208
+ }).replace(inlineUnderlinePattern, (_, text) => {
209
+ const escapedText = escapeMarkdownLinkLabel(text.trim() || "Text");
210
+ return `[${escapedText}](#md-underline:)`;
211
+ }).replace(inlineSpoilerPattern, (_, text) => {
212
+ const escapedText = escapeMarkdownLinkLabel(text.trim() || "Spoiler");
213
+ return `[${escapedText}](#md-spoiler:)`;
214
+ }).replace(inlineMathPattern, (_, formula) => {
215
+ const normalizedFormula = formula.trim();
216
+ const encodedFormula = encodeURIComponent(normalizedFormula);
217
+ const escapedLabel = escapeMarkdownLinkLabel(normalizedFormula || "math");
218
+ return `[${escapedLabel}](#md-math:${encodedFormula})`;
219
+ })
220
+ );
221
+ var normalizeMarkdownHtmlAliases = (markdown) => transformMarkdownOutsideCode(
222
+ markdown,
223
+ (value) => value.replace(htmlHorizontalRulePattern, markdownHorizontalRulePlaceholder).replace(htmlLineBreakPattern, markdownLineBreakPlaceholder)
224
+ ).replace(new RegExp(markdownLineBreakPlaceholder, "g"), " \n").replace(
225
+ new RegExp(`(^|
226
+ )${markdownHorizontalRulePlaceholder}(?=
227
+ |$)`, "g"),
228
+ (_, prefix) => `${prefix}---`
229
+ ).replace(new RegExp(markdownHorizontalRulePlaceholder, "g"), "\n---\n");
230
+
231
+ // src/shared/lib/url/normalize-http-url.ts
232
+ var normalizeHttpUrl = (rawUrl) => {
233
+ const trimmed = rawUrl?.trim();
234
+ if (!trimmed) return null;
235
+ try {
236
+ const parsed = new URL(trimmed);
237
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
238
+ return null;
239
+ }
240
+ return parsed.toString();
241
+ } catch {
242
+ return null;
243
+ }
244
+ };
245
+
246
+ // src/entities/editor-core/model/markdown-link.ts
247
+ var createMarkdownLink = (label, url, title) => {
248
+ const normalizedUrl = normalizeHttpUrl(url);
249
+ const normalizedLabel = label.trim();
250
+ if (!normalizedUrl) {
251
+ return normalizedLabel ? label : url.trim();
252
+ }
253
+ const resolvedLabel = normalizedLabel ? label : normalizedUrl;
254
+ const serializedTitle = title ? ` "${title}"` : "";
255
+ return `[${resolvedLabel}](${normalizedUrl}${serializedTitle})`;
256
+ };
257
+ var createMarkdownLinkByMode = ({ label, mode, url }) => {
258
+ if (mode === "embed") {
259
+ const normalizedUrl = normalizeHttpUrl(url);
260
+ if (!normalizedUrl) {
261
+ return label.trim() || url.trim();
262
+ }
263
+ return `[embed](${normalizedUrl})`;
264
+ }
265
+ if (mode === "preview" || mode === "card") {
266
+ return createMarkdownLink(label, url, mode);
267
+ }
268
+ return createMarkdownLink(label, url);
269
+ };
270
+ var extractLabelAndUrl = (clipboardText) => {
271
+ const match = clipboardText.trim().match(/^(?<label>.+?)\s+(?<url>https?:\/\/\S+)$/su);
272
+ const label = match?.groups?.label?.trim() ?? "";
273
+ const url = normalizeHttpUrl(match?.groups?.url);
274
+ if (!label || !url) return null;
275
+ return { label, url };
276
+ };
277
+ var buildEditorLinkInsertion = ({
278
+ clipboardText,
279
+ selectedText
280
+ }) => {
281
+ const normalizedUrl = normalizeHttpUrl(clipboardText);
282
+ const hasSelectedText = selectedText.trim().length > 0;
283
+ if (normalizedUrl && hasSelectedText) {
284
+ return {
285
+ text: createMarkdownLink(selectedText, normalizedUrl),
286
+ type: "link"
287
+ };
288
+ }
289
+ if (normalizedUrl) {
290
+ return {
291
+ text: createMarkdownLink(normalizedUrl, normalizedUrl),
292
+ type: "link"
293
+ };
294
+ }
295
+ const extracted = extractLabelAndUrl(clipboardText);
296
+ if (!extracted) return null;
297
+ return {
298
+ text: createMarkdownLink(extracted.label, extracted.url),
299
+ type: "link"
300
+ };
301
+ };
302
+
303
+ // src/shared/lib/markdown/collect-markdown-images.ts
304
+ var markdownImagePattern = /!\[(?<alt>[^\]]*)\]\((?<src>[^)\s]+)(?:\s+(?:"[^"]*"|'[^']*'|\([^)]*\)))?\)/g;
305
+ var galleryStartPattern = /^:::gallery\s*$/;
306
+ var galleryEndPattern = /^:::\s*$/;
307
+ var collectMarkdownImages = (markdown) => {
308
+ const items = [];
309
+ let imageIndex = 0;
310
+ let isInsideGallery = false;
311
+ for (const line of markdown.split("\n")) {
312
+ if (galleryStartPattern.test(line)) {
313
+ isInsideGallery = true;
314
+ continue;
315
+ }
316
+ if (isInsideGallery && galleryEndPattern.test(line)) {
317
+ isInsideGallery = false;
318
+ continue;
319
+ }
320
+ if (isInsideGallery) continue;
321
+ for (const matched of line.matchAll(markdownImagePattern)) {
322
+ const alt = matched.groups?.alt?.trim() ?? "";
323
+ const src = matched.groups?.src?.trim() ?? "";
324
+ if (!src) continue;
325
+ items.push({
326
+ alt,
327
+ src,
328
+ viewerId: `markdown-image-${imageIndex}`
329
+ });
330
+ imageIndex += 1;
331
+ }
332
+ }
333
+ return items;
334
+ };
335
+
336
+ // src/shared/lib/markdown/rich-markdown-segments.ts
337
+ var toggleStartPrefix = ":::toggle ";
338
+ var galleryStartPattern2 = /^:::gallery\s*$/;
339
+ var alignStartPattern = /^:::align (left|center|right)\s*$/;
340
+ var legacyYoutubePattern = /^<YouTube id="([^"]+)" \/>$/;
341
+ var videoPattern = /^<Video provider="([^"]+)"(?: id="([^"]+)")?(?: src="([^"]+)")? \/>$/;
342
+ var attachmentPattern = /^<Attachment href="([^"]+)" name="([^"]+)"(?: size="(\d+)")?(?: type="([^"]+)")? \/>$/;
343
+ var mathPattern = /^<Math(?: block="(true)")?>([\s\S]+?)<\/Math>$/;
344
+ var subtextPrefix = "-# ";
345
+ var fenceBoundaryPattern2 = /^\s*(`{3,}|~{3,})/;
346
+ var decodeHtmlAttributeEntities = (value) => value.replaceAll("&quot;", '"').replaceAll("&#39;", "'").replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&amp;", "&");
347
+ var getFenceBoundary2 = (line, activeFence) => {
348
+ const match = line.match(fenceBoundaryPattern2);
349
+ if (!match) return null;
350
+ const delimiter = match[1][0];
351
+ const size = match[1].length;
352
+ if (!activeFence) {
353
+ return {
354
+ delimiter,
355
+ size
356
+ };
357
+ }
358
+ if (activeFence.delimiter !== delimiter || size < activeFence.size) {
359
+ return null;
360
+ }
361
+ return {
362
+ delimiter,
363
+ size
364
+ };
365
+ };
366
+ var parseToggleTitle = (rawTitle) => {
367
+ const trimmedTitle = rawTitle.trim();
368
+ const headingMatch = trimmedTitle.match(/^(#{1,4})(?:\s+(.*))?$/);
369
+ const fallbackTitle = "Untitled toggle";
370
+ if (!trimmedTitle) {
371
+ return {
372
+ headingLevel: null,
373
+ title: fallbackTitle
374
+ };
375
+ }
376
+ if (!headingMatch) {
377
+ return {
378
+ headingLevel: null,
379
+ title: trimmedTitle || fallbackTitle
380
+ };
381
+ }
382
+ return {
383
+ headingLevel: headingMatch[1].length,
384
+ title: headingMatch[2]?.trim() || fallbackTitle
385
+ };
386
+ };
387
+ var consumeCustomBlockBody = (lines, startIndex) => {
388
+ const bodyLines = [];
389
+ let activeFence = null;
390
+ let cursor = startIndex;
391
+ while (cursor < lines.length) {
392
+ const line = lines[cursor];
393
+ const fenceBoundary = getFenceBoundary2(line, activeFence);
394
+ if (fenceBoundary) {
395
+ bodyLines.push(line);
396
+ activeFence = activeFence ? null : fenceBoundary;
397
+ cursor += 1;
398
+ continue;
399
+ }
400
+ if (!activeFence && line === ":::") {
401
+ break;
402
+ }
403
+ bodyLines.push(line);
404
+ cursor += 1;
405
+ }
406
+ return {
407
+ bodyLines,
408
+ cursor
409
+ };
410
+ };
411
+ var parseRichMarkdownSegments = (markdown) => {
412
+ const lines = markdown.split("\n");
413
+ const segments = [];
414
+ const currentMarkdownLines = [];
415
+ let activeFence = null;
416
+ const flushMarkdown = () => {
417
+ if (currentMarkdownLines.length === 0) return;
418
+ segments.push({
419
+ markdown: currentMarkdownLines.join("\n"),
420
+ type: "markdown"
421
+ });
422
+ currentMarkdownLines.length = 0;
423
+ };
424
+ for (let index = 0; index < lines.length; index += 1) {
425
+ const line = lines[index];
426
+ const fenceBoundary = getFenceBoundary2(line, activeFence);
427
+ if (fenceBoundary) {
428
+ currentMarkdownLines.push(line);
429
+ activeFence = activeFence ? null : fenceBoundary;
430
+ continue;
431
+ }
432
+ if (activeFence) {
433
+ currentMarkdownLines.push(line);
434
+ continue;
435
+ }
436
+ if (line.startsWith(toggleStartPrefix)) {
437
+ flushMarkdown();
438
+ const { bodyLines, cursor } = consumeCustomBlockBody(lines, index + 1);
439
+ const { headingLevel, title } = parseToggleTitle(line.slice(toggleStartPrefix.length));
440
+ segments.push({
441
+ content: bodyLines.join("\n"),
442
+ headingLevel,
443
+ title,
444
+ type: "toggle"
445
+ });
446
+ index = cursor;
447
+ continue;
448
+ }
449
+ const alignMatch = line.match(alignStartPattern);
450
+ if (alignMatch) {
451
+ flushMarkdown();
452
+ const { bodyLines, cursor } = consumeCustomBlockBody(lines, index + 1);
453
+ segments.push({
454
+ align: alignMatch[1],
455
+ content: bodyLines.join("\n"),
456
+ type: "align"
457
+ });
458
+ index = cursor;
459
+ continue;
460
+ }
461
+ if (galleryStartPattern2.test(line)) {
462
+ flushMarkdown();
463
+ const { bodyLines, cursor } = consumeCustomBlockBody(lines, index + 1);
464
+ segments.push({
465
+ items: collectMarkdownImages(bodyLines.join("\n")),
466
+ type: "gallery"
467
+ });
468
+ index = cursor;
469
+ continue;
470
+ }
471
+ const videoMatch = line.match(videoPattern);
472
+ if (videoMatch && (videoMatch[1] === "youtube" || videoMatch[1] === "upload")) {
473
+ flushMarkdown();
474
+ segments.push({
475
+ provider: videoMatch[1],
476
+ src: videoMatch[3] ? decodeHtmlAttributeEntities(videoMatch[3]) : void 0,
477
+ type: "video",
478
+ videoId: videoMatch[2] ? decodeHtmlAttributeEntities(videoMatch[2]) : void 0
479
+ });
480
+ continue;
481
+ }
482
+ const legacyYoutubeMatch = line.match(legacyYoutubePattern);
483
+ if (legacyYoutubeMatch) {
484
+ flushMarkdown();
485
+ segments.push({
486
+ provider: "youtube",
487
+ type: "video",
488
+ videoId: decodeHtmlAttributeEntities(legacyYoutubeMatch[1])
489
+ });
490
+ continue;
491
+ }
492
+ const attachmentMatch = line.match(attachmentPattern);
493
+ if (attachmentMatch) {
494
+ flushMarkdown();
495
+ segments.push({
496
+ contentType: attachmentMatch[4] ? decodeHtmlAttributeEntities(attachmentMatch[4]) : void 0,
497
+ fileName: decodeHtmlAttributeEntities(attachmentMatch[2]),
498
+ fileSize: attachmentMatch[3] ? Number(attachmentMatch[3]) : void 0,
499
+ href: decodeHtmlAttributeEntities(attachmentMatch[1]),
500
+ type: "attachment"
501
+ });
502
+ continue;
503
+ }
504
+ const mathMatch = line.match(mathPattern);
505
+ if (mathMatch) {
506
+ flushMarkdown();
507
+ segments.push({
508
+ formula: mathMatch[2],
509
+ isBlock: mathMatch[1] === "true",
510
+ type: "math"
511
+ });
512
+ continue;
513
+ }
514
+ if (line.startsWith(subtextPrefix)) {
515
+ flushMarkdown();
516
+ const subtextLines = [line.slice(subtextPrefix.length)];
517
+ let cursor = index + 1;
518
+ while (cursor < lines.length && lines[cursor].startsWith(subtextPrefix)) {
519
+ subtextLines.push(lines[cursor].slice(subtextPrefix.length));
520
+ cursor += 1;
521
+ }
522
+ segments.push({
523
+ content: subtextLines.join("\n"),
524
+ type: "subtext"
525
+ });
526
+ index = cursor - 1;
527
+ continue;
528
+ }
529
+ currentMarkdownLines.push(line);
530
+ }
531
+ flushMarkdown();
532
+ return segments;
533
+ };
534
+
535
+ // src/entities/editor-core/model/video-embed.ts
536
+ var escapeJsxAttribute = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;").replaceAll("'", "&#39;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
537
+ var getFirstPathSegment = (pathname) => pathname.split("/").find((segment) => segment.length > 0) ?? null;
538
+ var extractVideoEmbedReference = (value) => {
539
+ const trimmedValue = value.trim();
540
+ if (!trimmedValue) return null;
541
+ try {
542
+ const url = new URL(trimmedValue);
543
+ const isYoutubeDomain = url.hostname === "youtube.com" || url.hostname.endsWith(".youtube.com");
544
+ if (url.hostname === "youtu.be") {
545
+ const videoId = getFirstPathSegment(url.pathname);
546
+ return videoId ? {
547
+ provider: "youtube",
548
+ videoId
549
+ } : null;
550
+ }
551
+ if (isYoutubeDomain) {
552
+ if (url.pathname === "/watch") {
553
+ const videoId = url.searchParams.get("v");
554
+ return videoId ? {
555
+ provider: "youtube",
556
+ videoId
557
+ } : null;
558
+ }
559
+ const [, firstSegment, secondSegment] = url.pathname.split("/");
560
+ if (firstSegment === "shorts" && secondSegment) {
561
+ return {
562
+ provider: "youtube",
563
+ videoId: secondSegment
564
+ };
565
+ }
566
+ if (firstSegment === "embed" && secondSegment) {
567
+ return {
568
+ provider: "youtube",
569
+ videoId: secondSegment
570
+ };
571
+ }
572
+ }
573
+ } catch {
574
+ return null;
575
+ }
576
+ return null;
577
+ };
578
+ var extractYoutubeId = (value) => {
579
+ const reference = extractVideoEmbedReference(value);
580
+ return reference?.provider === "youtube" ? reference.videoId : null;
581
+ };
582
+ var createVideoEmbedMarkdown = (reference) => {
583
+ if (reference.provider === "upload") {
584
+ return `<Video provider="upload" src="${escapeJsxAttribute(reference.src)}" />`;
585
+ }
586
+ return `<Video provider="${reference.provider}" id="${escapeJsxAttribute(reference.videoId)}" />`;
587
+ };
588
+ var createYoutubeEmbedMarkdown = (videoId) => createVideoEmbedMarkdown({
589
+ provider: "youtube",
590
+ videoId
591
+ });
592
+ var createUploadedVideoEmbedMarkdown = (src) => createVideoEmbedMarkdown({
593
+ provider: "upload",
594
+ src
595
+ });
596
+
597
+ // src/features/edit-markdown/toolbar/contracts/markdown-toolbar-templates.ts
598
+ var escapeMarkdownAltText = (value) => value.replaceAll("]", "\\]");
599
+ var escapeMarkdownLinkDestination = (value) => value.replaceAll("\\", "\\\\").replaceAll("(", "\\(").replaceAll(")", "\\)").replaceAll("<", "%3C").replaceAll(">", "%3E");
600
+ var normalizeMathFormula = (value) => value.trim().replaceAll(/\s*\n+\s*/g, " ");
601
+ var escapeJsxAttribute2 = (value) => value.replaceAll("&", "&amp;").replaceAll('"', "&quot;");
602
+ var createImageEmbedMarkdown = (altText, url) => `![${escapeMarkdownAltText(altText)}](${escapeMarkdownLinkDestination(url)})`;
603
+ var createImageEmbedMarkdownGroup = (items) => items.map((item) => createImageEmbedMarkdown(item.altText, item.url)).join("\n\n");
604
+ var createImageGalleryMarkdown = (items) => [
605
+ ":::gallery",
606
+ ...items.map((item) => createImageEmbedMarkdown(item.altText, item.url)),
607
+ ":::"
608
+ ].join("\n");
609
+ var createAttachmentEmbedMarkdown = ({
610
+ contentType,
611
+ fileName,
612
+ fileSize,
613
+ url
614
+ }) => `<Attachment href="${escapeJsxAttribute2(url)}" name="${escapeJsxAttribute2(fileName)}" size="${String(fileSize)}" type="${escapeJsxAttribute2(contentType)}" />`;
615
+ var createMathEmbedMarkdown = ({
616
+ formula,
617
+ isBlock
618
+ }) => {
619
+ const normalizedFormula = normalizeMathFormula(formula);
620
+ if (isBlock) {
621
+ return `
622
+ <Math block="true">${normalizedFormula}</Math>
623
+ `;
624
+ }
625
+ return `<Math>${normalizedFormula}</Math>`;
626
+ };
627
+ var createAlignBlockMarkdown = (align) => {
628
+ const before = `:::align ${align}
629
+ `;
630
+ return {
631
+ cursorOffset: before.length,
632
+ text: `${before}Text
633
+ :::`
634
+ };
635
+ };
636
+ var createToggleBlockMarkdown = (level, selectedText) => {
637
+ const headingPrefix = "#".repeat(level);
638
+ if (!selectedText) {
639
+ const prefix = `:::toggle ${headingPrefix} `;
640
+ return {
641
+ cursorOffset: prefix.length,
642
+ text: `${prefix}
643
+ :::`
644
+ };
645
+ }
646
+ return {
647
+ cursorOffset: `:::toggle ${headingPrefix} `.length + selectedText.length,
648
+ text: `:::toggle ${headingPrefix} ${selectedText}
649
+ Content
650
+ :::`
651
+ };
652
+ };
653
+
654
+ // src/entities/editor-core/model/selection-utils.ts
655
+ var pendingSelectionStartKey = "selectionUtilsPendingStart";
656
+ var pendingSelectionEndKey = "selectionUtilsPendingEnd";
657
+ var setPendingSelection = (textarea, start, end) => {
658
+ textarea.dataset[pendingSelectionStartKey] = String(start);
659
+ textarea.dataset[pendingSelectionEndKey] = String(end);
660
+ };
661
+ var getSelectedLineRange = (textarea) => {
662
+ const { selectionEnd, selectionStart, value } = textarea;
663
+ const lineStart = selectionStart === 0 ? 0 : value.lastIndexOf("\n", selectionStart - 1) + 1;
664
+ const nextLineBreakIndex = value.indexOf("\n", selectionEnd);
665
+ const lineEnd = nextLineBreakIndex === -1 ? value.length : nextLineBreakIndex;
666
+ return {
667
+ lineEnd,
668
+ lineStart,
669
+ text: value.slice(lineStart, lineEnd)
670
+ };
671
+ };
672
+ var headingPrefixPattern = /^(#{1,6})\s+/;
673
+ var unorderedListPattern = /^(\s*)([-*])\s+(.*)$/;
674
+ var unorderedListMarkerOnlyPattern = /^(\s*)([-*])\s*$/;
675
+ var orderedListPattern = /^(\s*)(\d+)\.\s+(.*)$/;
676
+ var orderedListMarkerOnlyPattern = /^(\s*)(\d+)\.\s*$/;
677
+ var listItemPattern = /^(\s*)((?:[-*])|(?:\d+\.))\s+/;
678
+ var replaceSelectedLineRange = (textarea, nextBlock, lineStart, lineEnd) => {
679
+ const nextValue = [
680
+ textarea.value.slice(0, lineStart),
681
+ nextBlock,
682
+ textarea.value.slice(lineEnd)
683
+ ].join("");
684
+ setPendingSelection(textarea, lineStart, lineStart + nextBlock.length);
685
+ return nextValue;
686
+ };
687
+ var wrapSelection = (textarea, before, after, placeholder = "Text") => {
688
+ const { selectionEnd, selectionStart, value } = textarea;
689
+ const selectedText = value.slice(selectionStart, selectionEnd);
690
+ const nextSelectionText = selectedText || placeholder;
691
+ const nextValue = [
692
+ value.slice(0, selectionStart),
693
+ before,
694
+ nextSelectionText,
695
+ after,
696
+ value.slice(selectionEnd)
697
+ ].join("");
698
+ const nextStart = selectionStart + before.length;
699
+ const nextEnd = nextStart + nextSelectionText.length;
700
+ setPendingSelection(textarea, nextStart, nextEnd);
701
+ return nextValue;
702
+ };
703
+ var prefixLine = (textarea, prefix) => {
704
+ const { lineEnd, lineStart, text } = getSelectedLineRange(textarea);
705
+ const lines = text.split("\n");
706
+ const nonEmptyLines = lines.filter((line) => line.length > 0);
707
+ const shouldRemovePrefix = nonEmptyLines.length > 0 && nonEmptyLines.every((line) => line.startsWith(prefix));
708
+ const nextLines = lines.map((line) => {
709
+ if (line.length === 0) return line;
710
+ if (shouldRemovePrefix) {
711
+ return line.startsWith(prefix) ? line.slice(prefix.length) : line;
712
+ }
713
+ return line.startsWith(prefix) ? line : `${prefix}${line}`;
714
+ });
715
+ const nextBlock = nextLines.join("\n");
716
+ const nextValue = [
717
+ textarea.value.slice(0, lineStart),
718
+ nextBlock,
719
+ textarea.value.slice(lineEnd)
720
+ ].join("");
721
+ setPendingSelection(textarea, lineStart, lineStart + nextBlock.length);
722
+ return nextValue;
723
+ };
724
+ var insertTemplate = (textarea, template, cursorOffset = template.length) => {
725
+ const { selectionEnd, selectionStart, value } = textarea;
726
+ const nextValue = [value.slice(0, selectionStart), template, value.slice(selectionEnd)].join("");
727
+ const nextCursor = selectionStart + cursorOffset;
728
+ setPendingSelection(textarea, nextCursor, nextCursor);
729
+ return nextValue;
730
+ };
731
+ var restoreCursor = (textarea, start, end) => {
732
+ const maxIndex = textarea.value.length;
733
+ const nextStart = Math.max(0, Math.min(start, maxIndex));
734
+ const nextEnd = Math.max(nextStart, Math.min(end, maxIndex));
735
+ textarea.setSelectionRange(nextStart, nextEnd);
736
+ delete textarea.dataset[pendingSelectionStartKey];
737
+ delete textarea.dataset[pendingSelectionEndKey];
738
+ };
739
+ var focusTextarea = (textarea) => {
740
+ textarea.focus({ preventScroll: true });
741
+ };
742
+ var getPendingSelection = (textarea) => {
743
+ const start = Number(textarea.dataset[pendingSelectionStartKey]);
744
+ const end = Number(textarea.dataset[pendingSelectionEndKey]);
745
+ if (!Number.isFinite(start) || !Number.isFinite(end)) {
746
+ return {
747
+ end: textarea.selectionEnd,
748
+ start: textarea.selectionStart
749
+ };
750
+ }
751
+ return { end, start };
752
+ };
753
+ var applyTextareaTransform = (textarea, onChange, transform) => {
754
+ const nextValue = transform(textarea);
755
+ onChange(nextValue);
756
+ queueMicrotask(() => {
757
+ const pendingSelection = getPendingSelection(textarea);
758
+ focusTextarea(textarea);
759
+ restoreCursor(textarea, pendingSelection.start, pendingSelection.end);
760
+ });
761
+ return nextValue;
762
+ };
763
+ var toggleHeadingLine = (textarea, level) => {
764
+ const { lineEnd, lineStart, text } = getSelectedLineRange(textarea);
765
+ const lines = text.split("\n");
766
+ const targetPrefix = `${"#".repeat(level)} `;
767
+ if (lines.length === 1 && lines[0].trim().length === 0) {
768
+ const nextValue = [
769
+ textarea.value.slice(0, lineStart),
770
+ targetPrefix,
771
+ textarea.value.slice(lineEnd)
772
+ ].join("");
773
+ setPendingSelection(textarea, lineStart + targetPrefix.length, lineStart + targetPrefix.length);
774
+ return nextValue;
775
+ }
776
+ const nonEmptyLines = lines.filter((line) => line.trim().length > 0);
777
+ const shouldRemoveTargetPrefix = nonEmptyLines.length > 0 && nonEmptyLines.every((line) => line.startsWith(targetPrefix));
778
+ const nextLines = lines.map((line) => {
779
+ if (line.trim().length === 0) return line;
780
+ if (shouldRemoveTargetPrefix) {
781
+ return line.startsWith(targetPrefix) ? line.slice(targetPrefix.length) : line;
782
+ }
783
+ return line.replace(headingPrefixPattern, "") === line ? `${targetPrefix}${line}` : line.replace(headingPrefixPattern, targetPrefix);
784
+ });
785
+ return replaceSelectedLineRange(textarea, nextLines.join("\n"), lineStart, lineEnd);
786
+ };
787
+ var continueMarkdownList = (textarea) => {
788
+ const { selectionEnd, selectionStart, value } = textarea;
789
+ if (selectionStart !== selectionEnd) return null;
790
+ const lineStart = value.lastIndexOf("\n", selectionStart - 1) + 1;
791
+ const lineEnd = value.indexOf("\n", selectionStart);
792
+ const resolvedLineEnd = lineEnd === -1 ? value.length : lineEnd;
793
+ const currentLine = value.slice(lineStart, resolvedLineEnd);
794
+ const unorderedMatch = currentLine.match(unorderedListPattern);
795
+ if (unorderedMatch) {
796
+ const [, indent, marker, content] = unorderedMatch;
797
+ const nextLine = content.trim().length === 0 ? "" : `
798
+ ${indent}${marker} `;
799
+ const nextValue = `${value.slice(0, selectionStart)}${nextLine}${value.slice(selectionEnd)}`;
800
+ const nextCursor = selectionStart + nextLine.length;
801
+ setPendingSelection(textarea, nextCursor, nextCursor);
802
+ return nextValue;
803
+ }
804
+ const unorderedMarkerOnlyMatch = currentLine.match(unorderedListMarkerOnlyPattern);
805
+ if (unorderedMarkerOnlyMatch) {
806
+ const [, indent] = unorderedMarkerOnlyMatch;
807
+ const replacement = indent;
808
+ const nextValue = [value.slice(0, lineStart), replacement, value.slice(resolvedLineEnd)].join(
809
+ ""
810
+ );
811
+ const nextCursor = lineStart + replacement.length;
812
+ setPendingSelection(textarea, nextCursor, nextCursor);
813
+ return nextValue;
814
+ }
815
+ const orderedMatch = currentLine.match(orderedListPattern);
816
+ if (orderedMatch) {
817
+ const [, indent, numberText, content] = orderedMatch;
818
+ const nextLine = content.trim().length === 0 ? "" : `
819
+ ${indent}${Number(numberText) + 1}. `;
820
+ const nextValue = `${value.slice(0, selectionStart)}${nextLine}${value.slice(selectionEnd)}`;
821
+ const nextCursor = selectionStart + nextLine.length;
822
+ setPendingSelection(textarea, nextCursor, nextCursor);
823
+ return nextValue;
824
+ }
825
+ const orderedMarkerOnlyMatch = currentLine.match(orderedListMarkerOnlyPattern);
826
+ if (orderedMarkerOnlyMatch) {
827
+ const [, indent] = orderedMarkerOnlyMatch;
828
+ const replacement = indent;
829
+ const nextValue = [value.slice(0, lineStart), replacement, value.slice(resolvedLineEnd)].join(
830
+ ""
831
+ );
832
+ const nextCursor = lineStart + replacement.length;
833
+ setPendingSelection(textarea, nextCursor, nextCursor);
834
+ return nextValue;
835
+ }
836
+ return null;
837
+ };
838
+ var indentMarkdownList = (textarea) => {
839
+ const { lineEnd, lineStart, text } = getSelectedLineRange(textarea);
840
+ const lines = text.split("\n");
841
+ if (!lines.some((line) => listItemPattern.test(line))) {
842
+ return null;
843
+ }
844
+ const nextLines = lines.map((line) => listItemPattern.test(line) ? ` ${line}` : line);
845
+ return replaceSelectedLineRange(textarea, nextLines.join("\n"), lineStart, lineEnd);
846
+ };
847
+ var outdentMarkdownList = (textarea) => {
848
+ const { lineEnd, lineStart, text } = getSelectedLineRange(textarea);
849
+ const lines = text.split("\n");
850
+ if (!lines.some((line) => listItemPattern.test(line))) {
851
+ return null;
852
+ }
853
+ const nextLines = lines.map((line) => {
854
+ if (!listItemPattern.test(line)) return line;
855
+ if (line.startsWith(" ")) return line.slice(2);
856
+ if (line.startsWith(" ")) return line.slice(1);
857
+ return line;
858
+ });
859
+ return replaceSelectedLineRange(textarea, nextLines.join("\n"), lineStart, lineEnd);
860
+ };
861
+
862
+ // src/entities/editor-core/model/theme-contract.ts
863
+ var CHAEDITOR_THEME_VARIABLES = {
864
+ border: "--chaeditor-color-border",
865
+ borderStrong: "--chaeditor-color-border-strong",
866
+ focusRing: "--chaeditor-color-focus-ring",
867
+ monoFont: "--chaeditor-font-mono",
868
+ muted: "--chaeditor-color-muted",
869
+ overlayBackdrop: "--chaeditor-color-overlay-backdrop",
870
+ primary: "--chaeditor-color-primary",
871
+ primaryContrast: "--chaeditor-color-primary-contrast",
872
+ primaryHover: "--chaeditor-color-primary-hover",
873
+ primaryMuted: "--chaeditor-color-primary-muted",
874
+ primarySubtle: "--chaeditor-color-primary-subtle",
875
+ sansFont: "--chaeditor-font-sans",
876
+ sansJaFont: "--chaeditor-font-sans-ja",
877
+ success: "--chaeditor-color-success",
878
+ surface: "--chaeditor-color-surface",
879
+ surfaceMuted: "--chaeditor-color-surface-muted",
880
+ surfaceStrong: "--chaeditor-color-surface-strong",
881
+ text: "--chaeditor-color-text",
882
+ textSubtle: "--chaeditor-color-text-subtle",
883
+ error: "--chaeditor-color-error"
884
+ };
885
+ var CHAEDITOR_THEME_DEFAULTS = {
886
+ dark: {
887
+ border: "#52525b",
888
+ borderStrong: "#71717a",
889
+ error: "#f87171",
890
+ focusRing: "#1e3a8a",
891
+ muted: "#a1a1aa",
892
+ overlayBackdrop: "rgb(9 9 11 / 0.82)",
893
+ primary: "#93c5fd",
894
+ primaryContrast: "#18181b",
895
+ primaryHover: "#bfdbfe",
896
+ primaryMuted: "#1e40af",
897
+ primarySubtle: "#1e3a8a",
898
+ success: "#4ade80",
899
+ surface: "#18181b",
900
+ surfaceMuted: "#27272a",
901
+ surfaceStrong: "#3f3f46",
902
+ text: "#fafafa",
903
+ textSubtle: "#d4d4d8"
904
+ },
905
+ fonts: {
906
+ mono: "var(--font-d2coding), 'D2Coding', 'SFMono-Regular', 'JetBrains Mono', Consolas, 'Liberation Mono', monospace",
907
+ sans: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif",
908
+ sansJa: "system-ui, -apple-system, BlinkMacSystemFont, 'Hiragino Sans', 'Yu Gothic', 'Meiryo', sans-serif"
909
+ },
910
+ light: {
911
+ border: "#d4d4d8",
912
+ borderStrong: "#a1a1aa",
913
+ error: "#ef4444",
914
+ focusRing: "#dbeafe",
915
+ muted: "#71717a",
916
+ overlayBackdrop: "rgb(15 23 42 / 0.86)",
917
+ primary: "#3b82f6",
918
+ primaryContrast: "#ffffff",
919
+ primaryHover: "#2563eb",
920
+ primaryMuted: "#dbeafe",
921
+ primarySubtle: "#eff6ff",
922
+ success: "#22c55e",
923
+ surface: "#ffffff",
924
+ surfaceMuted: "#f4f4f5",
925
+ surfaceStrong: "#e4e4e7",
926
+ text: "#18181b",
927
+ textSubtle: "#52525b"
928
+ }
929
+ };
930
+ var createChaeditorThemeVars = (theme) => {
931
+ const vars = {};
932
+ if (theme.border) vars[CHAEDITOR_THEME_VARIABLES.border] = theme.border;
933
+ if (theme.borderStrong) vars[CHAEDITOR_THEME_VARIABLES.borderStrong] = theme.borderStrong;
934
+ if (theme.error) vars[CHAEDITOR_THEME_VARIABLES.error] = theme.error;
935
+ if (theme.focusRing) vars[CHAEDITOR_THEME_VARIABLES.focusRing] = theme.focusRing;
936
+ if (theme.monoFont) vars[CHAEDITOR_THEME_VARIABLES.monoFont] = theme.monoFont;
937
+ if (theme.muted) vars[CHAEDITOR_THEME_VARIABLES.muted] = theme.muted;
938
+ if (theme.overlayBackdrop) {
939
+ vars[CHAEDITOR_THEME_VARIABLES.overlayBackdrop] = theme.overlayBackdrop;
940
+ }
941
+ if (theme.primary) vars[CHAEDITOR_THEME_VARIABLES.primary] = theme.primary;
942
+ if (theme.primaryContrast) {
943
+ vars[CHAEDITOR_THEME_VARIABLES.primaryContrast] = theme.primaryContrast;
944
+ }
945
+ if (theme.primaryHover) vars[CHAEDITOR_THEME_VARIABLES.primaryHover] = theme.primaryHover;
946
+ if (theme.primaryMuted) vars[CHAEDITOR_THEME_VARIABLES.primaryMuted] = theme.primaryMuted;
947
+ if (theme.primarySubtle) vars[CHAEDITOR_THEME_VARIABLES.primarySubtle] = theme.primarySubtle;
948
+ if (theme.sansFont) vars[CHAEDITOR_THEME_VARIABLES.sansFont] = theme.sansFont;
949
+ if (theme.sansJaFont) vars[CHAEDITOR_THEME_VARIABLES.sansJaFont] = theme.sansJaFont;
950
+ if (theme.success) vars[CHAEDITOR_THEME_VARIABLES.success] = theme.success;
951
+ if (theme.surface) vars[CHAEDITOR_THEME_VARIABLES.surface] = theme.surface;
952
+ if (theme.surfaceMuted) vars[CHAEDITOR_THEME_VARIABLES.surfaceMuted] = theme.surfaceMuted;
953
+ if (theme.surfaceStrong) vars[CHAEDITOR_THEME_VARIABLES.surfaceStrong] = theme.surfaceStrong;
954
+ if (theme.text) vars[CHAEDITOR_THEME_VARIABLES.text] = theme.text;
955
+ if (theme.textSubtle) vars[CHAEDITOR_THEME_VARIABLES.textSubtle] = theme.textSubtle;
956
+ return vars;
957
+ };
958
+
959
+ // src/entities/editor-core/model/toolbar-preset.ts
960
+ var DEFAULT_MARKDOWN_TOOLBAR_PRESET = [
961
+ {
962
+ itemKeys: ["heading-popover", "subtext"],
963
+ key: "heading-and-subtext"
964
+ },
965
+ {
966
+ itemKeys: ["bold", "italic", "strike", "underline"],
967
+ key: "text-emphasis"
968
+ },
969
+ {
970
+ itemKeys: ["text-color", "background-color", "align"],
971
+ key: "highlight-and-alignment"
972
+ },
973
+ {
974
+ itemKeys: ["horizontal-rule", "quote", "code-block", "table", "spoiler", "toggle-popover"],
975
+ key: "block-syntax"
976
+ },
977
+ {
978
+ itemKeys: ["math-embed", "file-embed", "image-embed", "link-embed", "video-embed"],
979
+ key: "embed-and-media"
980
+ }
981
+ ];
982
+ var resolveMarkdownToolbarPresetSections = ({
983
+ itemRegistry,
984
+ preset = DEFAULT_MARKDOWN_TOOLBAR_PRESET
985
+ }) => preset.map((section) => ({
986
+ items: section.itemKeys.map((itemKey) => itemRegistry[itemKey]).filter((item) => item !== void 0),
987
+ key: section.key
988
+ }));
989
+
990
+ exports.CHAEDITOR_THEME_DEFAULTS = CHAEDITOR_THEME_DEFAULTS;
991
+ exports.CHAEDITOR_THEME_VARIABLES = CHAEDITOR_THEME_VARIABLES;
992
+ exports.DEFAULT_MARKDOWN_TOOLBAR_PRESET = DEFAULT_MARKDOWN_TOOLBAR_PRESET;
993
+ exports.EDITOR_ATTACHMENT_FILE_INPUT_ACCEPT = EDITOR_ATTACHMENT_FILE_INPUT_ACCEPT;
994
+ exports.EDITOR_ATTACHMENT_MAX_FILE_SIZE = EDITOR_ATTACHMENT_MAX_FILE_SIZE;
995
+ exports.EDITOR_VIDEO_FILE_INPUT_ACCEPT = EDITOR_VIDEO_FILE_INPUT_ACCEPT;
996
+ exports.EDITOR_VIDEO_MAX_FILE_SIZE = EDITOR_VIDEO_MAX_FILE_SIZE;
997
+ exports.applyTextareaTransform = applyTextareaTransform;
998
+ exports.buildEditorLinkInsertion = buildEditorLinkInsertion;
999
+ exports.continueMarkdownList = continueMarkdownList;
1000
+ exports.createAlignBlockMarkdown = createAlignBlockMarkdown;
1001
+ exports.createAttachmentEmbedMarkdown = createAttachmentEmbedMarkdown;
1002
+ exports.createChaeditorThemeVars = createChaeditorThemeVars;
1003
+ exports.createImageEmbedMarkdown = createImageEmbedMarkdown;
1004
+ exports.createImageEmbedMarkdownGroup = createImageEmbedMarkdownGroup;
1005
+ exports.createImageGalleryMarkdown = createImageGalleryMarkdown;
1006
+ exports.createMarkdownLink = createMarkdownLink;
1007
+ exports.createMarkdownLinkByMode = createMarkdownLinkByMode;
1008
+ exports.createMathEmbedMarkdown = createMathEmbedMarkdown;
1009
+ exports.createToggleBlockMarkdown = createToggleBlockMarkdown;
1010
+ exports.createUploadedVideoEmbedMarkdown = createUploadedVideoEmbedMarkdown;
1011
+ exports.createVideoEmbedMarkdown = createVideoEmbedMarkdown;
1012
+ exports.createYoutubeEmbedMarkdown = createYoutubeEmbedMarkdown;
1013
+ exports.decodeHtmlAttributeEntities = decodeHtmlAttributeEntities;
1014
+ exports.extractVideoEmbedReference = extractVideoEmbedReference;
1015
+ exports.extractYoutubeId = extractYoutubeId;
1016
+ exports.focusTextarea = focusTextarea;
1017
+ exports.getPendingSelection = getPendingSelection;
1018
+ exports.indentMarkdownList = indentMarkdownList;
1019
+ exports.insertTemplate = insertTemplate;
1020
+ exports.isAllowedEditorAttachmentExtension = isAllowedEditorAttachmentExtension;
1021
+ exports.isAllowedEditorAttachmentFile = isAllowedEditorAttachmentFile;
1022
+ exports.isAllowedEditorVideoExtension = isAllowedEditorVideoExtension;
1023
+ exports.isAllowedEditorVideoFile = isAllowedEditorVideoFile;
1024
+ exports.normalizeMarkdownHtmlAliases = normalizeMarkdownHtmlAliases;
1025
+ exports.outdentMarkdownList = outdentMarkdownList;
1026
+ exports.parseRichMarkdownSegments = parseRichMarkdownSegments;
1027
+ exports.parseToggleTitle = parseToggleTitle;
1028
+ exports.prefixLine = prefixLine;
1029
+ exports.preprocessMarkdownInlineSyntax = preprocessMarkdownInlineSyntax;
1030
+ exports.resolveMarkdownToolbarPresetSections = resolveMarkdownToolbarPresetSections;
1031
+ exports.restoreCursor = restoreCursor;
1032
+ exports.toggleHeadingLine = toggleHeadingLine;
1033
+ exports.transformMarkdownOutsideCode = transformMarkdownOutsideCode;
1034
+ exports.wrapSelection = wrapSelection;