nextblogkit 0.6.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 (107) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +951 -0
  3. package/dist/admin/index.cjs +2465 -0
  4. package/dist/admin/index.cjs.map +1 -0
  5. package/dist/admin/index.d.cts +44 -0
  6. package/dist/admin/index.d.ts +44 -0
  7. package/dist/admin/index.js +2438 -0
  8. package/dist/admin/index.js.map +1 -0
  9. package/dist/api/categories.cjs +82 -0
  10. package/dist/api/categories.cjs.map +1 -0
  11. package/dist/api/categories.d.cts +27 -0
  12. package/dist/api/categories.d.ts +27 -0
  13. package/dist/api/categories.js +77 -0
  14. package/dist/api/categories.js.map +1 -0
  15. package/dist/api/media.cjs +113 -0
  16. package/dist/api/media.cjs.map +1 -0
  17. package/dist/api/media.d.cts +22 -0
  18. package/dist/api/media.d.ts +22 -0
  19. package/dist/api/media.js +109 -0
  20. package/dist/api/media.js.map +1 -0
  21. package/dist/api/posts.cjs +103 -0
  22. package/dist/api/posts.cjs.map +1 -0
  23. package/dist/api/posts.d.cts +27 -0
  24. package/dist/api/posts.d.ts +27 -0
  25. package/dist/api/posts.js +98 -0
  26. package/dist/api/posts.js.map +1 -0
  27. package/dist/api/rss.cjs +25 -0
  28. package/dist/api/rss.cjs.map +1 -0
  29. package/dist/api/rss.d.cts +5 -0
  30. package/dist/api/rss.d.ts +5 -0
  31. package/dist/api/rss.js +23 -0
  32. package/dist/api/rss.js.map +1 -0
  33. package/dist/api/settings.cjs +40 -0
  34. package/dist/api/settings.cjs.map +1 -0
  35. package/dist/api/settings.d.cts +17 -0
  36. package/dist/api/settings.d.ts +17 -0
  37. package/dist/api/settings.js +37 -0
  38. package/dist/api/settings.js.map +1 -0
  39. package/dist/api/sitemap.cjs +25 -0
  40. package/dist/api/sitemap.cjs.map +1 -0
  41. package/dist/api/sitemap.d.cts +5 -0
  42. package/dist/api/sitemap.d.ts +5 -0
  43. package/dist/api/sitemap.js +23 -0
  44. package/dist/api/sitemap.js.map +1 -0
  45. package/dist/chunk-4NKOJYWJ.js +68 -0
  46. package/dist/chunk-4NKOJYWJ.js.map +1 -0
  47. package/dist/chunk-4PY224XM.js +103 -0
  48. package/dist/chunk-4PY224XM.js.map +1 -0
  49. package/dist/chunk-64HUVJOZ.js +446 -0
  50. package/dist/chunk-64HUVJOZ.js.map +1 -0
  51. package/dist/chunk-6HKMZOI4.cjs +48 -0
  52. package/dist/chunk-6HKMZOI4.cjs.map +1 -0
  53. package/dist/chunk-A2S32RZN.js +138 -0
  54. package/dist/chunk-A2S32RZN.js.map +1 -0
  55. package/dist/chunk-E2QLTHKN.cjs +70 -0
  56. package/dist/chunk-E2QLTHKN.cjs.map +1 -0
  57. package/dist/chunk-JLPJKNRZ.js +37 -0
  58. package/dist/chunk-JLPJKNRZ.js.map +1 -0
  59. package/dist/chunk-JM7QRXXK.js +330 -0
  60. package/dist/chunk-JM7QRXXK.js.map +1 -0
  61. package/dist/chunk-KDZER3PU.cjs +43 -0
  62. package/dist/chunk-KDZER3PU.cjs.map +1 -0
  63. package/dist/chunk-N5MKAD7J.cjs +109 -0
  64. package/dist/chunk-N5MKAD7J.cjs.map +1 -0
  65. package/dist/chunk-QE4VLQYN.cjs +337 -0
  66. package/dist/chunk-QE4VLQYN.cjs.map +1 -0
  67. package/dist/chunk-R6MO3QIP.js +46 -0
  68. package/dist/chunk-R6MO3QIP.js.map +1 -0
  69. package/dist/chunk-U2ROR6AY.cjs +476 -0
  70. package/dist/chunk-U2ROR6AY.cjs.map +1 -0
  71. package/dist/chunk-ZP5XRVVH.cjs +141 -0
  72. package/dist/chunk-ZP5XRVVH.cjs.map +1 -0
  73. package/dist/cli/index.cjs +1308 -0
  74. package/dist/components/index.cjs +541 -0
  75. package/dist/components/index.cjs.map +1 -0
  76. package/dist/components/index.d.cts +165 -0
  77. package/dist/components/index.d.ts +165 -0
  78. package/dist/components/index.js +527 -0
  79. package/dist/components/index.js.map +1 -0
  80. package/dist/editor/index.cjs +1083 -0
  81. package/dist/editor/index.cjs.map +1 -0
  82. package/dist/editor/index.d.cts +133 -0
  83. package/dist/editor/index.d.ts +133 -0
  84. package/dist/editor/index.js +1051 -0
  85. package/dist/editor/index.js.map +1 -0
  86. package/dist/index-Cgzphklp.d.ts +266 -0
  87. package/dist/index-vjlZDWNr.d.cts +266 -0
  88. package/dist/index.cjs +368 -0
  89. package/dist/index.cjs.map +1 -0
  90. package/dist/index.d.cts +27 -0
  91. package/dist/index.d.ts +27 -0
  92. package/dist/index.js +208 -0
  93. package/dist/index.js.map +1 -0
  94. package/dist/lib/index.cjs +120 -0
  95. package/dist/lib/index.cjs.map +1 -0
  96. package/dist/lib/index.d.cts +4 -0
  97. package/dist/lib/index.d.ts +4 -0
  98. package/dist/lib/index.js +7 -0
  99. package/dist/lib/index.js.map +1 -0
  100. package/dist/styles/admin.css +657 -0
  101. package/dist/styles/blog.css +851 -0
  102. package/dist/styles/editor.css +452 -0
  103. package/dist/styles/globals.css +270 -0
  104. package/dist/styles/prose.css +299 -0
  105. package/dist/types-CBEEBR4A.d.cts +732 -0
  106. package/dist/types-CBEEBR4A.d.ts +732 -0
  107. package/package.json +134 -0
@@ -0,0 +1,1083 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var react = require('react');
5
+ var react$1 = require('@tiptap/react');
6
+ var StarterKit = require('@tiptap/starter-kit');
7
+ var Placeholder = require('@tiptap/extension-placeholder');
8
+ var Link = require('@tiptap/extension-link');
9
+ var Underline = require('@tiptap/extension-underline');
10
+ var Highlight = require('@tiptap/extension-highlight');
11
+ var Typography = require('@tiptap/extension-typography');
12
+ var TaskList = require('@tiptap/extension-task-list');
13
+ var TaskItem = require('@tiptap/extension-task-item');
14
+ var Table = require('@tiptap/extension-table');
15
+ var TableRow = require('@tiptap/extension-table-row');
16
+ var TableCell = require('@tiptap/extension-table-cell');
17
+ var TableHeader = require('@tiptap/extension-table-header');
18
+ var extensionImage = require('@tiptap/extension-image');
19
+ var state = require('@tiptap/pm/state');
20
+ var core = require('@tiptap/core');
21
+ var CodeBlockLowlight = require('@tiptap/extension-code-block');
22
+ var jsxRuntime = require('react/jsx-runtime');
23
+
24
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
25
+
26
+ var StarterKit__default = /*#__PURE__*/_interopDefault(StarterKit);
27
+ var Placeholder__default = /*#__PURE__*/_interopDefault(Placeholder);
28
+ var Link__default = /*#__PURE__*/_interopDefault(Link);
29
+ var Underline__default = /*#__PURE__*/_interopDefault(Underline);
30
+ var Highlight__default = /*#__PURE__*/_interopDefault(Highlight);
31
+ var Typography__default = /*#__PURE__*/_interopDefault(Typography);
32
+ var TaskList__default = /*#__PURE__*/_interopDefault(TaskList);
33
+ var TaskItem__default = /*#__PURE__*/_interopDefault(TaskItem);
34
+ var Table__default = /*#__PURE__*/_interopDefault(Table);
35
+ var TableRow__default = /*#__PURE__*/_interopDefault(TableRow);
36
+ var TableCell__default = /*#__PURE__*/_interopDefault(TableCell);
37
+ var TableHeader__default = /*#__PURE__*/_interopDefault(TableHeader);
38
+ var CodeBlockLowlight__default = /*#__PURE__*/_interopDefault(CodeBlockLowlight);
39
+
40
+ // src/editor/Editor.tsx
41
+ var ImageUpload = extensionImage.Image.extend({
42
+ addOptions() {
43
+ return {
44
+ ...this.parent?.(),
45
+ uploadFn: async (_file) => ({ url: "" }),
46
+ maxSize: 10 * 1024 * 1024,
47
+ allowedTypes: ["image/jpeg", "image/png", "image/gif", "image/webp", "image/svg+xml"]
48
+ };
49
+ },
50
+ addAttributes() {
51
+ return {
52
+ ...this.parent?.(),
53
+ loading: {
54
+ default: false,
55
+ renderHTML: (attributes) => {
56
+ if (!attributes.loading) return {};
57
+ return { "data-loading": "true" };
58
+ }
59
+ },
60
+ width: { default: null },
61
+ height: { default: null },
62
+ caption: {
63
+ default: null,
64
+ renderHTML: (attributes) => {
65
+ if (!attributes.caption) return {};
66
+ return { "data-caption": attributes.caption };
67
+ }
68
+ }
69
+ };
70
+ },
71
+ addCommands() {
72
+ return {
73
+ ...this.parent?.(),
74
+ uploadImage: (file) => ({ commands, editor }) => {
75
+ const opts = this.options;
76
+ const { uploadFn, maxSize, allowedTypes } = opts;
77
+ if (maxSize && file.size > maxSize) {
78
+ console.error(`File too large: ${file.size} > ${maxSize}`);
79
+ return false;
80
+ }
81
+ if (allowedTypes && !allowedTypes.includes(file.type)) {
82
+ console.error(`File type not allowed: ${file.type}`);
83
+ return false;
84
+ }
85
+ const placeholderUrl = URL.createObjectURL(file);
86
+ commands.insertContent({
87
+ type: "image",
88
+ attrs: { src: placeholderUrl, loading: true, alt: file.name }
89
+ });
90
+ uploadFn(file).then((result) => {
91
+ const { state } = editor;
92
+ const { doc } = state;
93
+ let pos = null;
94
+ doc.descendants((node, nodePos) => {
95
+ if (node.type.name === "image" && node.attrs.src === placeholderUrl) {
96
+ pos = nodePos;
97
+ return false;
98
+ }
99
+ });
100
+ if (pos !== null) {
101
+ editor.chain().focus().setNodeSelection(pos).updateAttributes("image", {
102
+ src: result.url,
103
+ alt: result.alt || file.name,
104
+ loading: false
105
+ }).run();
106
+ }
107
+ URL.revokeObjectURL(placeholderUrl);
108
+ }).catch((err) => {
109
+ console.error("Image upload failed:", err);
110
+ URL.revokeObjectURL(placeholderUrl);
111
+ });
112
+ return true;
113
+ }
114
+ };
115
+ },
116
+ addProseMirrorPlugins() {
117
+ const opts = this.options;
118
+ const { uploadFn, maxSize, allowedTypes } = opts;
119
+ const editorRef = this.editor;
120
+ return [
121
+ new state.Plugin({
122
+ key: new state.PluginKey("imageUploadDrop"),
123
+ props: {
124
+ handleDOMEvents: {
125
+ drop(view, event) {
126
+ const files = event.dataTransfer?.files;
127
+ if (!files || files.length === 0) return false;
128
+ const imageFiles = Array.from(files).filter(
129
+ (f) => (allowedTypes || []).includes(f.type)
130
+ );
131
+ if (imageFiles.length === 0) return false;
132
+ event.preventDefault();
133
+ for (const file of imageFiles) {
134
+ if (maxSize && file.size > maxSize) continue;
135
+ editorRef.commands.uploadImage(file);
136
+ }
137
+ return true;
138
+ },
139
+ paste(view, event) {
140
+ const files = event.clipboardData?.files;
141
+ if (!files || files.length === 0) return false;
142
+ const imageFiles = Array.from(files).filter(
143
+ (f) => (allowedTypes || []).includes(f.type)
144
+ );
145
+ if (imageFiles.length === 0) return false;
146
+ event.preventDefault();
147
+ for (const file of imageFiles) {
148
+ if (maxSize && file.size > maxSize) continue;
149
+ editorRef.commands.uploadImage(file);
150
+ }
151
+ return true;
152
+ }
153
+ }
154
+ }
155
+ })
156
+ ];
157
+ }
158
+ });
159
+ var Callout = core.Node.create({
160
+ name: "callout",
161
+ group: "block",
162
+ content: "block+",
163
+ defining: true,
164
+ addAttributes() {
165
+ return {
166
+ type: {
167
+ default: "info",
168
+ parseHTML: (element) => element.getAttribute("data-callout-type") || "info",
169
+ renderHTML: (attributes) => ({
170
+ "data-callout-type": attributes.type
171
+ })
172
+ }
173
+ };
174
+ },
175
+ parseHTML() {
176
+ return [{ tag: "div[data-callout]" }];
177
+ },
178
+ renderHTML({ HTMLAttributes }) {
179
+ return [
180
+ "div",
181
+ core.mergeAttributes(HTMLAttributes, { "data-callout": "", class: `nbk-callout nbk-callout-${HTMLAttributes["data-callout-type"] || "info"}` }),
182
+ 0
183
+ ];
184
+ },
185
+ addCommands() {
186
+ return {
187
+ setCallout: (attrs) => ({ commands }) => {
188
+ return commands.wrapIn(this.name, attrs);
189
+ },
190
+ toggleCallout: (attrs) => ({ commands }) => {
191
+ return commands.toggleWrap(this.name, attrs);
192
+ }
193
+ };
194
+ }
195
+ });
196
+ var FAQItem = core.Node.create({
197
+ name: "faqItem",
198
+ group: "block",
199
+ content: "faqQuestion faqAnswer",
200
+ defining: true,
201
+ parseHTML() {
202
+ return [{ tag: "div[data-faq-item]" }];
203
+ },
204
+ renderHTML({ HTMLAttributes }) {
205
+ return ["div", core.mergeAttributes(HTMLAttributes, { "data-faq-item": "", class: "nbk-faq-item" }), 0];
206
+ }
207
+ });
208
+ var FAQQuestion = core.Node.create({
209
+ name: "faqQuestion",
210
+ content: "inline*",
211
+ defining: true,
212
+ parseHTML() {
213
+ return [{ tag: "div[data-faq-question]" }];
214
+ },
215
+ renderHTML({ HTMLAttributes }) {
216
+ return ["div", core.mergeAttributes(HTMLAttributes, { "data-faq-question": "", class: "nbk-faq-question" }), 0];
217
+ }
218
+ });
219
+ var FAQAnswer = core.Node.create({
220
+ name: "faqAnswer",
221
+ content: "block+",
222
+ defining: true,
223
+ parseHTML() {
224
+ return [{ tag: "div[data-faq-answer]" }];
225
+ },
226
+ renderHTML({ HTMLAttributes }) {
227
+ return ["div", core.mergeAttributes(HTMLAttributes, { "data-faq-answer": "", class: "nbk-faq-answer" }), 0];
228
+ }
229
+ });
230
+ var FAQ = core.Node.create({
231
+ name: "faq",
232
+ group: "block",
233
+ content: "faqItem+",
234
+ defining: true,
235
+ parseHTML() {
236
+ return [{ tag: "div[data-faq]" }];
237
+ },
238
+ renderHTML({ HTMLAttributes }) {
239
+ return ["div", core.mergeAttributes(HTMLAttributes, { "data-faq": "", class: "nbk-faq" }), 0];
240
+ },
241
+ addCommands() {
242
+ return {
243
+ insertFAQ: () => ({ chain }) => {
244
+ return chain().insertContent({
245
+ type: "faq",
246
+ content: [
247
+ {
248
+ type: "faqItem",
249
+ content: [
250
+ { type: "faqQuestion", content: [{ type: "text", text: "Question?" }] },
251
+ { type: "faqAnswer", content: [{ type: "paragraph", content: [{ type: "text", text: "Answer." }] }] }
252
+ ]
253
+ }
254
+ ]
255
+ }).run();
256
+ }
257
+ };
258
+ }
259
+ });
260
+ var TableOfContents = core.Node.create({
261
+ name: "tableOfContents",
262
+ group: "block",
263
+ atom: true,
264
+ parseHTML() {
265
+ return [{ tag: "div[data-toc]" }];
266
+ },
267
+ renderHTML({ HTMLAttributes }) {
268
+ return [
269
+ "div",
270
+ core.mergeAttributes(HTMLAttributes, {
271
+ "data-toc": "",
272
+ class: "nbk-toc-placeholder"
273
+ }),
274
+ "Table of Contents (auto-generated)"
275
+ ];
276
+ },
277
+ addCommands() {
278
+ return {
279
+ insertTableOfContents: () => ({ commands }) => {
280
+ return commands.insertContent({ type: this.name });
281
+ }
282
+ };
283
+ }
284
+ });
285
+ var CodeBlockEnhanced = CodeBlockLowlight__default.default.extend({
286
+ addAttributes() {
287
+ return {
288
+ ...this.parent?.(),
289
+ language: {
290
+ default: "plaintext",
291
+ parseHTML: (element) => element.getAttribute("data-language") || element.querySelector("code")?.className?.replace("language-", "") || "plaintext",
292
+ renderHTML: (attributes) => ({
293
+ "data-language": attributes.language
294
+ })
295
+ },
296
+ filename: {
297
+ default: null,
298
+ parseHTML: (element) => element.getAttribute("data-filename"),
299
+ renderHTML: (attributes) => {
300
+ if (!attributes.filename) return {};
301
+ return { "data-filename": attributes.filename };
302
+ }
303
+ }
304
+ };
305
+ }
306
+ });
307
+ var SUPPORTED_LANGUAGES = [
308
+ "plaintext",
309
+ "javascript",
310
+ "typescript",
311
+ "jsx",
312
+ "tsx",
313
+ "html",
314
+ "css",
315
+ "scss",
316
+ "json",
317
+ "python",
318
+ "rust",
319
+ "go",
320
+ "java",
321
+ "kotlin",
322
+ "swift",
323
+ "ruby",
324
+ "php",
325
+ "c",
326
+ "cpp",
327
+ "csharp",
328
+ "sql",
329
+ "bash",
330
+ "shell",
331
+ "yaml",
332
+ "toml",
333
+ "markdown",
334
+ "graphql",
335
+ "docker",
336
+ "nginx"
337
+ ];
338
+ var defaultSlashCommands = [
339
+ {
340
+ title: "Heading 2",
341
+ description: "Large section heading",
342
+ icon: "H2",
343
+ command: (editor) => editor.chain().focus().toggleHeading({ level: 2 }).run()
344
+ },
345
+ {
346
+ title: "Heading 3",
347
+ description: "Medium section heading",
348
+ icon: "H3",
349
+ command: (editor) => editor.chain().focus().toggleHeading({ level: 3 }).run()
350
+ },
351
+ {
352
+ title: "Heading 4",
353
+ description: "Small section heading",
354
+ icon: "H4",
355
+ command: (editor) => editor.chain().focus().toggleHeading({ level: 4 }).run()
356
+ },
357
+ {
358
+ title: "Bullet List",
359
+ description: "Create a simple bullet list",
360
+ icon: "\u2022",
361
+ command: (editor) => editor.chain().focus().toggleBulletList().run()
362
+ },
363
+ {
364
+ title: "Numbered List",
365
+ description: "Create a numbered list",
366
+ icon: "1.",
367
+ command: (editor) => editor.chain().focus().toggleOrderedList().run()
368
+ },
369
+ {
370
+ title: "Task List",
371
+ description: "Create a checklist",
372
+ icon: "\u2611",
373
+ command: (editor) => editor.chain().focus().toggleTaskList().run()
374
+ },
375
+ {
376
+ title: "Blockquote",
377
+ description: "Add a quote block",
378
+ icon: '"',
379
+ command: (editor) => editor.chain().focus().toggleBlockquote().run()
380
+ },
381
+ {
382
+ title: "Code Block",
383
+ description: "Add a code snippet",
384
+ icon: "</>",
385
+ command: (editor) => editor.chain().focus().toggleCodeBlock().run()
386
+ },
387
+ {
388
+ title: "Divider",
389
+ description: "Add a horizontal divider",
390
+ icon: "\u2014",
391
+ command: (editor) => editor.chain().focus().setHorizontalRule().run()
392
+ },
393
+ {
394
+ title: "Image",
395
+ description: "Upload or embed an image",
396
+ icon: "\u{1F5BC}",
397
+ command: (editor) => {
398
+ const input = document.createElement("input");
399
+ input.type = "file";
400
+ input.accept = "image/*";
401
+ input.onchange = () => {
402
+ const file = input.files?.[0];
403
+ if (file) {
404
+ editor.commands.uploadImage(file);
405
+ }
406
+ };
407
+ input.click();
408
+ }
409
+ },
410
+ {
411
+ title: "Table",
412
+ description: "Add a table",
413
+ icon: "\u229E",
414
+ command: (editor) => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run()
415
+ },
416
+ {
417
+ title: "Callout",
418
+ description: "Add an info callout box",
419
+ icon: "\u2139",
420
+ command: (editor) => editor.chain().focus().setCallout({ type: "info" }).run()
421
+ },
422
+ {
423
+ title: "FAQ",
424
+ description: "Add a FAQ section",
425
+ icon: "?",
426
+ command: (editor) => editor.chain().focus().insertFAQ().run()
427
+ },
428
+ {
429
+ title: "Table of Contents",
430
+ description: "Auto-generated from headings",
431
+ icon: "\u2261",
432
+ command: (editor) => editor.chain().focus().insertTableOfContents().run()
433
+ }
434
+ ];
435
+ var SlashCommand = core.Extension.create({
436
+ name: "slashCommand",
437
+ addOptions() {
438
+ return {
439
+ commands: defaultSlashCommands,
440
+ onStateChange: (_state) => {
441
+ }
442
+ };
443
+ },
444
+ addStorage() {
445
+ return {
446
+ deleteSlashAndRun: (_item) => {
447
+ }
448
+ };
449
+ },
450
+ addProseMirrorPlugins() {
451
+ const { commands, onStateChange } = this.options;
452
+ const editorRef = this.editor;
453
+ const storage = this.editor.storage.slashCommand;
454
+ let state$1 = {
455
+ isOpen: false,
456
+ query: "",
457
+ position: null,
458
+ selectedIndex: 0,
459
+ items: commands
460
+ };
461
+ function updateState(partial) {
462
+ state$1 = { ...state$1, ...partial };
463
+ onStateChange(state$1);
464
+ }
465
+ function deleteSlashText(view) {
466
+ const { $from } = view.state.selection;
467
+ const textBefore = $from.parent.textContent.slice(0, $from.parentOffset);
468
+ const slashIndex = textBefore.lastIndexOf("/");
469
+ if (slashIndex >= 0) {
470
+ const start = $from.start() + slashIndex;
471
+ const end = $from.pos;
472
+ view.dispatch(view.state.tr.delete(start, end));
473
+ }
474
+ }
475
+ storage.deleteSlashAndRun = (item) => {
476
+ deleteSlashText(editorRef.view);
477
+ item.command(editorRef);
478
+ updateState({ isOpen: false, query: "", selectedIndex: 0 });
479
+ };
480
+ return [
481
+ new state.Plugin({
482
+ key: new state.PluginKey("slashCommand"),
483
+ props: {
484
+ handleKeyDown(view, event) {
485
+ if (!state$1.isOpen) {
486
+ return false;
487
+ }
488
+ if (event.key === "ArrowDown") {
489
+ event.preventDefault();
490
+ updateState({
491
+ selectedIndex: (state$1.selectedIndex + 1) % state$1.items.length
492
+ });
493
+ return true;
494
+ }
495
+ if (event.key === "ArrowUp") {
496
+ event.preventDefault();
497
+ updateState({
498
+ selectedIndex: (state$1.selectedIndex - 1 + state$1.items.length) % state$1.items.length
499
+ });
500
+ return true;
501
+ }
502
+ if (event.key === "Enter") {
503
+ event.preventDefault();
504
+ const item = state$1.items[state$1.selectedIndex];
505
+ if (item) {
506
+ deleteSlashText(view);
507
+ item.command(editorRef);
508
+ }
509
+ updateState({ isOpen: false, query: "", selectedIndex: 0 });
510
+ return true;
511
+ }
512
+ if (event.key === "Escape") {
513
+ updateState({ isOpen: false, query: "", selectedIndex: 0 });
514
+ return true;
515
+ }
516
+ return false;
517
+ },
518
+ handleTextInput(view, from, _to, text) {
519
+ const { $from } = view.state.selection;
520
+ const textBefore = $from.parent.textContent.slice(0, $from.parentOffset) + text;
521
+ const slashIndex = textBefore.lastIndexOf("/");
522
+ if (slashIndex >= 0) {
523
+ const query = textBefore.slice(slashIndex + 1).toLowerCase();
524
+ const filtered = commands.filter(
525
+ (cmd) => cmd.title.toLowerCase().includes(query) || cmd.description.toLowerCase().includes(query)
526
+ );
527
+ if (filtered.length > 0) {
528
+ const coords = view.coordsAtPos(from);
529
+ updateState({
530
+ isOpen: true,
531
+ query,
532
+ position: { top: coords.bottom + 4, left: coords.left },
533
+ items: filtered,
534
+ selectedIndex: 0
535
+ });
536
+ } else {
537
+ updateState({ isOpen: false, query: "", selectedIndex: 0 });
538
+ }
539
+ } else if (state$1.isOpen) {
540
+ updateState({ isOpen: false, query: "", selectedIndex: 0 });
541
+ }
542
+ return false;
543
+ }
544
+ }
545
+ })
546
+ ];
547
+ }
548
+ });
549
+ function BlogEditor({
550
+ content,
551
+ onChange,
552
+ onSave,
553
+ uploadImage,
554
+ placeholder = 'Start writing your post... Type "/" for commands',
555
+ autosaveInterval = 3e4,
556
+ className = ""
557
+ }) {
558
+ const [slashState, setSlashState] = react.useState({
559
+ isOpen: false,
560
+ query: "",
561
+ position: null,
562
+ selectedIndex: 0,
563
+ items: []
564
+ });
565
+ const [wordCount, setWordCount] = react.useState(0);
566
+ const [isSaving, setIsSaving] = react.useState(false);
567
+ const autosaveTimerRef = react.useRef(null);
568
+ const lastSavedRef = react.useRef("");
569
+ const defaultUpload = react.useCallback(async (file) => {
570
+ if (!uploadImage) {
571
+ return { url: URL.createObjectURL(file), alt: file.name };
572
+ }
573
+ return uploadImage(file);
574
+ }, [uploadImage]);
575
+ const editor = react$1.useEditor({
576
+ extensions: [
577
+ StarterKit__default.default.configure({
578
+ codeBlock: false,
579
+ dropcursor: { color: "#2563eb", width: 2 }
580
+ }),
581
+ Placeholder__default.default.configure({ placeholder }),
582
+ Link__default.default.configure({ openOnClick: false, HTMLAttributes: { class: "nbk-link" } }),
583
+ Underline__default.default,
584
+ Highlight__default.default.configure({ multicolor: false }),
585
+ Typography__default.default,
586
+ TaskList__default.default,
587
+ TaskItem__default.default.configure({ nested: true }),
588
+ Table__default.default.configure({ resizable: true }),
589
+ TableRow__default.default,
590
+ TableCell__default.default,
591
+ TableHeader__default.default,
592
+ ImageUpload.configure({ uploadFn: defaultUpload }),
593
+ CodeBlockEnhanced,
594
+ Callout,
595
+ FAQ,
596
+ FAQItem,
597
+ FAQQuestion,
598
+ FAQAnswer,
599
+ TableOfContents,
600
+ SlashCommand.configure({
601
+ onStateChange: setSlashState
602
+ })
603
+ ],
604
+ content: content || { type: "doc", content: [{ type: "paragraph" }] },
605
+ onUpdate: ({ editor: editor2 }) => {
606
+ const json = editor2.getJSON();
607
+ onChange?.(json);
608
+ const text = editor2.getText();
609
+ setWordCount(text.trim() ? text.trim().split(/\s+/).length : 0);
610
+ },
611
+ editorProps: {
612
+ attributes: {
613
+ class: `nbk-editor-content ${className}`
614
+ }
615
+ }
616
+ });
617
+ react.useEffect(() => {
618
+ if (!onSave || !autosaveInterval || !editor) return;
619
+ autosaveTimerRef.current = setInterval(() => {
620
+ const json = JSON.stringify(editor.getJSON());
621
+ if (json !== lastSavedRef.current) {
622
+ setIsSaving(true);
623
+ onSave(editor.getJSON());
624
+ lastSavedRef.current = json;
625
+ setTimeout(() => setIsSaving(false), 1e3);
626
+ }
627
+ }, autosaveInterval);
628
+ return () => {
629
+ if (autosaveTimerRef.current) clearInterval(autosaveTimerRef.current);
630
+ };
631
+ }, [editor, onSave, autosaveInterval]);
632
+ const readingTime = Math.max(1, Math.ceil(wordCount / 200));
633
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nbk-editor", children: [
634
+ editor && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nbk-editor-toolbar", children: [
635
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nbk-toolbar-group", children: [
636
+ /* @__PURE__ */ jsxRuntime.jsx(
637
+ "button",
638
+ {
639
+ onClick: () => editor.chain().focus().toggleBold().run(),
640
+ className: editor.isActive("bold") ? "nbk-toolbar-btn active" : "nbk-toolbar-btn",
641
+ title: "Bold",
642
+ children: /* @__PURE__ */ jsxRuntime.jsx("strong", { children: "B" })
643
+ }
644
+ ),
645
+ /* @__PURE__ */ jsxRuntime.jsx(
646
+ "button",
647
+ {
648
+ onClick: () => editor.chain().focus().toggleItalic().run(),
649
+ className: editor.isActive("italic") ? "nbk-toolbar-btn active" : "nbk-toolbar-btn",
650
+ title: "Italic",
651
+ children: /* @__PURE__ */ jsxRuntime.jsx("em", { children: "I" })
652
+ }
653
+ ),
654
+ /* @__PURE__ */ jsxRuntime.jsx(
655
+ "button",
656
+ {
657
+ onClick: () => editor.chain().focus().toggleUnderline().run(),
658
+ className: editor.isActive("underline") ? "nbk-toolbar-btn active" : "nbk-toolbar-btn",
659
+ title: "Underline",
660
+ children: /* @__PURE__ */ jsxRuntime.jsx("u", { children: "U" })
661
+ }
662
+ ),
663
+ /* @__PURE__ */ jsxRuntime.jsx(
664
+ "button",
665
+ {
666
+ onClick: () => editor.chain().focus().toggleStrike().run(),
667
+ className: editor.isActive("strike") ? "nbk-toolbar-btn active" : "nbk-toolbar-btn",
668
+ title: "Strikethrough",
669
+ children: /* @__PURE__ */ jsxRuntime.jsx("s", { children: "S" })
670
+ }
671
+ ),
672
+ /* @__PURE__ */ jsxRuntime.jsx(
673
+ "button",
674
+ {
675
+ onClick: () => editor.chain().focus().toggleCode().run(),
676
+ className: editor.isActive("code") ? "nbk-toolbar-btn active" : "nbk-toolbar-btn",
677
+ title: "Inline Code",
678
+ children: "</>"
679
+ }
680
+ ),
681
+ /* @__PURE__ */ jsxRuntime.jsx(
682
+ "button",
683
+ {
684
+ onClick: () => editor.chain().focus().toggleHighlight().run(),
685
+ className: editor.isActive("highlight") ? "nbk-toolbar-btn active" : "nbk-toolbar-btn",
686
+ title: "Highlight",
687
+ children: "H"
688
+ }
689
+ )
690
+ ] }),
691
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nbk-toolbar-divider" }),
692
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nbk-toolbar-group", children: [2, 3, 4].map((level) => /* @__PURE__ */ jsxRuntime.jsxs(
693
+ "button",
694
+ {
695
+ onClick: () => editor.chain().focus().toggleHeading({ level }).run(),
696
+ className: editor.isActive("heading", { level }) ? "nbk-toolbar-btn active" : "nbk-toolbar-btn",
697
+ title: `Heading ${level}`,
698
+ children: [
699
+ "H",
700
+ level
701
+ ]
702
+ },
703
+ level
704
+ )) }),
705
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nbk-toolbar-divider" }),
706
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nbk-toolbar-group", children: [
707
+ /* @__PURE__ */ jsxRuntime.jsx(
708
+ "button",
709
+ {
710
+ onClick: () => editor.chain().focus().toggleBulletList().run(),
711
+ className: editor.isActive("bulletList") ? "nbk-toolbar-btn active" : "nbk-toolbar-btn",
712
+ title: "Bullet List",
713
+ children: "\u2022"
714
+ }
715
+ ),
716
+ /* @__PURE__ */ jsxRuntime.jsx(
717
+ "button",
718
+ {
719
+ onClick: () => editor.chain().focus().toggleOrderedList().run(),
720
+ className: editor.isActive("orderedList") ? "nbk-toolbar-btn active" : "nbk-toolbar-btn",
721
+ title: "Numbered List",
722
+ children: "1."
723
+ }
724
+ ),
725
+ /* @__PURE__ */ jsxRuntime.jsx(
726
+ "button",
727
+ {
728
+ onClick: () => editor.chain().focus().toggleTaskList().run(),
729
+ className: editor.isActive("taskList") ? "nbk-toolbar-btn active" : "nbk-toolbar-btn",
730
+ title: "Task List",
731
+ children: "\u2611"
732
+ }
733
+ )
734
+ ] }),
735
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nbk-toolbar-divider" }),
736
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nbk-toolbar-group", children: [
737
+ /* @__PURE__ */ jsxRuntime.jsx(
738
+ "button",
739
+ {
740
+ onClick: () => editor.chain().focus().toggleBlockquote().run(),
741
+ className: editor.isActive("blockquote") ? "nbk-toolbar-btn active" : "nbk-toolbar-btn",
742
+ title: "Quote",
743
+ children: "\u201C"
744
+ }
745
+ ),
746
+ /* @__PURE__ */ jsxRuntime.jsx(
747
+ "button",
748
+ {
749
+ onClick: () => editor.chain().focus().toggleCodeBlock().run(),
750
+ className: editor.isActive("codeBlock") ? "nbk-toolbar-btn active" : "nbk-toolbar-btn",
751
+ title: "Code Block",
752
+ children: "{ }"
753
+ }
754
+ ),
755
+ /* @__PURE__ */ jsxRuntime.jsx(
756
+ "button",
757
+ {
758
+ onClick: () => editor.chain().focus().setHorizontalRule().run(),
759
+ className: "nbk-toolbar-btn",
760
+ title: "Divider",
761
+ children: "\u2014"
762
+ }
763
+ ),
764
+ /* @__PURE__ */ jsxRuntime.jsx(
765
+ "button",
766
+ {
767
+ onClick: () => editor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run(),
768
+ className: "nbk-toolbar-btn",
769
+ title: "Table",
770
+ children: "\u229E"
771
+ }
772
+ )
773
+ ] }),
774
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nbk-toolbar-divider" }),
775
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nbk-toolbar-group", children: [
776
+ /* @__PURE__ */ jsxRuntime.jsx(
777
+ "button",
778
+ {
779
+ onClick: () => {
780
+ const url = window.prompt("Enter URL");
781
+ if (url) editor.chain().focus().setLink({ href: url }).run();
782
+ },
783
+ className: editor.isActive("link") ? "nbk-toolbar-btn active" : "nbk-toolbar-btn",
784
+ title: "Link",
785
+ children: "\u{1F517}"
786
+ }
787
+ ),
788
+ /* @__PURE__ */ jsxRuntime.jsx(
789
+ "button",
790
+ {
791
+ onClick: () => {
792
+ const input = document.createElement("input");
793
+ input.type = "file";
794
+ input.accept = "image/*";
795
+ input.onchange = () => {
796
+ const file = input.files?.[0];
797
+ if (file) editor.commands.uploadImage(file);
798
+ };
799
+ input.click();
800
+ },
801
+ className: "nbk-toolbar-btn",
802
+ title: "Upload Image",
803
+ children: "\u{1F4F7}"
804
+ }
805
+ )
806
+ ] })
807
+ ] }),
808
+ editor && /* @__PURE__ */ jsxRuntime.jsx(react$1.BubbleMenu, { editor, tippyOptions: { duration: 100 }, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nbk-bubble-menu", children: [
809
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => editor.chain().focus().toggleBold().run(), className: editor.isActive("bold") ? "active" : "", children: "B" }),
810
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => editor.chain().focus().toggleItalic().run(), className: editor.isActive("italic") ? "active" : "", children: "I" }),
811
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => editor.chain().focus().toggleCode().run(), className: editor.isActive("code") ? "active" : "", children: "</>" }),
812
+ /* @__PURE__ */ jsxRuntime.jsx(
813
+ "button",
814
+ {
815
+ onClick: () => {
816
+ const url = window.prompt("Enter URL");
817
+ if (url) editor.chain().focus().setLink({ href: url }).run();
818
+ },
819
+ className: editor.isActive("link") ? "active" : "",
820
+ children: "Link"
821
+ }
822
+ )
823
+ ] }) }),
824
+ /* @__PURE__ */ jsxRuntime.jsx(react$1.EditorContent, { editor }),
825
+ slashState.isOpen && slashState.position && /* @__PURE__ */ jsxRuntime.jsx(
826
+ "div",
827
+ {
828
+ className: "nbk-slash-menu",
829
+ style: {
830
+ position: "fixed",
831
+ top: slashState.position.top,
832
+ left: slashState.position.left
833
+ },
834
+ children: slashState.items.map((item, index) => /* @__PURE__ */ jsxRuntime.jsxs(
835
+ "button",
836
+ {
837
+ className: `nbk-slash-item ${index === slashState.selectedIndex ? "selected" : ""}`,
838
+ onMouseDown: (e) => {
839
+ e.preventDefault();
840
+ editor.storage.slashCommand.deleteSlashAndRun(item);
841
+ },
842
+ children: [
843
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nbk-slash-icon", children: item.icon }),
844
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
845
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nbk-slash-title", children: item.title }),
846
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "nbk-slash-desc", children: item.description })
847
+ ] })
848
+ ]
849
+ },
850
+ item.title
851
+ ))
852
+ }
853
+ ),
854
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "nbk-editor-status", children: [
855
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
856
+ wordCount,
857
+ " words"
858
+ ] }),
859
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
860
+ readingTime,
861
+ " min read"
862
+ ] }),
863
+ isSaving && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "nbk-saving", children: "Saving..." })
864
+ ] })
865
+ ] });
866
+ }
867
+
868
+ // src/editor/renderer.ts
869
+ function renderBlocksToHTML(doc) {
870
+ if (!doc.content) return "";
871
+ return doc.content.map(renderNode).join("");
872
+ }
873
+ function renderNode(node) {
874
+ switch (node.type) {
875
+ case "paragraph":
876
+ return `<p>${renderInline(node)}</p>`;
877
+ case "heading": {
878
+ const level = node.attrs?.level || 2;
879
+ const text = renderInline(node);
880
+ const id = slugify(stripTags(text));
881
+ return `<h${level} id="${id}">${text}</h${level}>`;
882
+ }
883
+ case "bulletList":
884
+ return `<ul>${renderChildren(node)}</ul>`;
885
+ case "orderedList":
886
+ return `<ol>${renderChildren(node)}</ol>`;
887
+ case "listItem":
888
+ return `<li>${renderChildren(node)}</li>`;
889
+ case "taskList":
890
+ return `<ul class="nbk-task-list">${renderChildren(node)}</ul>`;
891
+ case "taskItem": {
892
+ const checked = node.attrs?.checked ? "checked" : "";
893
+ return `<li class="nbk-task-item" data-checked="${checked}"><input type="checkbox" ${checked} disabled />${renderChildren(node)}</li>`;
894
+ }
895
+ case "blockquote":
896
+ return `<blockquote>${renderChildren(node)}</blockquote>`;
897
+ case "codeBlock": {
898
+ const lang = node.attrs?.language || "plaintext";
899
+ const filename = node.attrs?.filename;
900
+ const code = escapeHtml(getTextContent(node));
901
+ const header = filename ? `<div class="nbk-code-header">${escapeHtml(filename)}</div>` : "";
902
+ return `${header}<pre><code class="language-${lang}">${code}</code></pre>`;
903
+ }
904
+ case "image": {
905
+ const src = node.attrs?.src || "";
906
+ const alt = node.attrs?.alt || "";
907
+ const caption = node.attrs?.caption;
908
+ const width = node.attrs?.width;
909
+ const height = node.attrs?.height;
910
+ let img = `<img src="${escapeAttr(src)}" alt="${escapeAttr(alt)}"`;
911
+ if (width) img += ` width="${width}"`;
912
+ if (height) img += ` height="${height}"`;
913
+ img += ' loading="lazy" />';
914
+ if (caption) {
915
+ return `<figure>${img}<figcaption>${escapeHtml(caption)}</figcaption></figure>`;
916
+ }
917
+ return img;
918
+ }
919
+ case "horizontalRule":
920
+ return "<hr />";
921
+ case "table":
922
+ return `<table>${renderChildren(node)}</table>`;
923
+ case "tableRow":
924
+ return `<tr>${renderChildren(node)}</tr>`;
925
+ case "tableHeader":
926
+ return `<th>${renderInline(node)}</th>`;
927
+ case "tableCell":
928
+ return `<td>${renderInline(node)}</td>`;
929
+ case "callout": {
930
+ const calloutType = node.attrs?.type || "info";
931
+ const icons = {
932
+ info: "\u2139\uFE0F",
933
+ warning: "\u26A0\uFE0F",
934
+ tip: "\u{1F4A1}",
935
+ danger: "\u{1F6A8}"
936
+ };
937
+ return `<div class="nbk-callout nbk-callout-${calloutType}"><span class="nbk-callout-icon">${icons[calloutType] || ""}</span><div class="nbk-callout-content">${renderChildren(node)}</div></div>`;
938
+ }
939
+ case "faq":
940
+ return `<div class="nbk-faq" itemscope itemtype="https://schema.org/FAQPage">${renderChildren(node)}</div>`;
941
+ case "faqItem":
942
+ return `<div class="nbk-faq-item" itemscope itemprop="mainEntity" itemtype="https://schema.org/Question">${renderChildren(node)}</div>`;
943
+ case "faqQuestion":
944
+ return `<h3 itemprop="name">${renderInline(node)}</h3>`;
945
+ case "faqAnswer":
946
+ return `<div itemprop="acceptedAnswer" itemscope itemtype="https://schema.org/Answer"><div itemprop="text">${renderChildren(node)}</div></div>`;
947
+ case "tableOfContents":
948
+ return '<div data-toc="true" class="nbk-toc"></div>';
949
+ case "html":
950
+ return getTextContent(node);
951
+ case "embed": {
952
+ const embedUrl = node.attrs?.src || "";
953
+ return `<div class="nbk-embed"><iframe src="${escapeAttr(embedUrl)}" frameborder="0" allowfullscreen loading="lazy"></iframe></div>`;
954
+ }
955
+ case "text":
956
+ return renderTextNode(node);
957
+ case "hardBreak":
958
+ return "<br />";
959
+ default:
960
+ if (node.content) return renderChildren(node);
961
+ if (node.text) return escapeHtml(node.text);
962
+ return "";
963
+ }
964
+ }
965
+ function renderChildren(node) {
966
+ if (!node.content) return "";
967
+ return node.content.map(renderNode).join("");
968
+ }
969
+ function renderInline(node) {
970
+ if (!node.content) return "";
971
+ return node.content.map(renderNode).join("");
972
+ }
973
+ function renderTextNode(node) {
974
+ let text = escapeHtml(node.text || "");
975
+ if (node.marks) {
976
+ for (const mark of node.marks) {
977
+ switch (mark.type) {
978
+ case "bold":
979
+ text = `<strong>${text}</strong>`;
980
+ break;
981
+ case "italic":
982
+ text = `<em>${text}</em>`;
983
+ break;
984
+ case "strike":
985
+ text = `<s>${text}</s>`;
986
+ break;
987
+ case "code":
988
+ text = `<code>${text}</code>`;
989
+ break;
990
+ case "underline":
991
+ text = `<u>${text}</u>`;
992
+ break;
993
+ case "highlight":
994
+ text = `<mark>${text}</mark>`;
995
+ break;
996
+ case "link": {
997
+ const href = mark.attrs?.href || "";
998
+ const target = href.startsWith("http") ? ' target="_blank" rel="noopener noreferrer"' : "";
999
+ text = `<a href="${escapeAttr(href)}"${target}>${text}</a>`;
1000
+ break;
1001
+ }
1002
+ }
1003
+ }
1004
+ }
1005
+ return text;
1006
+ }
1007
+ function getTextContent(node) {
1008
+ if (node.text) return node.text;
1009
+ if (!node.content) return "";
1010
+ return node.content.map(getTextContent).join("");
1011
+ }
1012
+ function escapeHtml(str) {
1013
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
1014
+ }
1015
+ function escapeAttr(str) {
1016
+ return str.replace(/"/g, "&quot;").replace(/&/g, "&amp;");
1017
+ }
1018
+ function stripTags(html) {
1019
+ return html.replace(/<[^>]+>/g, "");
1020
+ }
1021
+ function slugify(text) {
1022
+ return text.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_]+/g, "-").replace(/-+/g, "-");
1023
+ }
1024
+ function extractHeadings(doc) {
1025
+ const headings = [];
1026
+ function walk(node) {
1027
+ if (node.type === "heading") {
1028
+ const text = getTextContent(node);
1029
+ headings.push({
1030
+ id: slugify(text),
1031
+ text,
1032
+ level: node.attrs?.level || 2
1033
+ });
1034
+ }
1035
+ if (node.content) {
1036
+ node.content.forEach(walk);
1037
+ }
1038
+ }
1039
+ if (doc.content) {
1040
+ doc.content.forEach(walk);
1041
+ }
1042
+ return headings;
1043
+ }
1044
+ function extractFAQItems(doc) {
1045
+ const items = [];
1046
+ function walk(node) {
1047
+ if (node.type === "faqItem" && node.content) {
1048
+ const question = node.content.find((c) => c.type === "faqQuestion");
1049
+ const answer = node.content.find((c) => c.type === "faqAnswer");
1050
+ if (question && answer) {
1051
+ items.push({
1052
+ question: getTextContent(question),
1053
+ answer: renderChildren(answer)
1054
+ });
1055
+ }
1056
+ }
1057
+ if (node.content) {
1058
+ node.content.forEach(walk);
1059
+ }
1060
+ }
1061
+ if (doc.content) {
1062
+ doc.content.forEach(walk);
1063
+ }
1064
+ return items;
1065
+ }
1066
+
1067
+ exports.BlogEditor = BlogEditor;
1068
+ exports.Callout = Callout;
1069
+ exports.CodeBlockEnhanced = CodeBlockEnhanced;
1070
+ exports.FAQ = FAQ;
1071
+ exports.FAQAnswer = FAQAnswer;
1072
+ exports.FAQItem = FAQItem;
1073
+ exports.FAQQuestion = FAQQuestion;
1074
+ exports.ImageUpload = ImageUpload;
1075
+ exports.SUPPORTED_LANGUAGES = SUPPORTED_LANGUAGES;
1076
+ exports.SlashCommand = SlashCommand;
1077
+ exports.TableOfContents = TableOfContents;
1078
+ exports.defaultSlashCommands = defaultSlashCommands;
1079
+ exports.extractFAQItems = extractFAQItems;
1080
+ exports.extractHeadings = extractHeadings;
1081
+ exports.renderBlocksToHTML = renderBlocksToHTML;
1082
+ //# sourceMappingURL=index.cjs.map
1083
+ //# sourceMappingURL=index.cjs.map