@comitor/ui 3.11.0 → 3.12.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 (88) hide show
  1. package/README.md +10 -5
  2. package/dist/chat/chat-composer.d.ts +36 -0
  3. package/dist/chat/chat-composer.js +85 -0
  4. package/dist/chat/chat-composer.js.map +1 -0
  5. package/dist/chat/chat-constants.d.ts +63 -0
  6. package/dist/chat/chat-constants.js +1 -0
  7. package/dist/chat/chat-constants.js.map +1 -0
  8. package/dist/chat/chat-message.d.ts +51 -0
  9. package/dist/chat/chat-message.js +137 -0
  10. package/dist/chat/chat-message.js.map +1 -0
  11. package/dist/chat/chat-sources.d.ts +25 -0
  12. package/dist/chat/chat-sources.js +97 -0
  13. package/dist/chat/chat-sources.js.map +1 -0
  14. package/dist/chat/chat-steps.d.ts +20 -0
  15. package/dist/chat/chat-steps.js +84 -0
  16. package/dist/chat/chat-steps.js.map +1 -0
  17. package/dist/chat/chat-thread.d.ts +21 -0
  18. package/dist/chat/chat-thread.js +87 -0
  19. package/dist/chat/chat-thread.js.map +1 -0
  20. package/dist/chat/index.d.ts +12 -0
  21. package/dist/chat/index.js +14 -0
  22. package/dist/chat/index.js.map +1 -0
  23. package/dist/components/composite/gantt-constants.d.ts +127 -0
  24. package/dist/components/composite/gantt-constants.js +5 -0
  25. package/dist/components/composite/gantt-constants.js.map +1 -0
  26. package/dist/components/composite/gantt-utils.d.ts +106 -0
  27. package/dist/components/composite/gantt-utils.js +196 -0
  28. package/dist/components/composite/gantt-utils.js.map +1 -0
  29. package/dist/components/composite/gantt.d.ts +93 -0
  30. package/dist/components/composite/gantt.js +1137 -0
  31. package/dist/components/composite/gantt.js.map +1 -0
  32. package/dist/components/composite/stat-card.d.ts +1 -1
  33. package/dist/components/composite/tree-view-constants.d.ts +96 -0
  34. package/dist/components/composite/tree-view-constants.js +85 -0
  35. package/dist/components/composite/tree-view-constants.js.map +1 -0
  36. package/dist/components/composite/tree-view.d.ts +58 -0
  37. package/dist/components/composite/tree-view.js +385 -0
  38. package/dist/components/composite/tree-view.js.map +1 -0
  39. package/dist/components/ui/badge.d.ts +1 -1
  40. package/dist/components/ui/button.d.ts +1 -1
  41. package/dist/data-grid/data-grid-cell-wrapper.d.ts +1 -1
  42. package/dist/data-grid/data-grid-cell-wrapper.js +11 -5
  43. package/dist/data-grid/data-grid-cell-wrapper.js.map +1 -1
  44. package/dist/data-grid/data-grid-column-header.js +12 -12
  45. package/dist/data-grid/data-grid-column-header.js.map +1 -1
  46. package/dist/data-grid/messages-en.d.ts +2 -0
  47. package/dist/data-grid/messages-en.js +3 -1
  48. package/dist/data-grid/messages-en.js.map +1 -1
  49. package/dist/data-grid/messages-vi.js +2 -1
  50. package/dist/data-grid/messages-vi.js.map +1 -1
  51. package/dist/data-grid/messages.d.ts +2 -0
  52. package/dist/data-grid/use-data-grid.d.ts +1 -0
  53. package/dist/data-grid/utils.d.ts +13 -1
  54. package/dist/data-grid/utils.js +13 -0
  55. package/dist/data-grid/utils.js.map +1 -1
  56. package/dist/editor/bubble-toolbar.d.ts +1 -1
  57. package/dist/editor/editor-core.d.ts +2 -2
  58. package/dist/editor/editor-core.js +6 -0
  59. package/dist/editor/editor-core.js.map +1 -1
  60. package/dist/editor/editor-types.d.ts +1 -1
  61. package/dist/editor/fixed-toolbar.d.ts +1 -1
  62. package/dist/editor/image-upload.d.ts +1 -1
  63. package/dist/editor/index.d.ts +1 -1
  64. package/dist/editor/markdown-editor.d.ts +1 -1
  65. package/dist/editor/markdown-extensions.d.ts +3 -1
  66. package/dist/editor/markdown-extensions.js +3 -1
  67. package/dist/editor/markdown-extensions.js.map +1 -1
  68. package/dist/editor/rich-text-editor.d.ts +1 -1
  69. package/dist/editor/slash-commands.d.ts +1 -1
  70. package/dist/editor/toolbar-actions.d.ts +1 -1
  71. package/dist/{editor-types-CSrMeuSw.d.ts → editor-types-BacXD2VN.d.ts} +7 -1
  72. package/dist/i18n/locale-provider.d.ts +3 -0
  73. package/dist/i18n/messages.d.ts +6 -0
  74. package/dist/i18n/messages.js +11 -2
  75. package/dist/i18n/messages.js.map +1 -1
  76. package/dist/i18n/namespaces/chat.d.ts +8 -0
  77. package/dist/i18n/namespaces/chat.js +47 -0
  78. package/dist/i18n/namespaces/chat.js.map +1 -0
  79. package/dist/i18n/namespaces/gantt.d.ts +10 -0
  80. package/dist/i18n/namespaces/gantt.js +57 -0
  81. package/dist/i18n/namespaces/gantt.js.map +1 -0
  82. package/dist/i18n/namespaces/tree-view.d.ts +8 -0
  83. package/dist/i18n/namespaces/tree-view.js +21 -0
  84. package/dist/i18n/namespaces/tree-view.js.map +1 -0
  85. package/dist/index.d.ts +5 -0
  86. package/dist/index.js +4 -0
  87. package/dist/index.js.map +1 -1
  88. package/package.json +9 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/editor/markdown-extensions.ts"],"sourcesContent":["/**\n * LƯỢC ĐỒ của hai trình soạn — danh sách extension Tiptap, không React, không DOM.\n *\n * Mọi thứ quyết định \"tài liệu này lưu xuống thành chuỗi nào, và đọc lên lại thành tài liệu nào\"\n * nằm ở đây, và CHỈ ở đây: trình soạn dùng nó, cổng `test:editor-markdown` dựng `MarkdownManager`\n * từ chính hàm này trên `dist/` rồi đo vòng tài liệu → markdown → tài liệu. Hai nơi mà dùng hai danh\n * sách là hai lược đồ, và cổng xanh trên một lược đồ không ai dùng.\n *\n * Hai định dạng LƯU, hai lược đồ khác nhau ở đúng những chỗ định dạng ấy biểu diễn được hay không\n * (`createSchemaExtensions`): markdown (`MarkdownEditor`) hẹp hơn — không gạch chân, ô bảng một đoạn —\n * vì thứ gì không ghi được thành markdown thì sẽ mất ở lần lưu; HTML (`RichTextEditor`) giữ được cả hai.\n *\n * Phần GIAO DIỆN (menu `/`, menu `@`, tải ảnh, phím tắt) gắn vào qua tham số — xem\n * `MarkdownSchemaOptions`. Gọi không tham số là ra đúng lược đồ, đủ để đọc/ghi.\n */\n\nimport { type AnyExtension, Extension, InputRule, type JSONContent, mergeAttributes } from \"@tiptap/core\";\nimport { CodeBlockLowlight } from \"@tiptap/extension-code-block-lowlight\";\nimport { Image } from \"@tiptap/extension-image\";\nimport { TaskItem, TaskList } from \"@tiptap/extension-list\";\nimport { Mention, type MentionOptions } from \"@tiptap/extension-mention\";\nimport { Paragraph } from \"@tiptap/extension-paragraph\";\nimport { renderTableToMarkdown, Table, TableCell, TableHeader, TableKit } from \"@tiptap/extension-table\";\nimport { Placeholder } from \"@tiptap/extensions\";\nimport { Markdown } from \"@tiptap/markdown\";\nimport { Fragment, type Node as ProseMirrorNode, type ResolvedPos, Slice } from \"@tiptap/pm/model\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { StarterKit } from \"@tiptap/starter-kit\";\nimport { common, createLowlight } from \"lowlight\";\nimport { Marked, type marked } from \"marked\";\nimport type { EditorFormat } from \"./editor-types.js\";\nimport {\n codeFence,\n escapeParagraphMarkdown,\n imageMarkdown,\n parseMentionMarkdown,\n renderMentionMarkdown\n} from \"./markdown-syntax.js\";\n\n/**\n * Giá trị đổi được SAU KHI trình soạn đã dựng. Extension đọc chúng lúc CẦN (lúc vẽ chữ mờ, lúc vẽ một\n * lần nhắc tên…), không chép lúc dựng — vì đổi danh sách extension là dựng lại cả trình soạn: mất\n * lịch sử hoàn tác, mất con trỏ. Component giữ object này trong một ref và ghi đè từng lượt render.\n */\nexport interface MarkdownEditorRuntime {\n placeholder: string;\n taskCheckbox: (text: string) => string;\n /** Đổi `src` ĐÃ LƯU thành địa chỉ HIỂN THỊ được (vd URL đã ký). Markdown vẫn giữ `src` gốc. */\n resolveImageSrc?: (src: string) => string;\n /**\n * Tên SỐNG theo id (và loại — `undefined` là người). `undefined` thì rơi về tên chụp lúc nhắc.\n */\n resolveMentionLabel?: (id: string, kind?: string) => string | undefined;\n /** Địa chỉ mở khi bấm một lần nhắc (vd `/tasks/<id>`). `undefined` = không phải liên kết. */\n resolveMentionHref?: (id: string, kind?: string) => string | undefined;\n}\n\nconst DEFAULT_RUNTIME: MarkdownEditorRuntime = {\n placeholder: \"\",\n taskCheckbox: (text) => text\n};\n\nexport interface MarkdownSchemaOptions {\n /** Định dạng LƯU — quyết định lược đồ. Mặc định `markdown`. */\n format?: EditorFormat;\n /** Đọc lười — xem `MarkdownEditorRuntime`. Bỏ trống ở nơi chỉ cần đọc/ghi (cổng, máy chủ). */\n runtime?: { readonly current: MarkdownEditorRuntime };\n /**\n * Cấu hình gợi ý `@` của `Mention` (danh sách, cách vẽ, `allow`). Bỏ trống = node `mention` vẫn có\n * trong lược đồ — để tài liệu CÓ nhắc tên vẫn đọc ra đúng ở chế độ chỉ đọc — nhưng gõ `@` không\n * mở gì.\n */\n mentionSuggestion?: Partial<MentionOptions[\"suggestion\"]>;\n}\n\n/*\n * Ngôn ngữ tô màu: bộ `common` của highlight.js (37 ngôn ngữ, ~53KB gzip — đo bằng esbuild trên\n * lowlight 3.3.0). Dựng MỘT lần cho cả module: bảng ngôn ngữ chỉ đọc, chia được giữa các trình soạn.\n */\nconst lowlight = createLowlight(common);\n\n/**\n * Đoạn văn — thêm phép thoát cú pháp khối (ca 1 ở đầu `markdown-syntax.ts`). Mọi hành vi khác giữ\n * nguyên bản gốc, kể cả `&nbsp;` cho đoạn rỗng: đó là cách CỐ Ý của Tiptap để giữ dòng trống người\n * dùng gõ — bỏ nó đi là nội dung \"co\" lại sau mỗi lần lưu.\n */\nconst ComitorParagraph = Paragraph.extend({\n renderMarkdown(node, helpers, context) {\n return escapeParagraphMarkdown(this.parent?.(node, helpers, context) ?? \"\");\n }\n});\n\n/** Khối mã — hàng rào dài hơn mọi dãy backtick bên trong (ca 2 ở đầu `markdown-syntax.ts`). */\nconst ComitorCodeBlock = CodeBlockLowlight.extend({\n renderMarkdown(node: JSONContent) {\n const language = typeof node.attrs?.language === \"string\" ? node.attrs.language : \"\";\n const text = (node.content ?? []).map((child) => child.text ?? \"\").join(\"\");\n const fence = codeFence(text);\n return `${fence}${language}\\n${text}\\n${fence}`;\n }\n});\n\n/** Bảng — bỏ dòng trống bản gốc kẹp hai đầu (xem `trimMarkdown`). */\nconst ComitorTable = Table.extend({\n renderMarkdown(node, helpers) {\n return renderTableToMarkdown(node, helpers).replace(/^\\n+|\\n+$/g, \"\");\n }\n});\n\n/*\n * Ô bảng chứa ĐÚNG MỘT đoạn văn — bản gốc cho `block+` (danh sách, khối mã, nhiều đoạn trong một ô).\n *\n * Ô bảng GFM là một dòng chữ, không chứa khối được. Đã đo trên 3.31.4: ô có hai đoạn ghi thành\n * `dòng 1<br>dòng 2`, ô có danh sách thành `- a<br>- b`, khối mã thành ```` ```<br>code<br>``` ````;\n * mở lại thì `<br>` là CHỮ THƯỜNG, và lần lưu kế tiếp nó thành `&lt;br&gt;` — mỗi lần lưu hỏng thêm\n * một lớp. Thu hẹp lược đồ là cách duy nhất chặn từ gốc: luật nhập (`- `, `# `, ```` ``` ````) và\n * lệnh khối tự thất bại trong ô vì lược đồ không cho, không cần chặn từng chỗ. Xuống dòng cứng trong ô\n * thì `createEditorKeymap` nuốt — `hardBreak` là node NỘI DÒNG nên lược đồ không chặn được nó.\n */\nconst ComitorTableCell = TableCell.extend({ content: \"paragraph\" });\nconst ComitorTableHeader = TableHeader.extend({ content: \"paragraph\" });\n\n/** Mẫu luật nhập của `HorizontalRule` trong StarterKit (3.31.4) — xem `MarkdownTableCellGuard`. */\nconst HORIZONTAL_RULE_INPUT = /^(?:---|—-|___\\s|\\*\\*\\*\\s)$/;\n\n/**\n * Ô bảng MARKDOWN — chặn nốt những đường CHÈN KHỐI mà lược đồ không chặn được.\n *\n * `ComitorTableCell` làm luật nhập BỌC (`- `, `# `, `> `) và lệnh đổi khối tự thất bại trong ô. Nhưng\n * phép THAY của ProseMirror không thất bại: khối không vừa chỗ thì nó TÁCH các node cha cho tới khi\n * vừa — tức tách CẢ BẢNG. Đã đo trên 3.31.4 (harness của `3.6.0`; cả ba có từ `3.5.0`):\n * · gõ `---` trong ô → bảng gãy làm hai, một đường kẻ ở giữa (luật nhập của `HorizontalRule`);\n * · dán một danh sách vào ô → bảng gãy làm hai, danh sách ở giữa;\n * · dán hai dòng chữ vào ô → hai dòng GHI ĐÈ lên ô đang đứng và ô kế bên — chữ cũ của cả hai mất.\n * Ba lớp, từ cụ thể tới chung:\n * 1. dán/thả từ ngoài: mọi khối của đoạn dán gộp thành MỘT dòng (`flattenSliceToLine`) — ô GFM là\n * một dòng chữ;\n * 2. `---` gõ trong ô ở lại là CHỮ — \"---\" là cách người ta hay ghi \"không có\" trong một ô bảng;\n * 3. lưới cuối: giao dịch nào làm SỐ BẢNG tăng khi con trỏ đang ở trong ô thì bị bỏ. Nó bắt mọi\n * đường còn lại (luật nhập ảnh `![a](b)`, kéo thả một khối trong tài liệu, `insertContent` của app),\n * với cái giá là phím hay cú thả vừa rồi không có tác dụng — mất một phím còn hơn gãy một bảng.\n * Hoàn tác/làm lại và thay CẢ tài liệu (`setContent`, `value` đổi từ ngoài) đi thẳng.\n *\n * Ô bảng của `RichTextEditor` chứa được khối nên không cần lớp nào trong ba.\n */\nconst MarkdownTableCellGuard = Extension.create({\n name: \"comitorMarkdownTableCellGuard\",\n // Cao hơn StarterKit (100): mỗi extension một plugin luật nhập, xếp theo `priority` — luật dưới đây\n // phải được hỏi TRƯỚC luật đường kẻ, không thì đường kẻ đã chèn xong.\n priority: 1000,\n addInputRules() {\n return [\n new InputRule({\n find: HORIZONTAL_RULE_INPUT,\n undoable: false,\n handler: ({ state, range, match }) => {\n if (!isInTableCell(state.doc.resolve(range.from))) return null;\n state.tr.insertText(match[0], range.from, range.to);\n }\n })\n ];\n },\n addProseMirrorPlugins() {\n /*\n * Đoạn dán có thật là BẢNG không — phải hỏi ở chuỗi GỐC. `normalizeSiblings` của ProseMirror bọc\n * sẵn các đoạn văn dán vào ô thành Ô BẢNG (để chúng \"vừa\" chỗ) trước khi `transformPasted` thấy\n * chúng, nên nhìn slice thì \"dán hai dòng chữ\" và \"dán hai ô\" là một — và `prosemirror-tables` dán\n * cả hai theo kiểu ô, đè lên ô kế bên. Đã đo: đó chính là ca \"hai dòng ghi đè hai ô\" ở trên.\n */\n let pastedTable = false;\n return [\n new Plugin({\n props: {\n transformPastedHTML: (html) => {\n pastedTable = /<(?:table|tr|td|th)[\\s>/]/i.test(html);\n return html;\n },\n transformPastedText: (text) => {\n pastedTable = false;\n return text;\n },\n transformPasted: (slice, view) => {\n const keepTables = pastedTable;\n pastedTable = false;\n return isInTableCell(view.state.selection.$from) ? flattenSliceToLine(slice, keepTables) : slice;\n }\n },\n filterTransaction: (tr, state) => {\n if (!tr.docChanged || tr.getMeta(\"history$\") || !isInTableCell(state.selection.$from)) return true;\n if (replacesWholeDocument(tr.steps, state.doc.content.size)) return true;\n return countTables(tr.doc) <= countTables(state.doc);\n }\n })\n ];\n }\n});\n\n/**\n * Gộp một đoạn dán thành MỘT dòng nội dòng: các khối chữ nối nhau bằng một dấu cách, xuống dòng (cả\n * `hardBreak` lẫn `\\n` trong khối mã) thành dấu cách, khối không phải chữ (ảnh, đường kẻ) bỏ đi.\n * Nội dung nội dòng sẵn thì để nguyên; `keepTables` (đoạn dán GỐC có bảng) thì đoạn dán mang ô bảng\n * cũng để nguyên — dán theo ô là việc của `prosemirror-tables`.\n * Xuất ra cho cổng `test:editor-markdown`; không nằm trong entry.\n */\nexport function flattenSliceToLine(slice: Slice, keepTables = false): Slice {\n const first = slice.content.firstChild;\n if (!first || first.isInline) return slice;\n if (keepTables) {\n let tabular = false;\n slice.content.descendants((node) => {\n if (node.type.spec.tableRole) tabular = true;\n return !tabular;\n });\n if (tabular) return slice;\n }\n\n const schema = first.type.schema;\n const line: ProseMirrorNode[] = [];\n slice.content.descendants((node) => {\n if (!node.isTextblock) return true;\n if (node.content.size === 0) return false;\n if (line.length > 0) line.push(schema.text(\" \"));\n node.content.forEach((child) => {\n if (child.type.name === \"hardBreak\") line.push(schema.text(\" \"));\n else if (child.isText && child.text?.includes(\"\\n\"))\n line.push(schema.text(child.text.replace(/\\s*\\n\\s*/g, \" \"), child.marks));\n else line.push(child);\n });\n return false;\n });\n return new Slice(Fragment.from(line), 0, 0);\n}\n\nfunction countTables(doc: ProseMirrorNode): number {\n let count = 0;\n doc.descendants((node) => {\n if (node.type.name === \"table\") count++;\n return node.type.name !== \"table\";\n });\n return count;\n}\n\n/** Có bước nào thay TOÀN BỘ tài liệu không — `setContent` làm đúng một bước như vậy. */\nfunction replacesWholeDocument(steps: readonly unknown[], size: number): boolean {\n return steps.some((step) => {\n const { from, to } = step as { from?: unknown; to?: unknown };\n return from === 0 && to === size;\n });\n}\n\n/**\n * Bảng chữ markdown RIÊNG cho từng trình soạn.\n *\n * ⚠ Không truyền thì `@tiptap/markdown` dùng `marked` TOÀN CỤC, và mỗi lần trình soạn mount nó gọi\n * `marked.use()` đăng ký lại bộ tách từ (bảng, nhắc tên…) — không bao giờ gỡ. Đã đo trên 3.31.4:\n * mỗi `MarkdownManager` thêm 4 bộ tách; sau 200 lần dựng, parse cùng một tài liệu 200 đoạn chậm từ\n * 18,6ms lên 282ms, và còn tăng tiếp. Trong một SPA, 200 lần là một buổi làm việc mở việc này sang\n * việc khác. Một bản `Marked` mỗi trình soạn: 4 bộ tách, 5,7ms, mất cùng trình soạn.\n *\n * Ép kiểu vì option khai `typeof marked` (hàm `marked` toàn cục, gọi được) mà thứ đúng là một bản\n * `Marked`: `MarkdownManager` chỉ dùng `.use`, `.Lexer`, `.defaults`, `.lexer`, `.setOptions` — bản\n * `Marked` có đủ cả năm, chỉ thiếu chữ ký gọi-như-hàm mà không chỗ nào gọi tới.\n */\nfunction createMarkedInstance(): typeof marked {\n return new Marked() as unknown as typeof marked;\n}\n\n/**\n * Danh sách extension tạo nên lược đồ của trình soạn, theo định dạng LƯU.\n *\n * Markdown (`format: \"markdown\"`, mặc định) hẹp hơn HTML ở hai chỗ, cả hai vì cùng một lý do — thứ gì\n * không ghi được thành markdown thì MẤT ở lần lưu, mà người dùng không được báo:\n * · `underline` tắt: markdown không có cú pháp gạch chân. `@tiptap/markdown` ghi nó thành\n * `++chữ++` — cú pháp riêng, nên email thông báo, tác tử đọc qua MCP và mọi trình xem markdown\n * khác in nguyên hai dấu cộng;\n * · ô bảng chỉ chứa MỘT đoạn văn (`ComitorTableCell`).\n * Hai bản vá markdown (`ComitorParagraph`, `Markdown` với `Marked` riêng) cũng chỉ nạp ở định dạng đó.\n *\n * HTML (`format: \"html\"`) giữ cả gạch chân lẫn ô bảng nhiều khối — `<u>`, `<td><ul>…</ul></td>` là HTML\n * hợp lệ và đọc lên lại đúng.\n */\nexport function createSchemaExtensions(options: MarkdownSchemaOptions = {}): AnyExtension[] {\n const runtime = options.runtime ?? { current: DEFAULT_RUNTIME };\n const markdown = (options.format ?? \"markdown\") === \"markdown\";\n\n return [\n StarterKit.configure({\n paragraph: false,\n codeBlock: false,\n ...(markdown ? { underline: false as const } : {}),\n link: {\n // Đang sửa thì bấm vào liên kết là đặt con trỏ, không phải mở tab mới (thanh định dạng có nút\n // Mở). Chỉ đọc thì Tiptap không chặn cú bấm — thẻ `<a target=\"_blank\">` tự mở như thường.\n openOnClick: false,\n autolink: true,\n linkOnPaste: true,\n // Gõ/dán `[chữ](https://…)` là thành liên kết — người quen markdown gõ vậy theo phản xạ.\n markdownLinks: true,\n defaultProtocol: \"https\",\n HTMLAttributes: { target: \"_blank\", rel: \"noopener noreferrer nofollow\" }\n }\n }),\n markdown ? ComitorParagraph : Paragraph,\n ComitorCodeBlock.configure({\n lowlight,\n defaultLanguage: null,\n // Tab trong khối mã là thụt lề — đúng điều người viết mã chờ đợi. Thoát khối: ↓ ở dòng cuối,\n // hoặc Enter ba lần (mặc định của Tiptap).\n enableTabIndentation: true,\n tabSize: 2\n }),\n TaskList,\n TaskItem.configure({\n nested: true,\n // Chữ của ĐOẠN ĐẦU, không phải `node.textContent`: mục cha có danh sách con thì `textContent` dính\n // liền chữ của mọi mục con (\"Gửi mã qua emailGiới hạn 5 lần/giờ\") — đã gặp.\n a11y: { checkboxLabel: (node) => runtime.current.taskCheckbox(node.firstChild?.textContent ?? \"\") }\n }),\n ...(markdown\n ? [\n TableKit.configure({ table: false, tableCell: false, tableHeader: false }),\n ComitorTable.configure({ resizable: false }),\n ComitorTableCell,\n ComitorTableHeader,\n MarkdownTableCellGuard\n ]\n : [TableKit.configure({ table: { resizable: false } })]),\n createImageExtension(runtime),\n createMentionExtension(runtime, options.mentionSuggestion),\n Placeholder.configure({ placeholder: () => runtime.current.placeholder }),\n ...(markdown\n ? [Markdown.configure({ marked: createMarkedInstance(), indentation: { style: \"space\", size: 2 } })]\n : [])\n ];\n}\n\n/** Lược đồ của `MarkdownEditor` — tên có từ `3.5.0`, cổng `test:editor-markdown` gọi thẳng nó. */\nexport function createMarkdownSchemaExtensions(options: Omit<MarkdownSchemaOptions, \"format\"> = {}): AnyExtension[] {\n return createSchemaExtensions({ ...options, format: \"markdown\" });\n}\n\n/**\n * Ảnh — tách địa chỉ LƯU khỏi địa chỉ HIỂN THỊ, và thoát cú pháp khi ghi markdown.\n *\n * Kho ảnh của module Comitor là bucket RIÊNG TƯ: thứ hiện được là URL đã ký, có hạn. Lưu URL đó vào\n * nội dung là lưu một giá trị sẽ chết ngay trong database — nên nội dung giữ `src` app trả về (khoá,\n * hoặc một route ổn định của app), còn `resolveImageSrc` đổi nó thành địa chỉ vẽ được lúc vẽ.\n *\n * ⚠ Đổi địa chỉ ở NODE VIEW, không ở `renderHTML`. `renderHTML` vừa vẽ ảnh trong trình soạn vừa là\n * thứ `editor.getHTML()` dùng để GHI — đổi `src` ở đó (cách của `3.5.0`, khi giá trị còn là markdown)\n * là `RichTextEditor` ghi URL đã ký vào HTML lưu xuống. Node view chỉ là DOM của màn hình; HTML lưu\n * vẫn đi `renderHTML` gốc với `src` gốc.\n *\n * Ảnh ĐANG tải lên không phải node — xem đầu `image-upload.ts`.\n */\nfunction createImageExtension(runtime: { readonly current: MarkdownEditorRuntime }) {\n return Image.extend({\n addNodeView() {\n return ({ node, HTMLAttributes }) => {\n const image = document.createElement(\"img\");\n setAttributes(image, mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), [\"src\"]);\n const src = typeof node.attrs.src === \"string\" ? node.attrs.src : \"\";\n // `src=\"\"` thì trình duyệt tải lại CHÍNH trang làm ảnh — thiếu địa chỉ thì bỏ hẳn thuộc tính.\n if (src) image.setAttribute(\"src\", runtime.current.resolveImageSrc?.(src) ?? src);\n return { dom: image, update: (updated) => sameNode(updated, node) };\n };\n },\n renderMarkdown(node: JSONContent) {\n return imageMarkdown(String(node.attrs?.src ?? \"\"), node.attrs?.alt, node.attrs?.title);\n }\n }).configure({ allowBase64: false });\n}\n\n/**\n * Nhắc tên — định dạng lưu `[@Tên](mention:<id>)` (lý do ở `markdown-syntax.ts`) và tên SỐNG lúc vẽ.\n *\n * Tên sống chỉ đi vào thứ NGƯỜI XEM thấy: node view và `renderText` (chữ khi chép ra ngoài).\n * `renderHTML` — thứ `getHTML()` ghi xuống — giữ TÊN CHỤP lúc nhắc, cùng luật với markdown: nội dung\n * lưu không tự đổi theo danh bạ chỉ vì có người mở và lưu lại.\n */\nfunction createMentionExtension(\n runtime: { readonly current: MarkdownEditorRuntime },\n suggestion: MarkdownSchemaOptions[\"mentionSuggestion\"]\n) {\n const storedLabelOf = (attrs: Record<string, unknown>) => {\n const stored = typeof attrs.label === \"string\" ? attrs.label : \"\";\n return stored || (typeof attrs.id === \"string\" ? attrs.id : \"\");\n };\n const kindOf = (attrs: Record<string, unknown>) =>\n typeof attrs.kind === \"string\" && attrs.kind ? attrs.kind : undefined;\n const labelOf = (attrs: Record<string, unknown>) =>\n runtime.current.resolveMentionLabel?.(typeof attrs.id === \"string\" ? attrs.id : \"\", kindOf(attrs)) ??\n storedLabelOf(attrs);\n\n return Mention.extend({\n /*\n * `kind` (từ 3.7.0): loại thực thể — `null` là người. Ra HTML thành `data-kind` (lưu được ở định dạng\n * HTML và để app tô khác theo loại), ra markdown thành tiền tố `kind/` của địa chỉ.\n */\n addAttributes() {\n return {\n ...this.parent?.(),\n kind: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute(\"data-kind\") || null,\n renderHTML: (attributes: Record<string, unknown>) =>\n typeof attributes.kind === \"string\" && attributes.kind ? { \"data-kind\": attributes.kind } : {}\n }\n };\n },\n markdownTokenName: \"mention\",\n markdownTokenizer: {\n name: \"mention\",\n level: \"inline\",\n start: (source: string) => source.indexOf(\"[@\"),\n tokenize: (source: string) => {\n const parsed = parseMentionMarkdown(source);\n return parsed\n ? { type: \"mention\", raw: parsed.raw, id: parsed.id, label: parsed.label, kind: parsed.kind ?? null }\n : undefined;\n }\n },\n parseMarkdown: (token, helpers) =>\n helpers.createNode(\"mention\", { id: token.id, label: token.label, kind: token.kind ?? null }),\n renderMarkdown: (node: JSONContent) =>\n renderMentionMarkdown(\n String(node.attrs?.id ?? \"\"),\n node.attrs?.label as string | null | undefined,\n node.attrs?.kind as string | null | undefined\n ),\n addNodeView() {\n return ({ node, HTMLAttributes }) => {\n /*\n * Có địa chỉ (`mentions.getHref`) thì vẽ `<a>`: nhắc VIỆC mở được việc đó. Chỉ nhận đường dẫn tương đối\n * cùng gốc hoặc `http(s):` — địa chỉ do app dựng, nhưng một `javascript:` lọt vào đây là chạy được.\n * Chỉ ở node VIEW: thứ GHI xuống (`renderHTML`, markdown) không mang địa chỉ nào.\n */\n const id = typeof node.attrs.id === \"string\" ? node.attrs.id : \"\";\n const href = runtime.current.resolveMentionHref?.(id, kindOf(node.attrs));\n const safeHref = href && /^(?:\\/(?![/\\\\])|https?:\\/\\/)/i.test(href) ? href : undefined;\n const dom = document.createElement(safeHref ? \"a\" : \"span\");\n setAttributes(dom, mergeAttributes({ \"data-type\": this.name }, this.options.HTMLAttributes, HTMLAttributes));\n if (safeHref) dom.setAttribute(\"href\", safeHref);\n dom.textContent = `@${labelOf(node.attrs)}`;\n return { dom, update: (updated) => sameNode(updated, node) };\n };\n }\n }).configure({\n renderText: ({ node }) => `@${labelOf(node.attrs)}`,\n // `options.HTMLAttributes` ở đây là bản Tiptap đã trộn sẵn (`data-type`, `data-id`, `data-label`).\n renderHTML: ({ options, node }) => [\"span\", options.HTMLAttributes, `@${storedLabelOf(node.attrs)}`],\n suggestion: { char: \"@\", allow: () => false, ...suggestion }\n });\n}\n\n/** Phím tắt riêng của trình soạn — xem `createEditorKeymap`. */\nexport interface EditorKeymapHandlers {\n /** ⌘/Ctrl+K — mở ô liên kết. Trả `true` khi đã xử lý. */\n onLinkShortcut: () => boolean;\n /** ⌘/Ctrl+Enter ngoài danh sách việc. Trả `false` để phím đi tiếp (xuống dòng cứng của Tiptap). */\n onSubmitShortcut: () => boolean;\n}\n\n/**\n * Phím tắt của RIÊNG gói, ưu tiên cao hơn mặc định của Tiptap.\n *\n * ⌘/Ctrl+Enter: trong danh sách việc thì tick/bỏ tick mục đang đứng (như Linear); ngoài đó thì gửi\n * (`onSubmit`) — đúng phím mà ô bình luận nào cũng dùng. Không có `onSubmit` thì trả phím về cho\n * Tiptap (bản gốc gán nó cho xuống dòng cứng).\n *\n * ⌘/Ctrl+K: ô liên kết. Không đụng bảng lệnh của shell — listener của shell tự bỏ qua phím khi\n * đích là vùng `contenteditable` (`shell-context.tsx`, nhánh `isTyping`).\n */\nexport function createEditorKeymap(\n handlers: { readonly current: EditorKeymapHandlers },\n format: EditorFormat = \"markdown\"\n): Extension {\n // Chỉ ô bảng MARKDOWN cấm xuống dòng cứng (`ComitorTableCell`); ô bảng HTML chứa được cả khối.\n const swallowInCell = (editor: { state: { selection: { $from: ResolvedPos } } }) =>\n format === \"markdown\" && isInTableCell(editor.state.selection.$from);\n return Extension.create({\n name: \"comitorEditorKeymap\",\n priority: 1000,\n addKeyboardShortcuts() {\n return {\n \"Mod-k\": () => handlers.current.onLinkShortcut(),\n \"Mod-Enter\": ({ editor }) => {\n const toggled = editor.commands.command(({ tr, state }) => {\n const { $from } = state.selection;\n for (let depth = $from.depth; depth > 0; depth--) {\n const node = $from.node(depth);\n if (node.type.name !== \"taskItem\") continue;\n tr.setNodeMarkup($from.before(depth), undefined, { ...node.attrs, checked: !node.attrs.checked });\n return true;\n }\n return false;\n });\n if (toggled || handlers.current.onSubmitShortcut()) return true;\n // Phím đi tiếp tới Tiptap là xuống dòng cứng — trong ô bảng markdown thì nuốt (xem `ComitorTableCell`).\n return swallowInCell(editor);\n },\n \"Shift-Enter\": ({ editor }) => swallowInCell(editor)\n };\n }\n });\n}\n\n/** Con trỏ có đang đứng trong một ô bảng (thường hay tiêu đề) không. */\nfunction isInTableCell($pos: ResolvedPos): boolean {\n for (let depth = $pos.depth; depth > 0; depth--) {\n const name = $pos.node(depth).type.name;\n if (name === \"tableCell\" || name === \"tableHeader\") return true;\n }\n return false;\n}\n\n/** Ghi thuộc tính lên phần tử của node view — bỏ giá trị rỗng, như `DOMSerializer` làm với `renderHTML`. */\nfunction setAttributes(element: HTMLElement, attributes: Record<string, unknown>, skip: readonly string[] = []): void {\n for (const [key, value] of Object.entries(attributes)) {\n if (skip.includes(key) || value === null || value === undefined || value === false) continue;\n element.setAttribute(key, String(value));\n }\n}\n\n/**\n * Node view của nút LÁ (ảnh, nhắc tên): thuộc tính không đổi thì giữ DOM; đổi thì trả `false` để\n * ProseMirror dựng lại — rẻ, và không có trạng thái nào trong DOM đáng giữ.\n */\nfunction sameNode(updated: ProseMirrorNode, current: ProseMirrorNode): boolean {\n if (updated.type !== current.type) return false;\n return Object.keys(current.attrs).every((key) => updated.attrs[key] === current.attrs[key]);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/editor/markdown-extensions.ts"],"sourcesContent":["/**\n * LƯỢC ĐỒ của hai trình soạn — danh sách extension Tiptap, không React, không DOM.\n *\n * Mọi thứ quyết định \"tài liệu này lưu xuống thành chuỗi nào, và đọc lên lại thành tài liệu nào\"\n * nằm ở đây, và CHỈ ở đây: trình soạn dùng nó, cổng `test:editor-markdown` dựng `MarkdownManager`\n * từ chính hàm này trên `dist/` rồi đo vòng tài liệu → markdown → tài liệu. Hai nơi mà dùng hai danh\n * sách là hai lược đồ, và cổng xanh trên một lược đồ không ai dùng.\n *\n * Hai định dạng LƯU, hai lược đồ khác nhau ở đúng những chỗ định dạng ấy biểu diễn được hay không\n * (`createSchemaExtensions`): markdown (`MarkdownEditor`) hẹp hơn — không gạch chân, ô bảng một đoạn —\n * vì thứ gì không ghi được thành markdown thì sẽ mất ở lần lưu; HTML (`RichTextEditor`) giữ được cả hai.\n *\n * Phần GIAO DIỆN (menu `/`, menu `@`, tải ảnh, phím tắt) gắn vào qua tham số — xem\n * `MarkdownSchemaOptions`. Gọi không tham số là ra đúng lược đồ, đủ để đọc/ghi.\n */\n\nimport { type AnyExtension, Extension, InputRule, type JSONContent, mergeAttributes } from \"@tiptap/core\";\nimport { CodeBlockLowlight } from \"@tiptap/extension-code-block-lowlight\";\nimport { Image } from \"@tiptap/extension-image\";\nimport { TaskItem, TaskList } from \"@tiptap/extension-list\";\nimport { Mention, type MentionOptions } from \"@tiptap/extension-mention\";\nimport { Paragraph } from \"@tiptap/extension-paragraph\";\nimport { renderTableToMarkdown, Table, TableCell, TableHeader, TableKit } from \"@tiptap/extension-table\";\nimport { Placeholder } from \"@tiptap/extensions\";\nimport { Markdown } from \"@tiptap/markdown\";\nimport { Fragment, type Node as ProseMirrorNode, type ResolvedPos, Slice } from \"@tiptap/pm/model\";\nimport { Plugin } from \"@tiptap/pm/state\";\nimport { StarterKit } from \"@tiptap/starter-kit\";\nimport { common, createLowlight } from \"lowlight\";\nimport { Marked, type marked } from \"marked\";\nimport type { EditorFormat } from \"./editor-types.js\";\nimport {\n codeFence,\n escapeParagraphMarkdown,\n imageMarkdown,\n parseMentionMarkdown,\n renderMentionMarkdown\n} from \"./markdown-syntax.js\";\n\n/**\n * Giá trị đổi được SAU KHI trình soạn đã dựng. Extension đọc chúng lúc CẦN (lúc vẽ chữ mờ, lúc vẽ một\n * lần nhắc tên…), không chép lúc dựng — vì đổi danh sách extension là dựng lại cả trình soạn: mất\n * lịch sử hoàn tác, mất con trỏ. Component giữ object này trong một ref và ghi đè từng lượt render.\n */\nexport interface MarkdownEditorRuntime {\n placeholder: string;\n taskCheckbox: (text: string) => string;\n /** Đổi `src` ĐÃ LƯU thành địa chỉ HIỂN THỊ được (vd URL đã ký). Markdown vẫn giữ `src` gốc. */\n resolveImageSrc?: (src: string) => string;\n /**\n * Tên SỐNG theo id (và loại — `undefined` là người). `undefined` thì rơi về tên chụp lúc nhắc.\n */\n resolveMentionLabel?: (id: string, kind?: string) => string | undefined;\n /** Địa chỉ mở khi bấm một lần nhắc (vd `/tasks/<id>`). `undefined` = không phải liên kết. */\n resolveMentionHref?: (id: string, kind?: string) => string | undefined;\n}\n\nconst DEFAULT_RUNTIME: MarkdownEditorRuntime = {\n placeholder: \"\",\n taskCheckbox: (text) => text\n};\n\nexport interface MarkdownSchemaOptions {\n /** Định dạng LƯU — quyết định lược đồ. Mặc định `markdown`. */\n format?: EditorFormat;\n /** Đọc lười — xem `MarkdownEditorRuntime`. Bỏ trống ở nơi chỉ cần đọc/ghi (cổng, máy chủ). */\n runtime?: { readonly current: MarkdownEditorRuntime };\n /**\n * Cấu hình gợi ý `@` của `Mention` (danh sách, cách vẽ, `allow`). Bỏ trống = node `mention` vẫn có\n * trong lược đồ — để tài liệu CÓ nhắc tên vẫn đọc ra đúng ở chế độ chỉ đọc — nhưng gõ `@` không\n * mở gì.\n */\n mentionSuggestion?: Partial<MentionOptions[\"suggestion\"]>;\n}\n\n/*\n * Ngôn ngữ tô màu: bộ `common` của highlight.js (37 ngôn ngữ, ~53KB gzip — đo bằng esbuild trên\n * lowlight 3.3.0). Dựng MỘT lần cho cả module: bảng ngôn ngữ chỉ đọc, chia được giữa các trình soạn.\n */\nconst lowlight = createLowlight(common);\n\n/**\n * Đoạn văn — thêm phép thoát cú pháp khối (ca 1 ở đầu `markdown-syntax.ts`). Mọi hành vi khác giữ\n * nguyên bản gốc, kể cả `&nbsp;` cho đoạn rỗng: đó là cách CỐ Ý của Tiptap để giữ dòng trống người\n * dùng gõ — bỏ nó đi là nội dung \"co\" lại sau mỗi lần lưu.\n */\nconst ComitorParagraph = Paragraph.extend({\n renderMarkdown(node, helpers, context) {\n return escapeParagraphMarkdown(this.parent?.(node, helpers, context) ?? \"\");\n }\n});\n\n/** Khối mã — hàng rào dài hơn mọi dãy backtick bên trong (ca 2 ở đầu `markdown-syntax.ts`). */\nconst ComitorCodeBlock = CodeBlockLowlight.extend({\n renderMarkdown(node: JSONContent) {\n const language = typeof node.attrs?.language === \"string\" ? node.attrs.language : \"\";\n const text = (node.content ?? []).map((child) => child.text ?? \"\").join(\"\");\n const fence = codeFence(text);\n return `${fence}${language}\\n${text}\\n${fence}`;\n }\n});\n\n/** Bảng — bỏ dòng trống bản gốc kẹp hai đầu (xem `trimMarkdown`). */\nconst ComitorTable = Table.extend({\n renderMarkdown(node, helpers) {\n return renderTableToMarkdown(node, helpers).replace(/^\\n+|\\n+$/g, \"\");\n }\n});\n\n/*\n * Ô bảng chứa ĐÚNG MỘT đoạn văn — bản gốc cho `block+` (danh sách, khối mã, nhiều đoạn trong một ô).\n *\n * Ô bảng GFM là một dòng chữ, không chứa khối được. Đã đo trên 3.31.4: ô có hai đoạn ghi thành\n * `dòng 1<br>dòng 2`, ô có danh sách thành `- a<br>- b`, khối mã thành ```` ```<br>code<br>``` ````;\n * mở lại thì `<br>` là CHỮ THƯỜNG, và lần lưu kế tiếp nó thành `&lt;br&gt;` — mỗi lần lưu hỏng thêm\n * một lớp. Thu hẹp lược đồ là cách duy nhất chặn từ gốc: luật nhập (`- `, `# `, ```` ``` ````) và\n * lệnh khối tự thất bại trong ô vì lược đồ không cho, không cần chặn từng chỗ. Xuống dòng cứng trong ô\n * thì `createEditorKeymap` nuốt — `hardBreak` là node NỘI DÒNG nên lược đồ không chặn được nó.\n */\nconst ComitorTableCell = TableCell.extend({ content: \"paragraph\" });\nconst ComitorTableHeader = TableHeader.extend({ content: \"paragraph\" });\n\n/** Mẫu luật nhập của `HorizontalRule` trong StarterKit (3.31.4) — xem `MarkdownTableCellGuard`. */\nconst HORIZONTAL_RULE_INPUT = /^(?:---|—-|___\\s|\\*\\*\\*\\s)$/;\n\n/**\n * Ô bảng MARKDOWN — chặn nốt những đường CHÈN KHỐI mà lược đồ không chặn được.\n *\n * `ComitorTableCell` làm luật nhập BỌC (`- `, `# `, `> `) và lệnh đổi khối tự thất bại trong ô. Nhưng\n * phép THAY của ProseMirror không thất bại: khối không vừa chỗ thì nó TÁCH các node cha cho tới khi\n * vừa — tức tách CẢ BẢNG. Đã đo trên 3.31.4 (harness của `3.6.0`; cả ba có từ `3.5.0`):\n * · gõ `---` trong ô → bảng gãy làm hai, một đường kẻ ở giữa (luật nhập của `HorizontalRule`);\n * · dán một danh sách vào ô → bảng gãy làm hai, danh sách ở giữa;\n * · dán hai dòng chữ vào ô → hai dòng GHI ĐÈ lên ô đang đứng và ô kế bên — chữ cũ của cả hai mất.\n * Ba lớp, từ cụ thể tới chung:\n * 1. dán/thả từ ngoài: mọi khối của đoạn dán gộp thành MỘT dòng (`flattenSliceToLine`) — ô GFM là\n * một dòng chữ;\n * 2. `---` gõ trong ô ở lại là CHỮ — \"---\" là cách người ta hay ghi \"không có\" trong một ô bảng;\n * 3. lưới cuối: giao dịch nào làm SỐ BẢNG tăng khi con trỏ đang ở trong ô thì bị bỏ. Nó bắt mọi\n * đường còn lại (luật nhập ảnh `![a](b)`, kéo thả một khối trong tài liệu, `insertContent` của app),\n * với cái giá là phím hay cú thả vừa rồi không có tác dụng — mất một phím còn hơn gãy một bảng.\n * Hoàn tác/làm lại và thay CẢ tài liệu (`setContent`, `value` đổi từ ngoài) đi thẳng.\n *\n * Ô bảng của `RichTextEditor` chứa được khối nên không cần lớp nào trong ba.\n */\nconst MarkdownTableCellGuard = Extension.create({\n name: \"comitorMarkdownTableCellGuard\",\n // Cao hơn StarterKit (100): mỗi extension một plugin luật nhập, xếp theo `priority` — luật dưới đây\n // phải được hỏi TRƯỚC luật đường kẻ, không thì đường kẻ đã chèn xong.\n priority: 1000,\n addInputRules() {\n return [\n new InputRule({\n find: HORIZONTAL_RULE_INPUT,\n undoable: false,\n handler: ({ state, range, match }) => {\n if (!isInTableCell(state.doc.resolve(range.from))) return null;\n state.tr.insertText(match[0], range.from, range.to);\n }\n })\n ];\n },\n addProseMirrorPlugins() {\n /*\n * Đoạn dán có thật là BẢNG không — phải hỏi ở chuỗi GỐC. `normalizeSiblings` của ProseMirror bọc\n * sẵn các đoạn văn dán vào ô thành Ô BẢNG (để chúng \"vừa\" chỗ) trước khi `transformPasted` thấy\n * chúng, nên nhìn slice thì \"dán hai dòng chữ\" và \"dán hai ô\" là một — và `prosemirror-tables` dán\n * cả hai theo kiểu ô, đè lên ô kế bên. Đã đo: đó chính là ca \"hai dòng ghi đè hai ô\" ở trên.\n */\n let pastedTable = false;\n return [\n new Plugin({\n props: {\n transformPastedHTML: (html) => {\n pastedTable = /<(?:table|tr|td|th)[\\s>/]/i.test(html);\n return html;\n },\n transformPastedText: (text) => {\n pastedTable = false;\n return text;\n },\n transformPasted: (slice, view) => {\n const keepTables = pastedTable;\n pastedTable = false;\n return isInTableCell(view.state.selection.$from) ? flattenSliceToLine(slice, keepTables) : slice;\n }\n },\n filterTransaction: (tr, state) => {\n if (!tr.docChanged || tr.getMeta(\"history$\") || !isInTableCell(state.selection.$from)) return true;\n if (replacesWholeDocument(tr.steps, state.doc.content.size)) return true;\n return countTables(tr.doc) <= countTables(state.doc);\n }\n })\n ];\n }\n});\n\n/**\n * Gộp một đoạn dán thành MỘT dòng nội dòng: các khối chữ nối nhau bằng một dấu cách, xuống dòng (cả\n * `hardBreak` lẫn `\\n` trong khối mã) thành dấu cách, khối không phải chữ (ảnh, đường kẻ) bỏ đi.\n * Nội dung nội dòng sẵn thì để nguyên; `keepTables` (đoạn dán GỐC có bảng) thì đoạn dán mang ô bảng\n * cũng để nguyên — dán theo ô là việc của `prosemirror-tables`.\n * Xuất ra cho cổng `test:editor-markdown`; không nằm trong entry.\n */\nexport function flattenSliceToLine(slice: Slice, keepTables = false): Slice {\n const first = slice.content.firstChild;\n if (!first || first.isInline) return slice;\n if (keepTables) {\n let tabular = false;\n slice.content.descendants((node) => {\n if (node.type.spec.tableRole) tabular = true;\n return !tabular;\n });\n if (tabular) return slice;\n }\n\n const schema = first.type.schema;\n const line: ProseMirrorNode[] = [];\n slice.content.descendants((node) => {\n if (!node.isTextblock) return true;\n if (node.content.size === 0) return false;\n if (line.length > 0) line.push(schema.text(\" \"));\n node.content.forEach((child) => {\n if (child.type.name === \"hardBreak\") line.push(schema.text(\" \"));\n else if (child.isText && child.text?.includes(\"\\n\"))\n line.push(schema.text(child.text.replace(/\\s*\\n\\s*/g, \" \"), child.marks));\n else line.push(child);\n });\n return false;\n });\n return new Slice(Fragment.from(line), 0, 0);\n}\n\nfunction countTables(doc: ProseMirrorNode): number {\n let count = 0;\n doc.descendants((node) => {\n if (node.type.name === \"table\") count++;\n return node.type.name !== \"table\";\n });\n return count;\n}\n\n/** Có bước nào thay TOÀN BỘ tài liệu không — `setContent` làm đúng một bước như vậy. */\nfunction replacesWholeDocument(steps: readonly unknown[], size: number): boolean {\n return steps.some((step) => {\n const { from, to } = step as { from?: unknown; to?: unknown };\n return from === 0 && to === size;\n });\n}\n\n/**\n * Bảng chữ markdown RIÊNG cho từng trình soạn.\n *\n * ⚠ Không truyền thì `@tiptap/markdown` dùng `marked` TOÀN CỤC, và mỗi lần trình soạn mount nó gọi\n * `marked.use()` đăng ký lại bộ tách từ (bảng, nhắc tên…) — không bao giờ gỡ. Đã đo trên 3.31.4:\n * mỗi `MarkdownManager` thêm 4 bộ tách; sau 200 lần dựng, parse cùng một tài liệu 200 đoạn chậm từ\n * 18,6ms lên 282ms, và còn tăng tiếp. Trong một SPA, 200 lần là một buổi làm việc mở việc này sang\n * việc khác. Một bản `Marked` mỗi trình soạn: 4 bộ tách, 5,7ms, mất cùng trình soạn.\n *\n * Ép kiểu vì option khai `typeof marked` (hàm `marked` toàn cục, gọi được) mà thứ đúng là một bản\n * `Marked`: `MarkdownManager` chỉ dùng `.use`, `.Lexer`, `.defaults`, `.lexer`, `.setOptions` — bản\n * `Marked` có đủ cả năm, chỉ thiếu chữ ký gọi-như-hàm mà không chỗ nào gọi tới.\n */\nfunction createMarkedInstance(): typeof marked {\n return new Marked() as unknown as typeof marked;\n}\n\n/**\n * Danh sách extension tạo nên lược đồ của trình soạn, theo định dạng LƯU.\n *\n * Markdown (`format: \"markdown\"`, mặc định) hẹp hơn HTML ở hai chỗ, cả hai vì cùng một lý do — thứ gì\n * không ghi được thành markdown thì MẤT ở lần lưu, mà người dùng không được báo:\n * · `underline` tắt: markdown không có cú pháp gạch chân. `@tiptap/markdown` ghi nó thành\n * `++chữ++` — cú pháp riêng, nên email thông báo, tác tử đọc qua MCP và mọi trình xem markdown\n * khác in nguyên hai dấu cộng;\n * · ô bảng chỉ chứa MỘT đoạn văn (`ComitorTableCell`).\n * Hai bản vá markdown (`ComitorParagraph`, `Markdown` với `Marked` riêng) cũng chỉ nạp ở định dạng đó.\n *\n * HTML (`format: \"html\"`) giữ cả gạch chân lẫn ô bảng nhiều khối — `<u>`, `<td><ul>…</ul></td>` là HTML\n * hợp lệ và đọc lên lại đúng.\n */\nexport function createSchemaExtensions(options: MarkdownSchemaOptions = {}): AnyExtension[] {\n const runtime = options.runtime ?? { current: DEFAULT_RUNTIME };\n const markdown = (options.format ?? \"markdown\") === \"markdown\";\n\n return [\n StarterKit.configure({\n paragraph: false,\n codeBlock: false,\n ...(markdown ? { underline: false as const } : {}),\n link: {\n // Đang sửa thì bấm vào liên kết là đặt con trỏ, không phải mở tab mới (thanh định dạng có nút\n // Mở). Chỉ đọc thì Tiptap không chặn cú bấm — thẻ `<a target=\"_blank\">` tự mở như thường.\n openOnClick: false,\n autolink: true,\n linkOnPaste: true,\n // Gõ/dán `[chữ](https://…)` là thành liên kết — người quen markdown gõ vậy theo phản xạ.\n markdownLinks: true,\n defaultProtocol: \"https\",\n HTMLAttributes: { target: \"_blank\", rel: \"noopener noreferrer nofollow\" }\n }\n }),\n markdown ? ComitorParagraph : Paragraph,\n ComitorCodeBlock.configure({\n lowlight,\n defaultLanguage: null,\n // Tab trong khối mã là thụt lề — đúng điều người viết mã chờ đợi. Thoát khối: ↓ ở dòng cuối,\n // hoặc Enter ba lần (mặc định của Tiptap).\n enableTabIndentation: true,\n tabSize: 2\n }),\n TaskList,\n TaskItem.configure({\n nested: true,\n // Chữ của ĐOẠN ĐẦU, không phải `node.textContent`: mục cha có danh sách con thì `textContent` dính\n // liền chữ của mọi mục con (\"Gửi mã qua emailGiới hạn 5 lần/giờ\") — đã gặp.\n a11y: { checkboxLabel: (node) => runtime.current.taskCheckbox(node.firstChild?.textContent ?? \"\") }\n }),\n ...(markdown\n ? [\n TableKit.configure({ table: false, tableCell: false, tableHeader: false }),\n ComitorTable.configure({ resizable: false }),\n ComitorTableCell,\n ComitorTableHeader,\n MarkdownTableCellGuard\n ]\n : [TableKit.configure({ table: { resizable: false } })]),\n createImageExtension(runtime),\n createMentionExtension(runtime, options.mentionSuggestion),\n Placeholder.configure({ placeholder: () => runtime.current.placeholder }),\n ...(markdown\n ? [Markdown.configure({ marked: createMarkedInstance(), indentation: { style: \"space\", size: 2 } })]\n : [])\n ];\n}\n\n/** Lược đồ của `MarkdownEditor` — tên có từ `3.5.0`, cổng `test:editor-markdown` gọi thẳng nó. */\nexport function createMarkdownSchemaExtensions(options: Omit<MarkdownSchemaOptions, \"format\"> = {}): AnyExtension[] {\n return createSchemaExtensions({ ...options, format: \"markdown\" });\n}\n\n/**\n * Ảnh — tách địa chỉ LƯU khỏi địa chỉ HIỂN THỊ, và thoát cú pháp khi ghi markdown.\n *\n * Kho ảnh của module Comitor là bucket RIÊNG TƯ: thứ hiện được là URL đã ký, có hạn. Lưu URL đó vào\n * nội dung là lưu một giá trị sẽ chết ngay trong database — nên nội dung giữ `src` app trả về (khoá,\n * hoặc một route ổn định của app), còn `resolveImageSrc` đổi nó thành địa chỉ vẽ được lúc vẽ.\n *\n * ⚠ Đổi địa chỉ ở NODE VIEW, không ở `renderHTML`. `renderHTML` vừa vẽ ảnh trong trình soạn vừa là\n * thứ `editor.getHTML()` dùng để GHI — đổi `src` ở đó (cách của `3.5.0`, khi giá trị còn là markdown)\n * là `RichTextEditor` ghi URL đã ký vào HTML lưu xuống. Node view chỉ là DOM của màn hình; HTML lưu\n * vẫn đi `renderHTML` gốc với `src` gốc.\n *\n * Ảnh ĐANG tải lên không phải node — xem đầu `image-upload.ts`.\n */\nfunction createImageExtension(runtime: { readonly current: MarkdownEditorRuntime }) {\n return Image.extend({\n addNodeView() {\n return ({ node, HTMLAttributes }) => {\n const image = document.createElement(\"img\");\n setAttributes(image, mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), [\"src\"]);\n const src = typeof node.attrs.src === \"string\" ? node.attrs.src : \"\";\n // `src=\"\"` thì trình duyệt tải lại CHÍNH trang làm ảnh — thiếu địa chỉ thì bỏ hẳn thuộc tính.\n if (src) image.setAttribute(\"src\", runtime.current.resolveImageSrc?.(src) ?? src);\n return { dom: image, update: (updated) => sameNode(updated, node) };\n };\n },\n renderMarkdown(node: JSONContent) {\n return imageMarkdown(String(node.attrs?.src ?? \"\"), node.attrs?.alt, node.attrs?.title);\n }\n }).configure({ allowBase64: false });\n}\n\n/**\n * Nhắc tên — định dạng lưu `[@Tên](mention:<id>)` (lý do ở `markdown-syntax.ts`) và tên SỐNG lúc vẽ.\n *\n * Tên sống chỉ đi vào thứ NGƯỜI XEM thấy: node view và `renderText` (chữ khi chép ra ngoài).\n * `renderHTML` — thứ `getHTML()` ghi xuống — giữ TÊN CHỤP lúc nhắc, cùng luật với markdown: nội dung\n * lưu không tự đổi theo danh bạ chỉ vì có người mở và lưu lại.\n */\nfunction createMentionExtension(\n runtime: { readonly current: MarkdownEditorRuntime },\n suggestion: MarkdownSchemaOptions[\"mentionSuggestion\"]\n) {\n const storedLabelOf = (attrs: Record<string, unknown>) => {\n const stored = typeof attrs.label === \"string\" ? attrs.label : \"\";\n return stored || (typeof attrs.id === \"string\" ? attrs.id : \"\");\n };\n const kindOf = (attrs: Record<string, unknown>) =>\n typeof attrs.kind === \"string\" && attrs.kind ? attrs.kind : undefined;\n const labelOf = (attrs: Record<string, unknown>) =>\n runtime.current.resolveMentionLabel?.(typeof attrs.id === \"string\" ? attrs.id : \"\", kindOf(attrs)) ??\n storedLabelOf(attrs);\n\n return Mention.extend({\n /*\n * `kind` (từ 3.7.0): loại thực thể — `null` là người. Ra HTML thành `data-kind` (lưu được ở định dạng\n * HTML và để app tô khác theo loại), ra markdown thành tiền tố `kind/` của địa chỉ.\n */\n addAttributes() {\n return {\n ...this.parent?.(),\n kind: {\n default: null,\n parseHTML: (element: HTMLElement) => element.getAttribute(\"data-kind\") || null,\n renderHTML: (attributes: Record<string, unknown>) =>\n typeof attributes.kind === \"string\" && attributes.kind ? { \"data-kind\": attributes.kind } : {}\n }\n };\n },\n markdownTokenName: \"mention\",\n markdownTokenizer: {\n name: \"mention\",\n level: \"inline\",\n start: (source: string) => source.indexOf(\"[@\"),\n tokenize: (source: string) => {\n const parsed = parseMentionMarkdown(source);\n return parsed\n ? { type: \"mention\", raw: parsed.raw, id: parsed.id, label: parsed.label, kind: parsed.kind ?? null }\n : undefined;\n }\n },\n parseMarkdown: (token, helpers) =>\n helpers.createNode(\"mention\", { id: token.id, label: token.label, kind: token.kind ?? null }),\n renderMarkdown: (node: JSONContent) =>\n renderMentionMarkdown(\n String(node.attrs?.id ?? \"\"),\n node.attrs?.label as string | null | undefined,\n node.attrs?.kind as string | null | undefined\n ),\n addNodeView() {\n return ({ node, HTMLAttributes }) => {\n /*\n * Có địa chỉ (`mentions.getHref`) thì vẽ `<a>`: nhắc VIỆC mở được việc đó. Chỉ nhận đường dẫn tương đối\n * cùng gốc hoặc `http(s):` — địa chỉ do app dựng, nhưng một `javascript:` lọt vào đây là chạy được.\n * Chỉ ở node VIEW: thứ GHI xuống (`renderHTML`, markdown) không mang địa chỉ nào.\n */\n const id = typeof node.attrs.id === \"string\" ? node.attrs.id : \"\";\n const href = runtime.current.resolveMentionHref?.(id, kindOf(node.attrs));\n const safeHref = href && /^(?:\\/(?![/\\\\])|https?:\\/\\/)/i.test(href) ? href : undefined;\n const dom = document.createElement(safeHref ? \"a\" : \"span\");\n setAttributes(dom, mergeAttributes({ \"data-type\": this.name }, this.options.HTMLAttributes, HTMLAttributes));\n if (safeHref) dom.setAttribute(\"href\", safeHref);\n dom.textContent = `@${labelOf(node.attrs)}`;\n return { dom, update: (updated) => sameNode(updated, node) };\n };\n }\n }).configure({\n renderText: ({ node }) => `@${labelOf(node.attrs)}`,\n // `options.HTMLAttributes` ở đây là bản Tiptap đã trộn sẵn (`data-type`, `data-id`, `data-label`).\n renderHTML: ({ options, node }) => [\"span\", options.HTMLAttributes, `@${storedLabelOf(node.attrs)}`],\n suggestion: { char: \"@\", allow: () => false, ...suggestion }\n });\n}\n\n/** Phím tắt riêng của trình soạn — xem `createEditorKeymap`. */\nexport interface EditorKeymapHandlers {\n /** ⌘/Ctrl+K — mở ô liên kết. Trả `true` khi đã xử lý. */\n onLinkShortcut: () => boolean;\n /** ⌘/Ctrl+Enter ngoài danh sách việc. Trả `false` để phím đi tiếp (xuống dòng cứng của Tiptap). */\n onSubmitShortcut: () => boolean;\n /** Enter trần (chỉ khi `submitOnEnter`). Trả `false` để phím đi tiếp (đoạn mới, mục danh sách mới…). */\n onEnterShortcut: () => boolean;\n}\n\n/**\n * Phím tắt của RIÊNG gói, ưu tiên cao hơn mặc định của Tiptap.\n *\n * ⌘/Ctrl+Enter: trong danh sách việc thì tick/bỏ tick mục đang đứng (như Linear); ngoài đó thì gửi\n * (`onSubmit`) — đúng phím mà ô bình luận nào cũng dùng. Không có `onSubmit` thì trả phím về cho\n * Tiptap (bản gốc gán nó cho xuống dòng cứng).\n *\n * ⌘/Ctrl+K: ô liên kết. Không đụng bảng lệnh của shell — listener của shell tự bỏ qua phím khi\n * đích là vùng `contenteditable` (`shell-context.tsx`, nhánh `isTyping`).\n */\nexport function createEditorKeymap(\n handlers: { readonly current: EditorKeymapHandlers },\n format: EditorFormat = \"markdown\"\n): Extension {\n // Chỉ ô bảng MARKDOWN cấm xuống dòng cứng (`ComitorTableCell`); ô bảng HTML chứa được cả khối.\n const swallowInCell = (editor: { state: { selection: { $from: ResolvedPos } } }) =>\n format === \"markdown\" && isInTableCell(editor.state.selection.$from);\n return Extension.create({\n name: \"comitorEditorKeymap\",\n priority: 1000,\n addKeyboardShortcuts() {\n return {\n \"Mod-k\": () => handlers.current.onLinkShortcut(),\n \"Mod-Enter\": ({ editor }) => {\n const toggled = editor.commands.command(({ tr, state }) => {\n const { $from } = state.selection;\n for (let depth = $from.depth; depth > 0; depth--) {\n const node = $from.node(depth);\n if (node.type.name !== \"taskItem\") continue;\n tr.setNodeMarkup($from.before(depth), undefined, { ...node.attrs, checked: !node.attrs.checked });\n return true;\n }\n return false;\n });\n if (toggled || handlers.current.onSubmitShortcut()) return true;\n // Phím đi tiếp tới Tiptap là xuống dòng cứng — trong ô bảng markdown thì nuốt (xem `ComitorTableCell`).\n return swallowInCell(editor);\n },\n \"Shift-Enter\": ({ editor }) => swallowInCell(editor),\n // `view.composing`: Enter đang chốt chữ của bộ gõ (Telex/VNI qua IME hệ thống) không được gửi tin.\n Enter: ({ editor }) => !editor.view.composing && handlers.current.onEnterShortcut()\n };\n }\n });\n}\n\n/** Con trỏ có đang đứng trong một ô bảng (thường hay tiêu đề) không. */\nfunction isInTableCell($pos: ResolvedPos): boolean {\n for (let depth = $pos.depth; depth > 0; depth--) {\n const name = $pos.node(depth).type.name;\n if (name === \"tableCell\" || name === \"tableHeader\") return true;\n }\n return false;\n}\n\n/** Ghi thuộc tính lên phần tử của node view — bỏ giá trị rỗng, như `DOMSerializer` làm với `renderHTML`. */\nfunction setAttributes(element: HTMLElement, attributes: Record<string, unknown>, skip: readonly string[] = []): void {\n for (const [key, value] of Object.entries(attributes)) {\n if (skip.includes(key) || value === null || value === undefined || value === false) continue;\n element.setAttribute(key, String(value));\n }\n}\n\n/**\n * Node view của nút LÁ (ảnh, nhắc tên): thuộc tính không đổi thì giữ DOM; đổi thì trả `false` để\n * ProseMirror dựng lại — rẻ, và không có trạng thái nào trong DOM đáng giữ.\n */\nfunction sameNode(updated: ProseMirrorNode, current: ProseMirrorNode): boolean {\n if (updated.type !== current.type) return false;\n return Object.keys(current.attrs).every((key) => updated.attrs[key] === current.attrs[key]);\n}\n"],"mappings":"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","names":[]}
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { g as EditorBaseProps, a as EditorToolbarMode, E as EditorHandleBase } from '../editor-types-CSrMeuSw.js';
2
+ import { f as EditorBaseProps, a as EditorToolbarMode, E as EditorHandleBase } from '../editor-types-BacXD2VN.js';
3
3
  import '@tiptap/core';
4
4
  import '../components/composite/empty-state.js';
5
5
  import './markdown-editor-constants.js';
@@ -2,7 +2,7 @@ import { Editor, Range, Extension } from '@tiptap/core';
2
2
  import { PluginKey } from '@tiptap/pm/state';
3
3
  import { SuggestionOptions } from '@tiptap/suggestion';
4
4
  import { LucideIcon } from 'lucide-react';
5
- import { f as EditorFormat } from '../editor-types-CSrMeuSw.js';
5
+ import { g as EditorFormat } from '../editor-types-BacXD2VN.js';
6
6
  import { MarkdownEditorBlockId, MarkdownEditorLabels } from './markdown-editor-constants.js';
7
7
  import '../components/composite/empty-state.js';
8
8
  import 'react';
@@ -1,6 +1,6 @@
1
1
  import { Editor } from '@tiptap/core';
2
2
  import { LucideIcon } from 'lucide-react';
3
- import { f as EditorFormat } from '../editor-types-CSrMeuSw.js';
3
+ import { g as EditorFormat } from '../editor-types-BacXD2VN.js';
4
4
  import { MarkdownEditorLabels } from './markdown-editor-constants.js';
5
5
  import '../components/composite/empty-state.js';
6
6
  import 'react';
@@ -140,6 +140,12 @@ interface EditorBaseProps {
140
140
  * phím giữ nghĩa mặc định.
141
141
  */
142
142
  onSubmit?: () => void;
143
+ /**
144
+ * Enter trần cũng gửi (`onSubmit`) — cho ô nhập của khung hội thoại. Shift+Enter xuống dòng; Enter
145
+ * khi menu `@`/`/` đang mở vẫn chọn mục, và Enter đang gõ dở bộ gõ tiếng Việt (IME) vẫn chốt chữ.
146
+ * Không có `onSubmit` thì phím giữ nghĩa mặc định.
147
+ */
148
+ submitOnEnter?: boolean;
143
149
  onFocus?: () => void;
144
150
  onBlur?: () => void;
145
151
  /** Chữ mờ khi rỗng. Mặc định theo `ComitorLocaleProvider`. */
@@ -185,4 +191,4 @@ interface EditorBaseProps {
185
191
  contentClassName?: string;
186
192
  }
187
193
 
188
- export { type EditorHandleBase as E, type ImageUploadHandlers as I, type MarkdownEditorImageUploadResult as M, type PendingUploads as P, type EditorToolbarMode as a, type MarkdownEditorMentionItem as b, type MarkdownEditorMentionSource as c, type MarkdownEditorMentions as d, type MarkdownEditorVariant as e, type EditorFormat as f, type EditorBaseProps as g, createImageUploadExtension as h, imageFilesFrom as i, insertImageFiles as j };
194
+ export { type EditorHandleBase as E, type ImageUploadHandlers as I, type MarkdownEditorImageUploadResult as M, type PendingUploads as P, type EditorToolbarMode as a, type MarkdownEditorMentionItem as b, type MarkdownEditorMentionSource as c, type MarkdownEditorMentions as d, type MarkdownEditorVariant as e, type EditorBaseProps as f, type EditorFormat as g, createImageUploadExtension as h, imageFilesFrom as i, insertImageFiles as j };
@@ -30,6 +30,7 @@ import './namespaces/command-palette.js';
30
30
  import '../components/composite/command-palette-constants.js';
31
31
  import './namespaces/command.js';
32
32
  import './namespaces/combobox.js';
33
+ import '../chat/chat-constants.js';
33
34
  import './namespaces/carousel.js';
34
35
  import './namespaces/calendar.js';
35
36
  import './namespaces/breadcrumb.js';
@@ -37,8 +38,10 @@ import './namespaces/banner.js';
37
38
  import './namespaces/badge-overflow.js';
38
39
  import './namespaces/avatar-group.js';
39
40
  import '../components/composite/data-table-constants.js';
41
+ import '../components/composite/gantt-constants.js';
40
42
  import '../components/composite/search-filter-bar-constants.js';
41
43
  import '../components/composite/table-pagination-constants.js';
44
+ import '../components/composite/tree-view-constants.js';
42
45
  import '../components/ui/action-bar-constants.js';
43
46
  import '../components/ui/cropper-constants.js';
44
47
  import '../components/ui/kanban-constants.js';
@@ -22,6 +22,7 @@ import { ConfirmDialogMessages } from './namespaces/confirm-dialog.js';
22
22
  import { CommandPaletteMessages } from './namespaces/command-palette.js';
23
23
  import { CommandMessages } from './namespaces/command.js';
24
24
  import { ComboboxMessages } from './namespaces/combobox.js';
25
+ import { ChatLabels } from '../chat/chat-constants.js';
25
26
  import { CarouselMessages } from './namespaces/carousel.js';
26
27
  import { CalendarMessages } from './namespaces/calendar.js';
27
28
  import { BreadcrumbMessages } from './namespaces/breadcrumb.js';
@@ -29,8 +30,10 @@ import { BannerMessages } from './namespaces/banner.js';
29
30
  import { BadgeOverflowMessages } from './namespaces/badge-overflow.js';
30
31
  import { AvatarGroupMessages } from './namespaces/avatar-group.js';
31
32
  import { DataTableLabels } from '../components/composite/data-table-constants.js';
33
+ import { GanttLabels } from '../components/composite/gantt-constants.js';
32
34
  import { SearchFilterBarLabels } from '../components/composite/search-filter-bar-constants.js';
33
35
  import { TablePaginationLabels } from '../components/composite/table-pagination-constants.js';
36
+ import { TreeViewLabels } from '../components/composite/tree-view-constants.js';
34
37
  import { ActionBarLabels } from '../components/ui/action-bar-constants.js';
35
38
  import { CropperLabels } from '../components/ui/cropper-constants.js';
36
39
  import { KanbanLabels } from '../components/ui/kanban-constants.js';
@@ -57,6 +60,7 @@ declare const comitorMessagesEn: {
57
60
  breadcrumb: BreadcrumbMessages;
58
61
  calendar: CalendarMessages;
59
62
  carousel: CarouselMessages;
63
+ chat: ChatLabels;
60
64
  combobox: ComboboxMessages;
61
65
  command: CommandMessages;
62
66
  commandPalette: CommandPaletteMessages;
@@ -70,6 +74,7 @@ declare const comitorMessagesEn: {
70
74
  displayAxis: DisplayAxisMessages;
71
75
  fileUpload: FileUploadLabels;
72
76
  filterChips: FilterChipsMessages;
77
+ gantt: GanttLabels;
73
78
  imageUploadField: ImageUploadFieldLabels;
74
79
  inlineEdit: InlineEditMessages;
75
80
  keyboardShortcuts: KeyboardShortcutsMessages;
@@ -92,6 +97,7 @@ declare const comitorMessagesEn: {
92
97
  timePicker: TimePickerLabels;
93
98
  toast: ToastMessages;
94
99
  tour: TourLabels;
100
+ treeView: TreeViewLabels;
95
101
  };
96
102
  /** Hình dạng của một bảng chữ đầy đủ. Suy từ bảng tiếng Anh, không viết tay lần hai. */
97
103
  type ComitorMessages = typeof comitorMessagesEn;
@@ -6,6 +6,7 @@ import { bannerEn, bannerVi } from "./namespaces/banner.js";
6
6
  import { breadcrumbEn, breadcrumbVi } from "./namespaces/breadcrumb.js";
7
7
  import { calendarEn, calendarVi } from "./namespaces/calendar.js";
8
8
  import { carouselEn, carouselVi } from "./namespaces/carousel.js";
9
+ import { chatEn, chatVi } from "./namespaces/chat.js";
9
10
  import { comboboxEn, comboboxVi } from "./namespaces/combobox.js";
10
11
  import { commandEn, commandVi } from "./namespaces/command.js";
11
12
  import { commandPaletteEn, commandPaletteVi } from "./namespaces/command-palette.js";
@@ -19,6 +20,7 @@ import { dialogEn, dialogVi } from "./namespaces/dialog.js";
19
20
  import { displayAxisEn, displayAxisVi } from "./namespaces/display-axis.js";
20
21
  import { fileUploadEn, fileUploadVi } from "./namespaces/file-upload.js";
21
22
  import { filterChipsEn, filterChipsVi } from "./namespaces/filter-chips.js";
23
+ import { ganttEn, ganttVi } from "./namespaces/gantt.js";
22
24
  import { imageUploadFieldEn, imageUploadFieldVi } from "./namespaces/image-upload-field.js";
23
25
  import { inlineEditEn, inlineEditVi } from "./namespaces/inline-edit.js";
24
26
  import { kanbanEn, kanbanVi } from "./namespaces/kanban.js";
@@ -41,6 +43,7 @@ import { tagsInputEn, tagsInputVi } from "./namespaces/tags-input.js";
41
43
  import { timePickerEn, timePickerVi } from "./namespaces/time-picker.js";
42
44
  import { toastEn, toastVi } from "./namespaces/toast.js";
43
45
  import { tourEn, tourVi } from "./namespaces/tour.js";
46
+ import { treeViewEn, treeViewVi } from "./namespaces/tree-view.js";
44
47
  const comitorMessagesEn = {
45
48
  actionBar: actionBarEn,
46
49
  avatarGroup: avatarGroupEn,
@@ -49,6 +52,7 @@ const comitorMessagesEn = {
49
52
  breadcrumb: breadcrumbEn,
50
53
  calendar: calendarEn,
51
54
  carousel: carouselEn,
55
+ chat: chatEn,
52
56
  combobox: comboboxEn,
53
57
  command: commandEn,
54
58
  commandPalette: commandPaletteEn,
@@ -62,6 +66,7 @@ const comitorMessagesEn = {
62
66
  displayAxis: displayAxisEn,
63
67
  fileUpload: fileUploadEn,
64
68
  filterChips: filterChipsEn,
69
+ gantt: ganttEn,
65
70
  imageUploadField: imageUploadFieldEn,
66
71
  inlineEdit: inlineEditEn,
67
72
  keyboardShortcuts: keyboardShortcutsEn,
@@ -83,7 +88,8 @@ const comitorMessagesEn = {
83
88
  tagsInput: tagsInputEn,
84
89
  timePicker: timePickerEn,
85
90
  toast: toastEn,
86
- tour: tourEn
91
+ tour: tourEn,
92
+ treeView: treeViewEn
87
93
  };
88
94
  const comitorMessagesVi = {
89
95
  actionBar: actionBarVi,
@@ -93,6 +99,7 @@ const comitorMessagesVi = {
93
99
  breadcrumb: breadcrumbVi,
94
100
  calendar: calendarVi,
95
101
  carousel: carouselVi,
102
+ chat: chatVi,
96
103
  combobox: comboboxVi,
97
104
  command: commandVi,
98
105
  commandPalette: commandPaletteVi,
@@ -106,6 +113,7 @@ const comitorMessagesVi = {
106
113
  displayAxis: displayAxisVi,
107
114
  fileUpload: fileUploadVi,
108
115
  filterChips: filterChipsVi,
116
+ gantt: ganttVi,
109
117
  imageUploadField: imageUploadFieldVi,
110
118
  inlineEdit: inlineEditVi,
111
119
  keyboardShortcuts: keyboardShortcutsVi,
@@ -127,7 +135,8 @@ const comitorMessagesVi = {
127
135
  tagsInput: tagsInputVi,
128
136
  timePicker: timePickerVi,
129
137
  toast: toastVi,
130
- tour: tourVi
138
+ tour: tourVi,
139
+ treeView: treeViewVi
131
140
  };
132
141
  const COMITOR_MESSAGES = {
133
142
  en: comitorMessagesEn,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/i18n/messages.ts"],"sourcesContent":["/**\n * Bảng CHỮ của cả gói — module THUẦN (không directive, không hook), Server Component đọc thẳng\n * được (`verify:directives`, phép kiểm 2 và 3).\n *\n * Cùng khuôn với bảng chuỗi của `DataGrid` (`data-grid/messages.ts`), nay áp cho MỌI component:\n * · `comitorMessagesEn` là BẢN GỐC định nghĩa hình dạng ({@link ComitorMessages}). Tiếng Anh\n * là mặc định từ `3.0.0` — gói phục vụ cả app quốc tế, không chỉ app Comitor.\n * · `comitorMessagesVi` chú thích `: ComitorMessages`, nên thiếu một khoá là typecheck đỏ\n * ngay — không có đường nào để một chuỗi `undefined` lặng lẽ lọt ra giao diện.\n *\n * Mỗi namespace là MỘT component (hoặc một cụm component dùng chung chữ, vd `shell`). Chuỗi có\n * tham số viết thành HÀM, không phải mẫu có chỗ trống — trật tự từ quanh con số khác nhau theo ngôn\n * ngữ, nên mọi cách để gói tự nối chuỗi đều là chỗ chắc chắn dịch sai.\n *\n * Thêm ngôn ngữ thứ ba: app KHÔNG phải sửa gói — truyền cả một bảng qua prop `messages` của\n * `ComitorLocaleProvider` (trải `comitorMessagesEn` ra rồi dịch từng namespace).\n */\nimport { type ComitorLanguage, getComitorLanguage } from \"./locale.js\";\nimport { actionBarEn, actionBarVi } from \"./namespaces/action-bar.js\";\nimport { avatarGroupEn, avatarGroupVi } from \"./namespaces/avatar-group.js\";\nimport { badgeOverflowEn, badgeOverflowVi } from \"./namespaces/badge-overflow.js\";\nimport { bannerEn, bannerVi } from \"./namespaces/banner.js\";\nimport { breadcrumbEn, breadcrumbVi } from \"./namespaces/breadcrumb.js\";\nimport { calendarEn, calendarVi } from \"./namespaces/calendar.js\";\nimport { carouselEn, carouselVi } from \"./namespaces/carousel.js\";\nimport { comboboxEn, comboboxVi } from \"./namespaces/combobox.js\";\nimport { commandEn, commandVi } from \"./namespaces/command.js\";\nimport { commandPaletteEn, commandPaletteVi } from \"./namespaces/command-palette.js\";\nimport { confirmDialogEn, confirmDialogVi } from \"./namespaces/confirm-dialog.js\";\nimport { contrastEn, contrastVi } from \"./namespaces/contrast.js\";\nimport { copyButtonEn, copyButtonVi } from \"./namespaces/copy-button.js\";\nimport { cropperEn, cropperVi } from \"./namespaces/cropper.js\";\nimport { dataTableEn, dataTableVi } from \"./namespaces/data-table.js\";\nimport { datePickerEn, datePickerVi } from \"./namespaces/date-picker.js\";\nimport { dialogEn, dialogVi } from \"./namespaces/dialog.js\";\nimport { displayAxisEn, displayAxisVi } from \"./namespaces/display-axis.js\";\nimport { fileUploadEn, fileUploadVi } from \"./namespaces/file-upload.js\";\nimport { filterChipsEn, filterChipsVi } from \"./namespaces/filter-chips.js\";\nimport { imageUploadFieldEn, imageUploadFieldVi } from \"./namespaces/image-upload-field.js\";\nimport { inlineEditEn, inlineEditVi } from \"./namespaces/inline-edit.js\";\nimport { kanbanEn, kanbanVi } from \"./namespaces/kanban.js\";\nimport { keyValueEn, keyValueVi } from \"./namespaces/key-value.js\";\nimport { keyboardShortcutsEn, keyboardShortcutsVi } from \"./namespaces/keyboard-shortcuts.js\";\nimport { markdownEditorEn, markdownEditorVi } from \"./namespaces/markdown-editor.js\";\nimport { mentionEn, mentionVi } from \"./namespaces/mention.js\";\nimport { paginationEn, paginationVi } from \"./namespaces/pagination.js\";\nimport { phoneInputEn, phoneInputVi } from \"./namespaces/phone-input.js\";\nimport { ratingEn, ratingVi } from \"./namespaces/rating.js\";\nimport { routeTabsEn, routeTabsVi } from \"./namespaces/route-tabs.js\";\nimport { scrollSpyEn, scrollSpyVi } from \"./namespaces/scroll-spy.js\";\nimport { searchFilterBarEn, searchFilterBarVi } from \"./namespaces/search-filter-bar.js\";\nimport { sheetEn, sheetVi } from \"./namespaces/sheet.js\";\nimport { shellEn, shellVi } from \"./namespaces/shell.js\";\nimport { spinnerEn, spinnerVi } from \"./namespaces/spinner.js\";\nimport { stepperEn, stepperVi } from \"./namespaces/stepper.js\";\nimport { tablePaginationEn, tablePaginationVi } from \"./namespaces/table-pagination.js\";\nimport { tagsInputEn, tagsInputVi } from \"./namespaces/tags-input.js\";\nimport { timePickerEn, timePickerVi } from \"./namespaces/time-picker.js\";\nimport { toastEn, toastVi } from \"./namespaces/toast.js\";\nimport { tourEn, tourVi } from \"./namespaces/tour.js\";\n\n/** Bảng tiếng Anh — BẢN GỐC, định nghĩa hình dạng của mọi bảng khác. */\nexport const comitorMessagesEn = {\n actionBar: actionBarEn,\n avatarGroup: avatarGroupEn,\n badgeOverflow: badgeOverflowEn,\n banner: bannerEn,\n breadcrumb: breadcrumbEn,\n calendar: calendarEn,\n carousel: carouselEn,\n combobox: comboboxEn,\n command: commandEn,\n commandPalette: commandPaletteEn,\n confirmDialog: confirmDialogEn,\n contrast: contrastEn,\n copyButton: copyButtonEn,\n cropper: cropperEn,\n dataTable: dataTableEn,\n datePicker: datePickerEn,\n dialog: dialogEn,\n displayAxis: displayAxisEn,\n fileUpload: fileUploadEn,\n filterChips: filterChipsEn,\n imageUploadField: imageUploadFieldEn,\n inlineEdit: inlineEditEn,\n keyboardShortcuts: keyboardShortcutsEn,\n kanban: kanbanEn,\n keyValue: keyValueEn,\n markdownEditor: markdownEditorEn,\n mention: mentionEn,\n pagination: paginationEn,\n phoneInput: phoneInputEn,\n rating: ratingEn,\n routeTabs: routeTabsEn,\n scrollSpy: scrollSpyEn,\n searchFilterBar: searchFilterBarEn,\n sheet: sheetEn,\n shell: shellEn,\n spinner: spinnerEn,\n stepper: stepperEn,\n tablePagination: tablePaginationEn,\n tagsInput: tagsInputEn,\n timePicker: timePickerEn,\n toast: toastEn,\n tour: tourEn\n};\n\n/** Hình dạng của một bảng chữ đầy đủ. Suy từ bảng tiếng Anh, không viết tay lần hai. */\nexport type ComitorMessages = typeof comitorMessagesEn;\n\n/** Bảng tiếng Việt — phải phủ ĐỦ mọi khoá của bảng tiếng Anh. */\nexport const comitorMessagesVi: ComitorMessages = {\n actionBar: actionBarVi,\n avatarGroup: avatarGroupVi,\n badgeOverflow: badgeOverflowVi,\n banner: bannerVi,\n breadcrumb: breadcrumbVi,\n calendar: calendarVi,\n carousel: carouselVi,\n combobox: comboboxVi,\n command: commandVi,\n commandPalette: commandPaletteVi,\n confirmDialog: confirmDialogVi,\n contrast: contrastVi,\n copyButton: copyButtonVi,\n cropper: cropperVi,\n dataTable: dataTableVi,\n datePicker: datePickerVi,\n dialog: dialogVi,\n displayAxis: displayAxisVi,\n fileUpload: fileUploadVi,\n filterChips: filterChipsVi,\n imageUploadField: imageUploadFieldVi,\n inlineEdit: inlineEditVi,\n keyboardShortcuts: keyboardShortcutsVi,\n kanban: kanbanVi,\n keyValue: keyValueVi,\n markdownEditor: markdownEditorVi,\n mention: mentionVi,\n pagination: paginationVi,\n phoneInput: phoneInputVi,\n rating: ratingVi,\n routeTabs: routeTabsVi,\n scrollSpy: scrollSpyVi,\n searchFilterBar: searchFilterBarVi,\n sheet: sheetVi,\n shell: shellVi,\n spinner: spinnerVi,\n stepper: stepperVi,\n tablePagination: tablePaginationVi,\n tagsInput: tagsInputVi,\n timePicker: timePickerVi,\n toast: toastVi,\n tour: tourVi\n};\n\n/** Mọi bảng dựng sẵn, tra theo ngôn ngữ. */\nexport const COMITOR_MESSAGES: Record<ComitorLanguage, ComitorMessages> = {\n en: comitorMessagesEn,\n vi: comitorMessagesVi\n};\n\n/**\n * Ghi đè MỘT PHẦN: theo namespace, và trong mỗi namespace theo khoá. Dùng để đổi vài chữ theo\n * nghiệp vụ (\"Không gian làm việc\" → \"Công ty\"), hoặc để cấp nguyên một bảng cho ngôn ngữ thứ ba.\n */\nexport type ComitorMessagesOverride = {\n [K in keyof ComitorMessages]?: Partial<ComitorMessages[K]>;\n};\n\n/**\n * Trộn phần ghi đè vào một bảng đầy đủ — từng namespace một, nông ở cấp khoá. Không đụng tới bảng\n * gốc (trả về object mới), và namespace không được ghi đè giữ nguyên tham chiếu.\n */\nexport function mergeComitorMessages(base: ComitorMessages, override?: ComitorMessagesOverride): ComitorMessages {\n if (!override) return base;\n const merged = { ...base } as Record<string, object>;\n for (const key of Object.keys(override) as Array<keyof ComitorMessages>) {\n const part = override[key];\n if (part) merged[key] = { ...base[key], ...part };\n }\n return merged as ComitorMessages;\n}\n\n/**\n * Bảng chữ cho một `locale` (+ phần ghi đè) — bản THUẦN của những gì `ComitorLocaleProvider` làm,\n * dành cho nơi không có context: Server Component, email, toast bắn ngoài cây React.\n */\nexport function getComitorMessages(locale?: string | null, override?: ComitorMessagesOverride): ComitorMessages {\n return mergeComitorMessages(COMITOR_MESSAGES[getComitorLanguage(locale)], override);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/i18n/messages.ts"],"sourcesContent":["/**\n * Bảng CHỮ của cả gói — module THUẦN (không directive, không hook), Server Component đọc thẳng\n * được (`verify:directives`, phép kiểm 2 và 3).\n *\n * Cùng khuôn với bảng chuỗi của `DataGrid` (`data-grid/messages.ts`), nay áp cho MỌI component:\n * · `comitorMessagesEn` là BẢN GỐC định nghĩa hình dạng ({@link ComitorMessages}). Tiếng Anh\n * là mặc định từ `3.0.0` — gói phục vụ cả app quốc tế, không chỉ app Comitor.\n * · `comitorMessagesVi` chú thích `: ComitorMessages`, nên thiếu một khoá là typecheck đỏ\n * ngay — không có đường nào để một chuỗi `undefined` lặng lẽ lọt ra giao diện.\n *\n * Mỗi namespace là MỘT component (hoặc một cụm component dùng chung chữ, vd `shell`). Chuỗi có\n * tham số viết thành HÀM, không phải mẫu có chỗ trống — trật tự từ quanh con số khác nhau theo ngôn\n * ngữ, nên mọi cách để gói tự nối chuỗi đều là chỗ chắc chắn dịch sai.\n *\n * Thêm ngôn ngữ thứ ba: app KHÔNG phải sửa gói — truyền cả một bảng qua prop `messages` của\n * `ComitorLocaleProvider` (trải `comitorMessagesEn` ra rồi dịch từng namespace).\n */\nimport { type ComitorLanguage, getComitorLanguage } from \"./locale.js\";\nimport { actionBarEn, actionBarVi } from \"./namespaces/action-bar.js\";\nimport { avatarGroupEn, avatarGroupVi } from \"./namespaces/avatar-group.js\";\nimport { badgeOverflowEn, badgeOverflowVi } from \"./namespaces/badge-overflow.js\";\nimport { bannerEn, bannerVi } from \"./namespaces/banner.js\";\nimport { breadcrumbEn, breadcrumbVi } from \"./namespaces/breadcrumb.js\";\nimport { calendarEn, calendarVi } from \"./namespaces/calendar.js\";\nimport { carouselEn, carouselVi } from \"./namespaces/carousel.js\";\nimport { chatEn, chatVi } from \"./namespaces/chat.js\";\nimport { comboboxEn, comboboxVi } from \"./namespaces/combobox.js\";\nimport { commandEn, commandVi } from \"./namespaces/command.js\";\nimport { commandPaletteEn, commandPaletteVi } from \"./namespaces/command-palette.js\";\nimport { confirmDialogEn, confirmDialogVi } from \"./namespaces/confirm-dialog.js\";\nimport { contrastEn, contrastVi } from \"./namespaces/contrast.js\";\nimport { copyButtonEn, copyButtonVi } from \"./namespaces/copy-button.js\";\nimport { cropperEn, cropperVi } from \"./namespaces/cropper.js\";\nimport { dataTableEn, dataTableVi } from \"./namespaces/data-table.js\";\nimport { datePickerEn, datePickerVi } from \"./namespaces/date-picker.js\";\nimport { dialogEn, dialogVi } from \"./namespaces/dialog.js\";\nimport { displayAxisEn, displayAxisVi } from \"./namespaces/display-axis.js\";\nimport { fileUploadEn, fileUploadVi } from \"./namespaces/file-upload.js\";\nimport { filterChipsEn, filterChipsVi } from \"./namespaces/filter-chips.js\";\nimport { ganttEn, ganttVi } from \"./namespaces/gantt.js\";\nimport { imageUploadFieldEn, imageUploadFieldVi } from \"./namespaces/image-upload-field.js\";\nimport { inlineEditEn, inlineEditVi } from \"./namespaces/inline-edit.js\";\nimport { kanbanEn, kanbanVi } from \"./namespaces/kanban.js\";\nimport { keyValueEn, keyValueVi } from \"./namespaces/key-value.js\";\nimport { keyboardShortcutsEn, keyboardShortcutsVi } from \"./namespaces/keyboard-shortcuts.js\";\nimport { markdownEditorEn, markdownEditorVi } from \"./namespaces/markdown-editor.js\";\nimport { mentionEn, mentionVi } from \"./namespaces/mention.js\";\nimport { paginationEn, paginationVi } from \"./namespaces/pagination.js\";\nimport { phoneInputEn, phoneInputVi } from \"./namespaces/phone-input.js\";\nimport { ratingEn, ratingVi } from \"./namespaces/rating.js\";\nimport { routeTabsEn, routeTabsVi } from \"./namespaces/route-tabs.js\";\nimport { scrollSpyEn, scrollSpyVi } from \"./namespaces/scroll-spy.js\";\nimport { searchFilterBarEn, searchFilterBarVi } from \"./namespaces/search-filter-bar.js\";\nimport { sheetEn, sheetVi } from \"./namespaces/sheet.js\";\nimport { shellEn, shellVi } from \"./namespaces/shell.js\";\nimport { spinnerEn, spinnerVi } from \"./namespaces/spinner.js\";\nimport { stepperEn, stepperVi } from \"./namespaces/stepper.js\";\nimport { tablePaginationEn, tablePaginationVi } from \"./namespaces/table-pagination.js\";\nimport { tagsInputEn, tagsInputVi } from \"./namespaces/tags-input.js\";\nimport { timePickerEn, timePickerVi } from \"./namespaces/time-picker.js\";\nimport { toastEn, toastVi } from \"./namespaces/toast.js\";\nimport { tourEn, tourVi } from \"./namespaces/tour.js\";\nimport { treeViewEn, treeViewVi } from \"./namespaces/tree-view.js\";\n\n/** Bảng tiếng Anh — BẢN GỐC, định nghĩa hình dạng của mọi bảng khác. */\nexport const comitorMessagesEn = {\n actionBar: actionBarEn,\n avatarGroup: avatarGroupEn,\n badgeOverflow: badgeOverflowEn,\n banner: bannerEn,\n breadcrumb: breadcrumbEn,\n calendar: calendarEn,\n carousel: carouselEn,\n chat: chatEn,\n combobox: comboboxEn,\n command: commandEn,\n commandPalette: commandPaletteEn,\n confirmDialog: confirmDialogEn,\n contrast: contrastEn,\n copyButton: copyButtonEn,\n cropper: cropperEn,\n dataTable: dataTableEn,\n datePicker: datePickerEn,\n dialog: dialogEn,\n displayAxis: displayAxisEn,\n fileUpload: fileUploadEn,\n filterChips: filterChipsEn,\n gantt: ganttEn,\n imageUploadField: imageUploadFieldEn,\n inlineEdit: inlineEditEn,\n keyboardShortcuts: keyboardShortcutsEn,\n kanban: kanbanEn,\n keyValue: keyValueEn,\n markdownEditor: markdownEditorEn,\n mention: mentionEn,\n pagination: paginationEn,\n phoneInput: phoneInputEn,\n rating: ratingEn,\n routeTabs: routeTabsEn,\n scrollSpy: scrollSpyEn,\n searchFilterBar: searchFilterBarEn,\n sheet: sheetEn,\n shell: shellEn,\n spinner: spinnerEn,\n stepper: stepperEn,\n tablePagination: tablePaginationEn,\n tagsInput: tagsInputEn,\n timePicker: timePickerEn,\n toast: toastEn,\n tour: tourEn,\n treeView: treeViewEn\n};\n\n/** Hình dạng của một bảng chữ đầy đủ. Suy từ bảng tiếng Anh, không viết tay lần hai. */\nexport type ComitorMessages = typeof comitorMessagesEn;\n\n/** Bảng tiếng Việt — phải phủ ĐỦ mọi khoá của bảng tiếng Anh. */\nexport const comitorMessagesVi: ComitorMessages = {\n actionBar: actionBarVi,\n avatarGroup: avatarGroupVi,\n badgeOverflow: badgeOverflowVi,\n banner: bannerVi,\n breadcrumb: breadcrumbVi,\n calendar: calendarVi,\n carousel: carouselVi,\n chat: chatVi,\n combobox: comboboxVi,\n command: commandVi,\n commandPalette: commandPaletteVi,\n confirmDialog: confirmDialogVi,\n contrast: contrastVi,\n copyButton: copyButtonVi,\n cropper: cropperVi,\n dataTable: dataTableVi,\n datePicker: datePickerVi,\n dialog: dialogVi,\n displayAxis: displayAxisVi,\n fileUpload: fileUploadVi,\n filterChips: filterChipsVi,\n gantt: ganttVi,\n imageUploadField: imageUploadFieldVi,\n inlineEdit: inlineEditVi,\n keyboardShortcuts: keyboardShortcutsVi,\n kanban: kanbanVi,\n keyValue: keyValueVi,\n markdownEditor: markdownEditorVi,\n mention: mentionVi,\n pagination: paginationVi,\n phoneInput: phoneInputVi,\n rating: ratingVi,\n routeTabs: routeTabsVi,\n scrollSpy: scrollSpyVi,\n searchFilterBar: searchFilterBarVi,\n sheet: sheetVi,\n shell: shellVi,\n spinner: spinnerVi,\n stepper: stepperVi,\n tablePagination: tablePaginationVi,\n tagsInput: tagsInputVi,\n timePicker: timePickerVi,\n toast: toastVi,\n tour: tourVi,\n treeView: treeViewVi\n};\n\n/** Mọi bảng dựng sẵn, tra theo ngôn ngữ. */\nexport const COMITOR_MESSAGES: Record<ComitorLanguage, ComitorMessages> = {\n en: comitorMessagesEn,\n vi: comitorMessagesVi\n};\n\n/**\n * Ghi đè MỘT PHẦN: theo namespace, và trong mỗi namespace theo khoá. Dùng để đổi vài chữ theo\n * nghiệp vụ (\"Không gian làm việc\" → \"Công ty\"), hoặc để cấp nguyên một bảng cho ngôn ngữ thứ ba.\n */\nexport type ComitorMessagesOverride = {\n [K in keyof ComitorMessages]?: Partial<ComitorMessages[K]>;\n};\n\n/**\n * Trộn phần ghi đè vào một bảng đầy đủ — từng namespace một, nông ở cấp khoá. Không đụng tới bảng\n * gốc (trả về object mới), và namespace không được ghi đè giữ nguyên tham chiếu.\n */\nexport function mergeComitorMessages(base: ComitorMessages, override?: ComitorMessagesOverride): ComitorMessages {\n if (!override) return base;\n const merged = { ...base } as Record<string, object>;\n for (const key of Object.keys(override) as Array<keyof ComitorMessages>) {\n const part = override[key];\n if (part) merged[key] = { ...base[key], ...part };\n }\n return merged as ComitorMessages;\n}\n\n/**\n * Bảng chữ cho một `locale` (+ phần ghi đè) — bản THUẦN của những gì `ComitorLocaleProvider` làm,\n * dành cho nơi không có context: Server Component, email, toast bắn ngoài cây React.\n */\nexport function getComitorMessages(locale?: string | null, override?: ComitorMessagesOverride): ComitorMessages {\n return mergeComitorMessages(COMITOR_MESSAGES[getComitorLanguage(locale)], override);\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,8 @@
1
+ import { ChatLabels } from '../../chat/chat-constants.js';
2
+ import 'react';
3
+
4
+ /** Chữ của khung hội thoại (`@comitor/ui/chat`). Hình dạng + chú thích từng khoá: `ChatLabels`. */
5
+ declare const chatEn: ChatLabels;
6
+ declare const chatVi: ChatLabels;
7
+
8
+ export { chatEn, chatVi };
@@ -0,0 +1,47 @@
1
+ const chatEn = {
2
+ log: "Conversation",
3
+ scrollToLatest: "Scroll to latest message",
4
+ aiGenerated: "AI-generated",
5
+ aiGeneratedHint: "Generated by AI. Check important details before relying on them.",
6
+ you: "You",
7
+ assistant: "Assistant",
8
+ thinking: "Thinking\u2026",
9
+ stepsSummary: (done, total) => `${done} of ${total} ${total === 1 ? "step" : "steps"}`,
10
+ stepPending: "Pending",
11
+ stepRunning: "In progress",
12
+ stepDone: "Done",
13
+ stepError: "Failed",
14
+ sources: (count) => `${count} ${count === 1 ? "source" : "sources"}`,
15
+ citation: (index, title) => `Source ${index}: ${title}`,
16
+ opensInNewTab: "(opens in a new tab)",
17
+ composerLabel: "Message",
18
+ composerPlaceholder: "Ask anything\u2026 Type @ to mention",
19
+ send: "Send",
20
+ stop: "Stop generating"
21
+ };
22
+ const chatVi = {
23
+ log: "Cu\u1ED9c tr\xF2 chuy\u1EC7n",
24
+ scrollToLatest: "Cu\u1ED9n t\u1EDBi tin m\u1EDBi nh\u1EA5t",
25
+ aiGenerated: "Do AI t\u1EA1o",
26
+ aiGeneratedHint: "N\u1ED9i dung do AI t\u1EA1o. H\xE3y ki\u1EC3m tra c\xE1c chi ti\u1EBFt quan tr\u1ECDng tr\u01B0\u1EDBc khi d\xF9ng.",
27
+ you: "B\u1EA1n",
28
+ assistant: "Tr\u1EE3 l\xFD",
29
+ thinking: "\u0110ang suy ngh\u0129\u2026",
30
+ stepsSummary: (done, total) => `${done}/${total} b\u01B0\u1EDBc`,
31
+ stepPending: "Ch\u1EDD",
32
+ stepRunning: "\u0110ang l\xE0m",
33
+ stepDone: "Xong",
34
+ stepError: "L\u1ED7i",
35
+ sources: (count) => `${count} ngu\u1ED3n`,
36
+ citation: (index, title) => `Ngu\u1ED3n ${index}: ${title}`,
37
+ opensInNewTab: "(m\u1EDF trong th\u1EBB m\u1EDBi)",
38
+ composerLabel: "Tin nh\u1EAFn",
39
+ composerPlaceholder: "H\u1ECFi b\u1EA5t c\u1EE9 \u0111i\u1EC1u g\xEC\u2026 G\xF5 @ \u0111\u1EC3 nh\u1EAFc t\xEAn",
40
+ send: "G\u1EEDi",
41
+ stop: "D\u1EEBng tr\u1EA3 l\u1EDDi"
42
+ };
43
+ export {
44
+ chatEn,
45
+ chatVi
46
+ };
47
+ //# sourceMappingURL=chat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/i18n/namespaces/chat.ts"],"sourcesContent":["import type { ChatLabels } from \"../../chat/chat-constants.js\";\n\n/** Chữ của khung hội thoại (`@comitor/ui/chat`). Hình dạng + chú thích từng khoá: `ChatLabels`. */\nexport const chatEn: ChatLabels = {\n log: \"Conversation\",\n scrollToLatest: \"Scroll to latest message\",\n aiGenerated: \"AI-generated\",\n aiGeneratedHint: \"Generated by AI. Check important details before relying on them.\",\n you: \"You\",\n assistant: \"Assistant\",\n thinking: \"Thinking…\",\n stepsSummary: (done, total) => `${done} of ${total} ${total === 1 ? \"step\" : \"steps\"}`,\n stepPending: \"Pending\",\n stepRunning: \"In progress\",\n stepDone: \"Done\",\n stepError: \"Failed\",\n sources: (count) => `${count} ${count === 1 ? \"source\" : \"sources\"}`,\n citation: (index, title) => `Source ${index}: ${title}`,\n opensInNewTab: \"(opens in a new tab)\",\n composerLabel: \"Message\",\n composerPlaceholder: \"Ask anything… Type @ to mention\",\n send: \"Send\",\n stop: \"Stop generating\"\n};\n\nexport const chatVi: ChatLabels = {\n log: \"Cuộc trò chuyện\",\n scrollToLatest: \"Cuộn tới tin mới nhất\",\n aiGenerated: \"Do AI tạo\",\n aiGeneratedHint: \"Nội dung do AI tạo. Hãy kiểm tra các chi tiết quan trọng trước khi dùng.\",\n you: \"Bạn\",\n assistant: \"Trợ lý\",\n thinking: \"Đang suy nghĩ…\",\n stepsSummary: (done, total) => `${done}/${total} bước`,\n stepPending: \"Chờ\",\n stepRunning: \"Đang làm\",\n stepDone: \"Xong\",\n stepError: \"Lỗi\",\n sources: (count) => `${count} nguồn`,\n citation: (index, title) => `Nguồn ${index}: ${title}`,\n opensInNewTab: \"(mở trong thẻ mới)\",\n composerLabel: \"Tin nhắn\",\n composerPlaceholder: \"Hỏi bất cứ điều gì… Gõ @ để nhắc tên\",\n send: \"Gửi\",\n stop: \"Dừng trả lời\"\n};\n"],"mappings":"AAGO,MAAM,SAAqB;AAAA,EAChC,KAAK;AAAA,EACL,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,KAAK;AAAA,EACL,WAAW;AAAA,EACX,UAAU;AAAA,EACV,cAAc,CAAC,MAAM,UAAU,GAAG,IAAI,OAAO,KAAK,IAAI,UAAU,IAAI,SAAS,OAAO;AAAA,EACpF,aAAa;AAAA,EACb,aAAa;AAAA,EACb,UAAU;AAAA,EACV,WAAW;AAAA,EACX,SAAS,CAAC,UAAU,GAAG,KAAK,IAAI,UAAU,IAAI,WAAW,SAAS;AAAA,EAClE,UAAU,CAAC,OAAO,UAAU,UAAU,KAAK,KAAK,KAAK;AAAA,EACrD,eAAe;AAAA,EACf,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,MAAM;AAAA,EACN,MAAM;AACR;AAEO,MAAM,SAAqB;AAAA,EAChC,KAAK;AAAA,EACL,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,iBAAiB;AAAA,EACjB,KAAK;AAAA,EACL,WAAW;AAAA,EACX,UAAU;AAAA,EACV,cAAc,CAAC,MAAM,UAAU,GAAG,IAAI,IAAI,KAAK;AAAA,EAC/C,aAAa;AAAA,EACb,aAAa;AAAA,EACb,UAAU;AAAA,EACV,WAAW;AAAA,EACX,SAAS,CAAC,UAAU,GAAG,KAAK;AAAA,EAC5B,UAAU,CAAC,OAAO,UAAU,cAAS,KAAK,KAAK,KAAK;AAAA,EACpD,eAAe;AAAA,EACf,eAAe;AAAA,EACf,qBAAqB;AAAA,EACrB,MAAM;AAAA,EACN,MAAM;AACR;","names":[]}
@@ -0,0 +1,10 @@
1
+ import { GanttLabels } from '../../components/composite/gantt-constants.js';
2
+
3
+ /**
4
+ * Chữ của `Gantt`. Hình dạng + chú thích từng khoá: `GanttLabels`. Ngày đưa vào các hàm ở đây ĐÃ
5
+ * được định dạng theo `locale` của provider (`Intl.DateTimeFormat`) — hàm chỉ ghép câu.
6
+ */
7
+ declare const ganttEn: GanttLabels;
8
+ declare const ganttVi: GanttLabels;
9
+
10
+ export { ganttEn, ganttVi };
@@ -0,0 +1,57 @@
1
+ const ganttEn = {
2
+ label: "Timeline",
3
+ sidebarTitle: "Name",
4
+ scaleLabel: "Zoom",
5
+ scaleDay: "Days",
6
+ scaleWeek: "Weeks",
7
+ scaleMonth: "Months",
8
+ scaleQuarter: "Quarters",
9
+ scaleYear: "Years",
10
+ today: "Today",
11
+ quarter: (quarter) => `Q${quarter}`,
12
+ itemRange: (start, end, days) => `${start} \u2013 ${end}, ${days} ${days === 1 ? "day" : "days"}`,
13
+ milestoneDate: (date) => `Milestone on ${date}`,
14
+ progress: (percent) => `${percent}% complete`,
15
+ unscheduled: "No dates",
16
+ critical: "On the critical path",
17
+ conflict: "Starts before a task it depends on",
18
+ instructions: "Use Up and Down arrows to move between rows. Left and Right arrows move the dates by one day; hold Shift to move by a larger step. Alt with Left or Right changes the end date; Alt and Shift changes the start date. Enter opens the item, Space expands or collapses a group.",
19
+ rescheduled: (title, range) => `${title}: ${range}`,
20
+ expand: "Expand",
21
+ collapse: "Collapse",
22
+ scrollToItem: (title) => `Scroll to ${title}`,
23
+ linkHandle: (title) => `Drag to connect ${title} to the next task`,
24
+ dependency: (from, to) => `${from} \u2192 ${to}`,
25
+ scheduleHint: "Click to schedule"
26
+ };
27
+ const ganttVi = {
28
+ label: "Tr\u1EE5c th\u1EDDi gian",
29
+ sidebarTitle: "T\xEAn",
30
+ scaleLabel: "Thu ph\xF3ng",
31
+ scaleDay: "Ng\xE0y",
32
+ scaleWeek: "Tu\u1EA7n",
33
+ scaleMonth: "Th\xE1ng",
34
+ scaleQuarter: "Qu\xFD",
35
+ scaleYear: "N\u0103m",
36
+ today: "H\xF4m nay",
37
+ quarter: (quarter) => `Q${quarter}`,
38
+ itemRange: (start, end, days) => `${start} \u2013 ${end}, ${days} ng\xE0y`,
39
+ milestoneDate: (date) => `M\u1ED1c ng\xE0y ${date}`,
40
+ progress: (percent) => `Ho\xE0n th\xE0nh ${percent}%`,
41
+ unscheduled: "Ch\u01B0a c\xF3 ng\xE0y",
42
+ critical: "N\u1EB1m tr\xEAn \u0111\u01B0\u1EDDng g\u0103ng",
43
+ conflict: "B\u1EAFt \u0111\u1EA7u tr\u01B0\u1EDBc khi vi\u1EC7c ph\u1EE5 thu\u1ED9c xong",
44
+ instructions: "D\xF9ng ph\xEDm m\u0169i t\xEAn l\xEAn, xu\u1ED1ng \u0111\u1EC3 chuy\u1EC3n d\xF2ng. M\u0169i t\xEAn tr\xE1i, ph\u1EA3i d\u1EDDi ng\xE0y \u0111i m\u1ED9t ng\xE0y; gi\u1EEF Shift \u0111\u1EC3 d\u1EDDi m\u1ED9t b\u01B0\u1EDBc l\u1EDBn. Alt c\xF9ng m\u0169i t\xEAn tr\xE1i, ph\u1EA3i \u0111\u1ED5i ng\xE0y k\u1EBFt th\xFAc; Alt v\xE0 Shift \u0111\u1ED5i ng\xE0y b\u1EAFt \u0111\u1EA7u. Enter m\u1EDF m\u1EE5c, Space m\u1EDF ho\u1EB7c thu m\u1ED9t nh\xF3m.",
45
+ rescheduled: (title, range) => `${title}: ${range}`,
46
+ expand: "M\u1EDF r\u1ED9ng",
47
+ collapse: "Thu g\u1ECDn",
48
+ scrollToItem: (title) => `Cu\u1ED9n t\u1EDBi ${title}`,
49
+ linkHandle: (title) => `K\xE9o \u0111\u1EC3 n\u1ED1i ${title} v\u1EDBi vi\u1EC7c sau`,
50
+ dependency: (from, to) => `${from} \u2192 ${to}`,
51
+ scheduleHint: "B\u1EA5m \u0111\u1EC3 x\u1EBFp l\u1ECBch"
52
+ };
53
+ export {
54
+ ganttEn,
55
+ ganttVi
56
+ };
57
+ //# sourceMappingURL=gantt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/i18n/namespaces/gantt.ts"],"sourcesContent":["import type { GanttLabels } from \"../../components/composite/gantt-constants.js\";\n\n/**\n * Chữ của `Gantt`. Hình dạng + chú thích từng khoá: `GanttLabels`. Ngày đưa vào các hàm ở đây ĐÃ\n * được định dạng theo `locale` của provider (`Intl.DateTimeFormat`) — hàm chỉ ghép câu.\n */\nexport const ganttEn: GanttLabels = {\n label: \"Timeline\",\n sidebarTitle: \"Name\",\n scaleLabel: \"Zoom\",\n scaleDay: \"Days\",\n scaleWeek: \"Weeks\",\n scaleMonth: \"Months\",\n scaleQuarter: \"Quarters\",\n scaleYear: \"Years\",\n today: \"Today\",\n quarter: (quarter) => `Q${quarter}`,\n itemRange: (start, end, days) => `${start} – ${end}, ${days} ${days === 1 ? \"day\" : \"days\"}`,\n milestoneDate: (date) => `Milestone on ${date}`,\n progress: (percent) => `${percent}% complete`,\n unscheduled: \"No dates\",\n critical: \"On the critical path\",\n conflict: \"Starts before a task it depends on\",\n instructions:\n \"Use Up and Down arrows to move between rows. Left and Right arrows move the dates by one day; hold Shift to move by a larger step. Alt with Left or Right changes the end date; Alt and Shift changes the start date. Enter opens the item, Space expands or collapses a group.\",\n rescheduled: (title, range) => `${title}: ${range}`,\n expand: \"Expand\",\n collapse: \"Collapse\",\n scrollToItem: (title) => `Scroll to ${title}`,\n linkHandle: (title) => `Drag to connect ${title} to the next task`,\n dependency: (from, to) => `${from} → ${to}`,\n scheduleHint: \"Click to schedule\"\n};\n\nexport const ganttVi: GanttLabels = {\n label: \"Trục thời gian\",\n sidebarTitle: \"Tên\",\n scaleLabel: \"Thu phóng\",\n scaleDay: \"Ngày\",\n scaleWeek: \"Tuần\",\n scaleMonth: \"Tháng\",\n scaleQuarter: \"Quý\",\n scaleYear: \"Năm\",\n today: \"Hôm nay\",\n quarter: (quarter) => `Q${quarter}`,\n itemRange: (start, end, days) => `${start} – ${end}, ${days} ngày`,\n milestoneDate: (date) => `Mốc ngày ${date}`,\n progress: (percent) => `Hoàn thành ${percent}%`,\n unscheduled: \"Chưa có ngày\",\n critical: \"Nằm trên đường găng\",\n conflict: \"Bắt đầu trước khi việc phụ thuộc xong\",\n instructions:\n \"Dùng phím mũi tên lên, xuống để chuyển dòng. Mũi tên trái, phải dời ngày đi một ngày; giữ Shift để dời một bước lớn. Alt cùng mũi tên trái, phải đổi ngày kết thúc; Alt và Shift đổi ngày bắt đầu. Enter mở mục, Space mở hoặc thu một nhóm.\",\n rescheduled: (title, range) => `${title}: ${range}`,\n expand: \"Mở rộng\",\n collapse: \"Thu gọn\",\n scrollToItem: (title) => `Cuộn tới ${title}`,\n linkHandle: (title) => `Kéo để nối ${title} với việc sau`,\n dependency: (from, to) => `${from} → ${to}`,\n scheduleHint: \"Bấm để xếp lịch\"\n};\n"],"mappings":"AAMO,MAAM,UAAuB;AAAA,EAClC,OAAO;AAAA,EACP,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,WAAW;AAAA,EACX,OAAO;AAAA,EACP,SAAS,CAAC,YAAY,IAAI,OAAO;AAAA,EACjC,WAAW,CAAC,OAAO,KAAK,SAAS,GAAG,KAAK,WAAM,GAAG,KAAK,IAAI,IAAI,SAAS,IAAI,QAAQ,MAAM;AAAA,EAC1F,eAAe,CAAC,SAAS,gBAAgB,IAAI;AAAA,EAC7C,UAAU,CAAC,YAAY,GAAG,OAAO;AAAA,EACjC,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,cACE;AAAA,EACF,aAAa,CAAC,OAAO,UAAU,GAAG,KAAK,KAAK,KAAK;AAAA,EACjD,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,cAAc,CAAC,UAAU,aAAa,KAAK;AAAA,EAC3C,YAAY,CAAC,UAAU,mBAAmB,KAAK;AAAA,EAC/C,YAAY,CAAC,MAAM,OAAO,GAAG,IAAI,WAAM,EAAE;AAAA,EACzC,cAAc;AAChB;AAEO,MAAM,UAAuB;AAAA,EAClC,OAAO;AAAA,EACP,cAAc;AAAA,EACd,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,WAAW;AAAA,EACX,OAAO;AAAA,EACP,SAAS,CAAC,YAAY,IAAI,OAAO;AAAA,EACjC,WAAW,CAAC,OAAO,KAAK,SAAS,GAAG,KAAK,WAAM,GAAG,KAAK,IAAI;AAAA,EAC3D,eAAe,CAAC,SAAS,oBAAY,IAAI;AAAA,EACzC,UAAU,CAAC,YAAY,oBAAc,OAAO;AAAA,EAC5C,aAAa;AAAA,EACb,UAAU;AAAA,EACV,UAAU;AAAA,EACV,cACE;AAAA,EACF,aAAa,CAAC,OAAO,UAAU,GAAG,KAAK,KAAK,KAAK;AAAA,EACjD,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,cAAc,CAAC,UAAU,sBAAY,KAAK;AAAA,EAC1C,YAAY,CAAC,UAAU,gCAAc,KAAK;AAAA,EAC1C,YAAY,CAAC,MAAM,OAAO,GAAG,IAAI,WAAM,EAAE;AAAA,EACzC,cAAc;AAChB;","names":[]}
@@ -0,0 +1,8 @@
1
+ import { TreeViewLabels } from '../../components/composite/tree-view-constants.js';
2
+ import 'react';
3
+
4
+ /** Chữ của `TreeView`. Hình dạng + chú thích từng khoá: `TreeViewLabels`. */
5
+ declare const treeViewEn: TreeViewLabels;
6
+ declare const treeViewVi: TreeViewLabels;
7
+
8
+ export { treeViewEn, treeViewVi };
@@ -0,0 +1,21 @@
1
+ const treeViewEn = {
2
+ label: "Tree",
3
+ nameHeader: "Name",
4
+ root: "the top level",
5
+ instructions: "Use Up and Down arrows to move between items, Right to expand and Left to collapse. Tab indents the item under the one above it, Shift+Tab outdents it. Alt with Up or Down moves the item among its siblings. Enter opens the item.",
6
+ movedInto: (name, parent, position, total) => `${name} moved into ${parent}, position ${position} of ${total}.`,
7
+ movedTo: (name, position, total) => `${name} moved to position ${position} of ${total}.`
8
+ };
9
+ const treeViewVi = {
10
+ label: "C\xE2y",
11
+ nameHeader: "T\xEAn",
12
+ root: "c\u1EA5p ngo\xE0i c\xF9ng",
13
+ instructions: "D\xF9ng ph\xEDm m\u0169i t\xEAn l\xEAn, xu\u1ED1ng \u0111\u1EC3 chuy\u1EC3n m\u1EE5c, m\u0169i t\xEAn ph\u1EA3i \u0111\u1EC3 m\u1EDF v\xE0 m\u0169i t\xEAn tr\xE1i \u0111\u1EC3 thu nh\xE1nh. Tab \u0111\u01B0a m\u1EE5c v\xE0o l\xE0m con c\u1EE7a m\u1EE5c ph\xEDa tr\xEAn, Shift+Tab \u0111\u01B0a m\u1EE5c ra ngo\xE0i m\u1ED9t c\u1EA5p. Alt c\xF9ng m\u0169i t\xEAn l\xEAn, xu\u1ED1ng \u0111\u1ED5i ch\u1ED7 m\u1EE5c v\u1EDBi c\xE1c m\u1EE5c c\xF9ng c\u1EA5p. Enter m\u1EDF m\u1EE5c.",
14
+ movedInto: (name, parent, position, total) => `\u0110\xE3 chuy\u1EC3n ${name} v\xE0o ${parent}, v\u1ECB tr\xED ${position} tr\xEAn ${total}.`,
15
+ movedTo: (name, position, total) => `\u0110\xE3 chuy\u1EC3n ${name} t\u1EDBi v\u1ECB tr\xED ${position} tr\xEAn ${total}.`
16
+ };
17
+ export {
18
+ treeViewEn,
19
+ treeViewVi
20
+ };
21
+ //# sourceMappingURL=tree-view.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/i18n/namespaces/tree-view.ts"],"sourcesContent":["import type { TreeViewLabels } from \"../../components/composite/tree-view-constants.js\";\n\n/** Chữ của `TreeView`. Hình dạng + chú thích từng khoá: `TreeViewLabels`. */\nexport const treeViewEn: TreeViewLabels = {\n label: \"Tree\",\n nameHeader: \"Name\",\n root: \"the top level\",\n instructions:\n \"Use Up and Down arrows to move between items, Right to expand and Left to collapse. Tab indents the item under the one above it, Shift+Tab outdents it. Alt with Up or Down moves the item among its siblings. Enter opens the item.\",\n movedInto: (name, parent, position, total) => `${name} moved into ${parent}, position ${position} of ${total}.`,\n movedTo: (name, position, total) => `${name} moved to position ${position} of ${total}.`\n};\n\nexport const treeViewVi: TreeViewLabels = {\n label: \"Cây\",\n nameHeader: \"Tên\",\n root: \"cấp ngoài cùng\",\n instructions:\n \"Dùng phím mũi tên lên, xuống để chuyển mục, mũi tên phải để mở và mũi tên trái để thu nhánh. Tab đưa mục vào làm con của mục phía trên, Shift+Tab đưa mục ra ngoài một cấp. Alt cùng mũi tên lên, xuống đổi chỗ mục với các mục cùng cấp. Enter mở mục.\",\n movedInto: (name, parent, position, total) => `Đã chuyển ${name} vào ${parent}, vị trí ${position} trên ${total}.`,\n movedTo: (name, position, total) => `Đã chuyển ${name} tới vị trí ${position} trên ${total}.`\n};\n"],"mappings":"AAGO,MAAM,aAA6B;AAAA,EACxC,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,cACE;AAAA,EACF,WAAW,CAAC,MAAM,QAAQ,UAAU,UAAU,GAAG,IAAI,eAAe,MAAM,cAAc,QAAQ,OAAO,KAAK;AAAA,EAC5G,SAAS,CAAC,MAAM,UAAU,UAAU,GAAG,IAAI,sBAAsB,QAAQ,OAAO,KAAK;AACvF;AAEO,MAAM,aAA6B;AAAA,EACxC,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,MAAM;AAAA,EACN,cACE;AAAA,EACF,WAAW,CAAC,MAAM,QAAQ,UAAU,UAAU,0BAAa,IAAI,WAAQ,MAAM,oBAAY,QAAQ,YAAS,KAAK;AAAA,EAC/G,SAAS,CAAC,MAAM,UAAU,UAAU,0BAAa,IAAI,4BAAe,QAAQ,YAAS,KAAK;AAC5F;","names":[]}