@eigenpal/docx-editor-agents 0.0.28 → 0.0.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/bridge.js +3 -1
  2. package/dist/bridge.js.map +1 -1
  3. package/dist/bridge.mjs +8 -0
  4. package/dist/bridge.mjs.map +1 -0
  5. package/dist/chunk-5D2V7VK3.js +976 -0
  6. package/dist/chunk-5D2V7VK3.js.map +1 -0
  7. package/dist/chunk-5E3CFYZ4.mjs +249 -0
  8. package/dist/chunk-5E3CFYZ4.mjs.map +1 -0
  9. package/dist/chunk-GACRQVPW.js +11680 -0
  10. package/dist/chunk-GACRQVPW.js.map +1 -0
  11. package/dist/chunk-OFUT6WUQ.mjs +969 -0
  12. package/dist/chunk-OFUT6WUQ.mjs.map +1 -0
  13. package/dist/chunk-Q2HHIVUL.js +266 -0
  14. package/dist/chunk-Q2HHIVUL.js.map +1 -0
  15. package/dist/chunk-R4MIGZEJ.mjs +11587 -0
  16. package/dist/chunk-R4MIGZEJ.mjs.map +1 -0
  17. package/dist/executor-6ZG2VUZS.mjs +3 -0
  18. package/dist/executor-6ZG2VUZS.mjs.map +1 -0
  19. package/dist/executor-ZRVQSXRT.js +16 -0
  20. package/dist/executor-ZRVQSXRT.js.map +1 -0
  21. package/dist/headless-O2RRWYCB.js +422 -0
  22. package/dist/headless-O2RRWYCB.js.map +1 -0
  23. package/dist/headless-UKRSG32U.mjs +5 -0
  24. package/dist/headless-UKRSG32U.mjs.map +1 -0
  25. package/dist/index.d.mts +2013 -0
  26. package/dist/index.d.ts +1776 -1
  27. package/dist/index.js +26 -19
  28. package/dist/index.js.map +1 -1
  29. package/dist/{index.cjs → index.mjs} +23 -26
  30. package/dist/index.mjs.map +1 -0
  31. package/dist/processTemplate-7M6KZ6GR.mjs +3 -0
  32. package/dist/processTemplate-7M6KZ6GR.mjs.map +1 -0
  33. package/dist/processTemplate-H4X2MH5R.js +54 -0
  34. package/dist/processTemplate-H4X2MH5R.js.map +1 -0
  35. package/package.json +11 -9
  36. package/dist/bridge.cjs +0 -10
  37. package/dist/bridge.cjs.map +0 -1
  38. package/dist/index.cjs.map +0 -1
  39. package/dist/index.d.cts +0 -238
  40. /package/dist/{bridge.d.cts → bridge.d.mts} +0 -0
@@ -0,0 +1,969 @@
1
+ // ../core/src/core-plugins/registry.ts
2
+ var PluginRegistry = class {
3
+ constructor() {
4
+ this.plugins = /* @__PURE__ */ new Map();
5
+ this.commandHandlers = /* @__PURE__ */ new Map();
6
+ this.eventListeners = /* @__PURE__ */ new Set();
7
+ this.initialized = /* @__PURE__ */ new Set();
8
+ }
9
+ // ==========================================================================
10
+ // REGISTRATION
11
+ // ==========================================================================
12
+ /**
13
+ * Register a plugin
14
+ *
15
+ * @param plugin - The plugin to register
16
+ * @param options - Optional configuration
17
+ * @returns Registration result
18
+ */
19
+ register(plugin, options) {
20
+ const warnings = [];
21
+ if (!plugin.id) {
22
+ return { success: false, error: "Plugin must have an id" };
23
+ }
24
+ if (this.plugins.has(plugin.id)) {
25
+ return { success: false, error: `Plugin '${plugin.id}' is already registered` };
26
+ }
27
+ if (plugin.dependencies) {
28
+ for (const depId of plugin.dependencies) {
29
+ if (!this.plugins.has(depId)) {
30
+ return {
31
+ success: false,
32
+ error: `Plugin '${plugin.id}' requires '${depId}' which is not registered`
33
+ };
34
+ }
35
+ }
36
+ }
37
+ if (plugin.commandHandlers) {
38
+ for (const [commandType, handler] of Object.entries(plugin.commandHandlers)) {
39
+ if (this.commandHandlers.has(commandType)) {
40
+ const existing = this.commandHandlers.get(commandType);
41
+ warnings.push(
42
+ `Command '${commandType}' from '${plugin.id}' overrides handler from '${existing.pluginId}'`
43
+ );
44
+ }
45
+ this.commandHandlers.set(commandType, { pluginId: plugin.id, handler });
46
+ }
47
+ }
48
+ this.plugins.set(plugin.id, plugin);
49
+ if (plugin.initialize && !this.initialized.has(plugin.id)) {
50
+ try {
51
+ const result = plugin.initialize();
52
+ if (result instanceof Promise) {
53
+ result.then(() => {
54
+ this.initialized.add(plugin.id);
55
+ }).catch((err) => {
56
+ this.emit({ type: "error", pluginId: plugin.id, error: err });
57
+ });
58
+ } else {
59
+ this.initialized.add(plugin.id);
60
+ }
61
+ } catch (err) {
62
+ this.emit({ type: "error", pluginId: plugin.id, error: err });
63
+ }
64
+ }
65
+ if (options?.debug) {
66
+ console.log(`[PluginRegistry] Registered plugin: ${plugin.id}`);
67
+ }
68
+ this.emit({ type: "registered", plugin });
69
+ return {
70
+ success: true,
71
+ plugin,
72
+ warnings: warnings.length > 0 ? warnings : void 0
73
+ };
74
+ }
75
+ /**
76
+ * Unregister a plugin
77
+ *
78
+ * @param pluginId - ID of the plugin to unregister
79
+ * @returns Whether unregistration succeeded
80
+ */
81
+ unregister(pluginId) {
82
+ const plugin = this.plugins.get(pluginId);
83
+ if (!plugin) {
84
+ return false;
85
+ }
86
+ for (const [id, p] of this.plugins) {
87
+ if (p.dependencies?.includes(pluginId)) {
88
+ console.warn(`Cannot unregister '${pluginId}': '${id}' depends on it`);
89
+ return false;
90
+ }
91
+ }
92
+ for (const [commandType, { pluginId: pid }] of this.commandHandlers) {
93
+ if (pid === pluginId) {
94
+ this.commandHandlers.delete(commandType);
95
+ }
96
+ }
97
+ if (plugin.destroy) {
98
+ try {
99
+ const result = plugin.destroy();
100
+ if (result instanceof Promise) {
101
+ result.catch((err) => {
102
+ this.emit({ type: "error", pluginId, error: err });
103
+ });
104
+ }
105
+ } catch (err) {
106
+ this.emit({ type: "error", pluginId, error: err });
107
+ }
108
+ }
109
+ this.plugins.delete(pluginId);
110
+ this.initialized.delete(pluginId);
111
+ this.emit({ type: "unregistered", pluginId });
112
+ return true;
113
+ }
114
+ // ==========================================================================
115
+ // QUERIES
116
+ // ==========================================================================
117
+ /**
118
+ * Get a registered plugin by ID
119
+ *
120
+ * @param id - Plugin ID
121
+ * @returns The plugin or undefined
122
+ */
123
+ get(id) {
124
+ return this.plugins.get(id);
125
+ }
126
+ /**
127
+ * Get all registered plugins
128
+ *
129
+ * @returns Array of all plugins
130
+ */
131
+ getAll() {
132
+ return Array.from(this.plugins.values());
133
+ }
134
+ /**
135
+ * Check if a plugin is registered
136
+ *
137
+ * @param id - Plugin ID
138
+ * @returns Whether the plugin is registered
139
+ */
140
+ has(id) {
141
+ return this.plugins.has(id);
142
+ }
143
+ /**
144
+ * Get number of registered plugins
145
+ */
146
+ get size() {
147
+ return this.plugins.size;
148
+ }
149
+ // ==========================================================================
150
+ // COMMAND HANDLERS
151
+ // ==========================================================================
152
+ /**
153
+ * Get a command handler for a command type
154
+ *
155
+ * @param commandType - The command type
156
+ * @returns The handler or undefined
157
+ */
158
+ getCommandHandler(commandType) {
159
+ const entry = this.commandHandlers.get(commandType);
160
+ return entry?.handler;
161
+ }
162
+ /**
163
+ * Get all registered command types
164
+ *
165
+ * @returns Array of command type strings
166
+ */
167
+ getCommandTypes() {
168
+ return Array.from(this.commandHandlers.keys());
169
+ }
170
+ /**
171
+ * Check if a command type has a handler
172
+ *
173
+ * @param commandType - The command type
174
+ * @returns Whether a handler exists
175
+ */
176
+ hasCommandHandler(commandType) {
177
+ return this.commandHandlers.has(commandType);
178
+ }
179
+ // ==========================================================================
180
+ // MCP TOOLS
181
+ // ==========================================================================
182
+ /**
183
+ * Get all MCP tools from all registered plugins
184
+ *
185
+ * @returns Array of MCP tool definitions
186
+ */
187
+ getMcpTools() {
188
+ const tools = [];
189
+ for (const plugin of this.plugins.values()) {
190
+ if (plugin.mcpTools) {
191
+ tools.push(...plugin.mcpTools);
192
+ }
193
+ }
194
+ return tools;
195
+ }
196
+ /**
197
+ * Get MCP tools from a specific plugin
198
+ *
199
+ * @param pluginId - Plugin ID
200
+ * @returns Array of MCP tool definitions
201
+ */
202
+ getMcpToolsForPlugin(pluginId) {
203
+ const plugin = this.plugins.get(pluginId);
204
+ return plugin?.mcpTools || [];
205
+ }
206
+ /**
207
+ * Get an MCP tool by name
208
+ *
209
+ * @param toolName - Tool name
210
+ * @returns The tool definition or undefined
211
+ */
212
+ getMcpTool(toolName) {
213
+ for (const plugin of this.plugins.values()) {
214
+ if (plugin.mcpTools) {
215
+ const tool = plugin.mcpTools.find((t) => t.name === toolName);
216
+ if (tool) return tool;
217
+ }
218
+ }
219
+ return void 0;
220
+ }
221
+ // ==========================================================================
222
+ // EVENTS
223
+ // ==========================================================================
224
+ /**
225
+ * Add an event listener
226
+ *
227
+ * @param listener - Event listener function
228
+ */
229
+ addEventListener(listener) {
230
+ this.eventListeners.add(listener);
231
+ }
232
+ /**
233
+ * Remove an event listener
234
+ *
235
+ * @param listener - Event listener function
236
+ */
237
+ removeEventListener(listener) {
238
+ this.eventListeners.delete(listener);
239
+ }
240
+ /**
241
+ * Emit an event to all listeners
242
+ */
243
+ emit(event) {
244
+ for (const listener of this.eventListeners) {
245
+ try {
246
+ listener(event);
247
+ } catch (err) {
248
+ console.error("[PluginRegistry] Event listener error:", err);
249
+ }
250
+ }
251
+ }
252
+ // ==========================================================================
253
+ // UTILITIES
254
+ // ==========================================================================
255
+ /**
256
+ * Clear all registered plugins
257
+ *
258
+ * Useful for testing or resetting state.
259
+ */
260
+ clear() {
261
+ for (const plugin of this.plugins.values()) {
262
+ if (plugin.destroy) {
263
+ try {
264
+ plugin.destroy();
265
+ } catch {
266
+ }
267
+ }
268
+ }
269
+ this.plugins.clear();
270
+ this.commandHandlers.clear();
271
+ this.initialized.clear();
272
+ }
273
+ /**
274
+ * Get registry state for debugging
275
+ */
276
+ getDebugInfo() {
277
+ return {
278
+ plugins: Array.from(this.plugins.keys()),
279
+ commandTypes: Array.from(this.commandHandlers.keys()),
280
+ mcpTools: this.getMcpTools().map((t) => t.name),
281
+ initialized: Array.from(this.initialized)
282
+ };
283
+ }
284
+ };
285
+ var pluginRegistry = new PluginRegistry();
286
+ function registerPlugins(plugins, options) {
287
+ return plugins.map((plugin) => pluginRegistry.register(plugin, options));
288
+ }
289
+ function createPluginRegistrar(options) {
290
+ return (plugin) => pluginRegistry.register(plugin, options);
291
+ }
292
+
293
+ // ../core/src/agent/executor.ts
294
+ function executeCommand(doc, command) {
295
+ const pluginHandler = pluginRegistry.getCommandHandler(command.type);
296
+ if (pluginHandler) {
297
+ return pluginHandler(doc, command);
298
+ }
299
+ switch (command.type) {
300
+ case "insertText":
301
+ return executeInsertText(doc, command);
302
+ case "replaceText":
303
+ return executeReplaceText(doc, command);
304
+ case "deleteText":
305
+ return executeDeleteText(doc, command);
306
+ case "formatText":
307
+ return executeFormatText(doc, command);
308
+ case "formatParagraph":
309
+ return executeFormatParagraph(doc, command);
310
+ case "applyStyle":
311
+ return executeApplyStyle(doc, command);
312
+ case "insertTable":
313
+ return executeInsertTable(doc, command);
314
+ case "insertImage":
315
+ return executeInsertImage(doc, command);
316
+ case "insertHyperlink":
317
+ return executeInsertHyperlink(doc, command);
318
+ case "removeHyperlink":
319
+ return executeRemoveHyperlink(doc, command);
320
+ case "insertParagraphBreak":
321
+ return executeInsertParagraphBreak(doc, command);
322
+ case "mergeParagraphs":
323
+ return executeMergeParagraphs(doc, command);
324
+ case "splitParagraph":
325
+ return executeSplitParagraph(doc, command);
326
+ case "setVariable":
327
+ return executeSetVariable(doc, command);
328
+ case "applyVariables":
329
+ return executeApplyVariables(doc, command);
330
+ default:
331
+ const _exhaustive = command;
332
+ throw new Error(`Unknown command type: ${_exhaustive.type}`);
333
+ }
334
+ }
335
+ function executeCommands(doc, commands) {
336
+ return commands.reduce((currentDoc, command) => executeCommand(currentDoc, command), doc);
337
+ }
338
+ function cloneDocument(doc) {
339
+ return JSON.parse(JSON.stringify(doc));
340
+ }
341
+ function getBlockIndexForParagraph(body, paragraphIndex) {
342
+ let currentParagraphIndex = 0;
343
+ for (let i = 0; i < body.content.length; i++) {
344
+ if (body.content[i].type === "paragraph") {
345
+ if (currentParagraphIndex === paragraphIndex) {
346
+ return i;
347
+ }
348
+ currentParagraphIndex++;
349
+ }
350
+ }
351
+ return -1;
352
+ }
353
+ function getParagraphText(paragraph) {
354
+ let text = "";
355
+ for (const item of paragraph.content) {
356
+ if (item.type === "run") {
357
+ for (const content of item.content) {
358
+ if (content.type === "text") {
359
+ text += content.text;
360
+ }
361
+ }
362
+ } else if (item.type === "hyperlink") {
363
+ for (const child of item.children) {
364
+ if (child.type === "run") {
365
+ for (const content of child.content) {
366
+ if (content.type === "text") {
367
+ text += content.text;
368
+ }
369
+ }
370
+ }
371
+ }
372
+ }
373
+ }
374
+ return text;
375
+ }
376
+ function createTextRun(text, formatting) {
377
+ return {
378
+ type: "run",
379
+ formatting,
380
+ content: [
381
+ {
382
+ type: "text",
383
+ text
384
+ }
385
+ ]
386
+ };
387
+ }
388
+ function insertTextAtOffset(paragraph, offset, text, formatting) {
389
+ const newContent = [];
390
+ let currentOffset = 0;
391
+ let inserted = false;
392
+ for (const item of paragraph.content) {
393
+ if (item.type === "run") {
394
+ const runText = item.content.filter((c) => c.type === "text").map((c) => c.text).join("");
395
+ const runStart = currentOffset;
396
+ const runEnd = currentOffset + runText.length;
397
+ if (!inserted && offset >= runStart && offset <= runEnd) {
398
+ const insertPos = offset - runStart;
399
+ if (insertPos > 0) {
400
+ newContent.push({
401
+ ...item,
402
+ content: [{ type: "text", text: runText.slice(0, insertPos) }]
403
+ });
404
+ }
405
+ newContent.push(createTextRun(text, formatting || item.formatting));
406
+ if (insertPos < runText.length) {
407
+ newContent.push({
408
+ ...item,
409
+ content: [{ type: "text", text: runText.slice(insertPos) }]
410
+ });
411
+ }
412
+ inserted = true;
413
+ } else {
414
+ newContent.push(item);
415
+ }
416
+ currentOffset = runEnd;
417
+ } else {
418
+ newContent.push(item);
419
+ }
420
+ }
421
+ if (!inserted) {
422
+ newContent.push(createTextRun(text, formatting));
423
+ }
424
+ return newContent;
425
+ }
426
+ function deleteTextInParagraph(paragraph, startOffset, endOffset) {
427
+ const newContent = [];
428
+ let currentOffset = 0;
429
+ for (const item of paragraph.content) {
430
+ if (item.type === "run") {
431
+ const runText = item.content.filter((c) => c.type === "text").map((c) => c.text).join("");
432
+ const runStart = currentOffset;
433
+ const runEnd = currentOffset + runText.length;
434
+ if (runEnd <= startOffset || runStart >= endOffset) {
435
+ newContent.push(item);
436
+ } else {
437
+ let newText = "";
438
+ if (runStart < startOffset) {
439
+ newText += runText.slice(0, startOffset - runStart);
440
+ }
441
+ if (runEnd > endOffset) {
442
+ newText += runText.slice(endOffset - runStart);
443
+ }
444
+ if (newText.length > 0) {
445
+ newContent.push({
446
+ ...item,
447
+ content: [{ type: "text", text: newText }]
448
+ });
449
+ }
450
+ }
451
+ currentOffset = runEnd;
452
+ } else {
453
+ newContent.push(item);
454
+ }
455
+ }
456
+ return newContent;
457
+ }
458
+ function applyFormattingInParagraph(paragraph, startOffset, endOffset, formatting) {
459
+ const newContent = [];
460
+ let currentOffset = 0;
461
+ for (const item of paragraph.content) {
462
+ if (item.type === "run") {
463
+ const runText = item.content.filter((c) => c.type === "text").map((c) => c.text).join("");
464
+ const runStart = currentOffset;
465
+ const runEnd = currentOffset + runText.length;
466
+ if (runEnd <= startOffset || runStart >= endOffset) {
467
+ newContent.push(item);
468
+ } else if (runStart >= startOffset && runEnd <= endOffset) {
469
+ newContent.push({
470
+ ...item,
471
+ formatting: { ...item.formatting, ...formatting }
472
+ });
473
+ } else {
474
+ const overlapStart = Math.max(startOffset, runStart);
475
+ const overlapEnd = Math.min(endOffset, runEnd);
476
+ if (runStart < overlapStart) {
477
+ newContent.push({
478
+ ...item,
479
+ content: [{ type: "text", text: runText.slice(0, overlapStart - runStart) }]
480
+ });
481
+ }
482
+ newContent.push({
483
+ ...item,
484
+ formatting: { ...item.formatting, ...formatting },
485
+ content: [
486
+ {
487
+ type: "text",
488
+ text: runText.slice(overlapStart - runStart, overlapEnd - runStart)
489
+ }
490
+ ]
491
+ });
492
+ if (runEnd > overlapEnd) {
493
+ newContent.push({
494
+ ...item,
495
+ content: [{ type: "text", text: runText.slice(overlapEnd - runStart) }]
496
+ });
497
+ }
498
+ }
499
+ currentOffset = runEnd;
500
+ } else {
501
+ newContent.push(item);
502
+ }
503
+ }
504
+ return newContent;
505
+ }
506
+ function executeInsertText(doc, command) {
507
+ const newDoc = cloneDocument(doc);
508
+ const body = newDoc.package.document;
509
+ const blockIndex = getBlockIndexForParagraph(body, command.position.paragraphIndex);
510
+ if (blockIndex === -1) {
511
+ throw new Error(`Paragraph index ${command.position.paragraphIndex} not found`);
512
+ }
513
+ const paragraph = body.content[blockIndex];
514
+ paragraph.content = insertTextAtOffset(
515
+ paragraph,
516
+ command.position.offset,
517
+ command.text,
518
+ command.formatting
519
+ );
520
+ return newDoc;
521
+ }
522
+ function executeReplaceText(doc, command) {
523
+ const newDoc = cloneDocument(doc);
524
+ const body = newDoc.package.document;
525
+ const { start, end } = command.range;
526
+ if (start.paragraphIndex === end.paragraphIndex) {
527
+ const blockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
528
+ if (blockIndex === -1) {
529
+ throw new Error(`Paragraph index ${start.paragraphIndex} not found`);
530
+ }
531
+ const paragraph = body.content[blockIndex];
532
+ paragraph.content = deleteTextInParagraph(paragraph, start.offset, end.offset);
533
+ paragraph.content = insertTextAtOffset(
534
+ paragraph,
535
+ start.offset,
536
+ command.text,
537
+ command.formatting
538
+ );
539
+ } else {
540
+ const startBlockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
541
+ const startParagraph = body.content[startBlockIndex];
542
+ const startText = getParagraphText(startParagraph);
543
+ startParagraph.content = deleteTextInParagraph(startParagraph, start.offset, startText.length);
544
+ startParagraph.content = insertTextAtOffset(
545
+ startParagraph,
546
+ start.offset,
547
+ command.text,
548
+ command.formatting
549
+ );
550
+ const paragraphsToRemove = [];
551
+ for (let i = start.paragraphIndex + 1; i <= end.paragraphIndex; i++) {
552
+ paragraphsToRemove.push(getBlockIndexForParagraph(body, i));
553
+ }
554
+ for (let i = paragraphsToRemove.length - 1; i >= 0; i--) {
555
+ if (paragraphsToRemove[i] !== -1) {
556
+ body.content.splice(paragraphsToRemove[i], 1);
557
+ }
558
+ }
559
+ }
560
+ return newDoc;
561
+ }
562
+ function executeDeleteText(doc, command) {
563
+ const newDoc = cloneDocument(doc);
564
+ const body = newDoc.package.document;
565
+ const { start, end } = command.range;
566
+ if (start.paragraphIndex === end.paragraphIndex) {
567
+ const blockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
568
+ if (blockIndex === -1) {
569
+ throw new Error(`Paragraph index ${start.paragraphIndex} not found`);
570
+ }
571
+ const paragraph = body.content[blockIndex];
572
+ paragraph.content = deleteTextInParagraph(paragraph, start.offset, end.offset);
573
+ } else {
574
+ const startBlockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
575
+ const startParagraph = body.content[startBlockIndex];
576
+ const startText = getParagraphText(startParagraph);
577
+ startParagraph.content = deleteTextInParagraph(startParagraph, start.offset, startText.length);
578
+ const endBlockIndex = getBlockIndexForParagraph(body, end.paragraphIndex);
579
+ const endParagraph = body.content[endBlockIndex];
580
+ endParagraph.content = deleteTextInParagraph(endParagraph, 0, end.offset);
581
+ startParagraph.content.push(...endParagraph.content);
582
+ const indicesToRemove = [];
583
+ for (let i = start.paragraphIndex + 1; i <= end.paragraphIndex; i++) {
584
+ indicesToRemove.push(getBlockIndexForParagraph(body, i));
585
+ }
586
+ for (let i = indicesToRemove.length - 1; i >= 0; i--) {
587
+ if (indicesToRemove[i] !== -1) {
588
+ body.content.splice(indicesToRemove[i], 1);
589
+ }
590
+ }
591
+ }
592
+ return newDoc;
593
+ }
594
+ function executeFormatText(doc, command) {
595
+ const newDoc = cloneDocument(doc);
596
+ const body = newDoc.package.document;
597
+ const { start, end } = command.range;
598
+ if (start.paragraphIndex === end.paragraphIndex) {
599
+ const blockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
600
+ if (blockIndex === -1) {
601
+ throw new Error(`Paragraph index ${start.paragraphIndex} not found`);
602
+ }
603
+ const paragraph = body.content[blockIndex];
604
+ paragraph.content = applyFormattingInParagraph(
605
+ paragraph,
606
+ start.offset,
607
+ end.offset,
608
+ command.formatting
609
+ );
610
+ } else {
611
+ for (let i = start.paragraphIndex; i <= end.paragraphIndex; i++) {
612
+ const blockIndex = getBlockIndexForParagraph(body, i);
613
+ if (blockIndex === -1) continue;
614
+ const paragraph = body.content[blockIndex];
615
+ const paragraphText = getParagraphText(paragraph);
616
+ let startOffset = 0;
617
+ let endOffset = paragraphText.length;
618
+ if (i === start.paragraphIndex) {
619
+ startOffset = start.offset;
620
+ }
621
+ if (i === end.paragraphIndex) {
622
+ endOffset = end.offset;
623
+ }
624
+ paragraph.content = applyFormattingInParagraph(
625
+ paragraph,
626
+ startOffset,
627
+ endOffset,
628
+ command.formatting
629
+ );
630
+ }
631
+ }
632
+ return newDoc;
633
+ }
634
+ function executeFormatParagraph(doc, command) {
635
+ const newDoc = cloneDocument(doc);
636
+ const body = newDoc.package.document;
637
+ const blockIndex = getBlockIndexForParagraph(body, command.paragraphIndex);
638
+ if (blockIndex === -1) {
639
+ throw new Error(`Paragraph index ${command.paragraphIndex} not found`);
640
+ }
641
+ const paragraph = body.content[blockIndex];
642
+ paragraph.formatting = { ...paragraph.formatting, ...command.formatting };
643
+ if ("numPr" in command.formatting) {
644
+ const numPr = command.formatting.numPr;
645
+ if (numPr && numPr.numId !== void 0 && numPr.numId !== 0) {
646
+ const ilvl = numPr.ilvl ?? 0;
647
+ const isBullet = numPr.numId === 1;
648
+ let marker = isBullet ? "\u2022" : `${1}.`;
649
+ if (newDoc.package.numbering) {
650
+ const num = newDoc.package.numbering.nums.find((n) => n.numId === numPr.numId);
651
+ if (num) {
652
+ const abstractNum = newDoc.package.numbering.abstractNums.find(
653
+ (a) => a.abstractNumId === num.abstractNumId
654
+ );
655
+ if (abstractNum) {
656
+ const level = abstractNum.levels.find((l) => l.ilvl === ilvl);
657
+ if (level) {
658
+ marker = level.lvlText || marker;
659
+ }
660
+ }
661
+ }
662
+ }
663
+ paragraph.listRendering = {
664
+ level: ilvl,
665
+ numId: numPr.numId,
666
+ marker,
667
+ isBullet
668
+ };
669
+ } else {
670
+ delete paragraph.listRendering;
671
+ }
672
+ }
673
+ return newDoc;
674
+ }
675
+ function executeApplyStyle(doc, command) {
676
+ const newDoc = cloneDocument(doc);
677
+ const body = newDoc.package.document;
678
+ const blockIndex = getBlockIndexForParagraph(body, command.paragraphIndex);
679
+ if (blockIndex === -1) {
680
+ throw new Error(`Paragraph index ${command.paragraphIndex} not found`);
681
+ }
682
+ const paragraph = body.content[blockIndex];
683
+ paragraph.formatting = {
684
+ ...paragraph.formatting,
685
+ styleId: command.styleId
686
+ };
687
+ return newDoc;
688
+ }
689
+ function executeInsertTable(doc, command) {
690
+ const newDoc = cloneDocument(doc);
691
+ const body = newDoc.package.document;
692
+ const rows = [];
693
+ for (let r = 0; r < command.rows; r++) {
694
+ const cells = [];
695
+ for (let c = 0; c < command.columns; c++) {
696
+ const cellText = command.data?.[r]?.[c] || "";
697
+ cells.push({
698
+ type: "tableCell",
699
+ content: [
700
+ {
701
+ type: "paragraph",
702
+ content: cellText ? [createTextRun(cellText)] : []
703
+ }
704
+ ]
705
+ });
706
+ }
707
+ rows.push({
708
+ type: "tableRow",
709
+ formatting: r === 0 && command.hasHeader ? { header: true } : void 0,
710
+ cells
711
+ });
712
+ }
713
+ const table = {
714
+ type: "table",
715
+ rows
716
+ };
717
+ const blockIndex = getBlockIndexForParagraph(body, command.position.paragraphIndex);
718
+ if (blockIndex === -1) {
719
+ body.content.push(table);
720
+ } else {
721
+ body.content.splice(blockIndex + 1, 0, table);
722
+ }
723
+ return newDoc;
724
+ }
725
+ function executeInsertImage(doc, command) {
726
+ const newDoc = cloneDocument(doc);
727
+ const body = newDoc.package.document;
728
+ const blockIndex = getBlockIndexForParagraph(body, command.position.paragraphIndex);
729
+ if (blockIndex === -1) {
730
+ throw new Error(`Paragraph index ${command.position.paragraphIndex} not found`);
731
+ }
732
+ const paragraph = body.content[blockIndex];
733
+ const image = {
734
+ type: "image",
735
+ rId: `rId_img_${Date.now()}`,
736
+ src: command.src,
737
+ alt: command.alt,
738
+ size: {
739
+ width: (command.width || 100) * 914400,
740
+ // Convert pixels to EMU
741
+ height: (command.height || 100) * 914400
742
+ },
743
+ wrap: { type: "inline" }
744
+ };
745
+ const imageRun = {
746
+ type: "run",
747
+ content: [
748
+ {
749
+ type: "drawing",
750
+ image
751
+ }
752
+ ]
753
+ };
754
+ const newContent = insertTextAtOffset(paragraph, command.position.offset, "", void 0);
755
+ let inserted = false;
756
+ let currentOffset = 0;
757
+ for (let i = 0; i < newContent.length; i++) {
758
+ const item = newContent[i];
759
+ if (item.type === "run") {
760
+ const runText = item.content.filter((c) => c.type === "text").map((c) => c.text).join("");
761
+ currentOffset += runText.length;
762
+ if (!inserted && currentOffset >= command.position.offset) {
763
+ newContent.splice(i + 1, 0, imageRun);
764
+ inserted = true;
765
+ break;
766
+ }
767
+ }
768
+ }
769
+ if (!inserted) {
770
+ newContent.push(imageRun);
771
+ }
772
+ paragraph.content = newContent;
773
+ return newDoc;
774
+ }
775
+ function executeInsertHyperlink(doc, command) {
776
+ const newDoc = cloneDocument(doc);
777
+ const body = newDoc.package.document;
778
+ const { start, end } = command.range;
779
+ if (start.paragraphIndex !== end.paragraphIndex) {
780
+ throw new Error("Hyperlinks cannot span multiple paragraphs");
781
+ }
782
+ const blockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
783
+ if (blockIndex === -1) {
784
+ throw new Error(`Paragraph index ${start.paragraphIndex} not found`);
785
+ }
786
+ const paragraph = body.content[blockIndex];
787
+ const paragraphText = getParagraphText(paragraph);
788
+ const linkText = command.displayText || paragraphText.slice(start.offset, end.offset);
789
+ paragraph.content = deleteTextInParagraph(paragraph, start.offset, end.offset);
790
+ const hyperlink = {
791
+ type: "hyperlink",
792
+ href: command.url,
793
+ tooltip: command.tooltip,
794
+ children: [createTextRun(linkText)]
795
+ };
796
+ let inserted = false;
797
+ let currentOffset = 0;
798
+ const newContent = [];
799
+ for (const item of paragraph.content) {
800
+ if (item.type === "run") {
801
+ const runText = item.content.filter((c) => c.type === "text").map((c) => c.text).join("");
802
+ const runEnd = currentOffset + runText.length;
803
+ if (!inserted && currentOffset <= start.offset && start.offset <= runEnd) {
804
+ const insertPos = start.offset - currentOffset;
805
+ if (insertPos > 0) {
806
+ newContent.push({
807
+ ...item,
808
+ content: [{ type: "text", text: runText.slice(0, insertPos) }]
809
+ });
810
+ }
811
+ newContent.push(hyperlink);
812
+ if (insertPos < runText.length) {
813
+ newContent.push({
814
+ ...item,
815
+ content: [{ type: "text", text: runText.slice(insertPos) }]
816
+ });
817
+ }
818
+ inserted = true;
819
+ } else {
820
+ newContent.push(item);
821
+ }
822
+ currentOffset = runEnd;
823
+ } else {
824
+ newContent.push(item);
825
+ }
826
+ }
827
+ if (!inserted) {
828
+ newContent.push(hyperlink);
829
+ }
830
+ paragraph.content = newContent;
831
+ return newDoc;
832
+ }
833
+ function executeRemoveHyperlink(doc, command) {
834
+ const newDoc = cloneDocument(doc);
835
+ const body = newDoc.package.document;
836
+ const { start } = command.range;
837
+ const blockIndex = getBlockIndexForParagraph(body, start.paragraphIndex);
838
+ if (blockIndex === -1) {
839
+ throw new Error(`Paragraph index ${start.paragraphIndex} not found`);
840
+ }
841
+ const paragraph = body.content[blockIndex];
842
+ const newContent = [];
843
+ for (const item of paragraph.content) {
844
+ if (item.type === "hyperlink") {
845
+ for (const child of item.children) {
846
+ if (child.type === "run") {
847
+ newContent.push(child);
848
+ }
849
+ }
850
+ } else {
851
+ newContent.push(item);
852
+ }
853
+ }
854
+ paragraph.content = newContent;
855
+ return newDoc;
856
+ }
857
+ function executeInsertParagraphBreak(doc, command) {
858
+ const newDoc = cloneDocument(doc);
859
+ const body = newDoc.package.document;
860
+ const blockIndex = getBlockIndexForParagraph(body, command.position.paragraphIndex);
861
+ if (blockIndex === -1) {
862
+ throw new Error(`Paragraph index ${command.position.paragraphIndex} not found`);
863
+ }
864
+ const paragraph = body.content[blockIndex];
865
+ const paragraphText = getParagraphText(paragraph);
866
+ const beforeContent = deleteTextInParagraph(
867
+ { ...paragraph, content: [...paragraph.content] },
868
+ command.position.offset,
869
+ paragraphText.length
870
+ );
871
+ const afterContent = deleteTextInParagraph(
872
+ { ...paragraph, content: [...paragraph.content] },
873
+ 0,
874
+ command.position.offset
875
+ );
876
+ paragraph.content = beforeContent;
877
+ const newParagraph = {
878
+ type: "paragraph",
879
+ formatting: paragraph.formatting,
880
+ content: afterContent
881
+ };
882
+ body.content.splice(blockIndex + 1, 0, newParagraph);
883
+ return newDoc;
884
+ }
885
+ function executeMergeParagraphs(doc, command) {
886
+ const newDoc = cloneDocument(doc);
887
+ const body = newDoc.package.document;
888
+ const startBlockIndex = getBlockIndexForParagraph(body, command.paragraphIndex);
889
+ if (startBlockIndex === -1) {
890
+ throw new Error(`Paragraph index ${command.paragraphIndex} not found`);
891
+ }
892
+ const baseParagraph = body.content[startBlockIndex];
893
+ const indicesToRemove = [];
894
+ for (let i = 1; i <= command.count; i++) {
895
+ const blockIndex = getBlockIndexForParagraph(body, command.paragraphIndex + i);
896
+ if (blockIndex !== -1) {
897
+ const para = body.content[blockIndex];
898
+ baseParagraph.content.push(...para.content);
899
+ indicesToRemove.push(blockIndex);
900
+ }
901
+ }
902
+ for (let i = indicesToRemove.length - 1; i >= 0; i--) {
903
+ body.content.splice(indicesToRemove[i], 1);
904
+ }
905
+ return newDoc;
906
+ }
907
+ function executeSplitParagraph(doc, command) {
908
+ return executeInsertParagraphBreak(doc, {
909
+ position: command.position
910
+ });
911
+ }
912
+ function executeSetVariable(doc, command) {
913
+ const newDoc = cloneDocument(doc);
914
+ if (!newDoc.templateVariables) {
915
+ newDoc.templateVariables = [];
916
+ }
917
+ if (!newDoc.templateVariables.includes(command.name)) {
918
+ newDoc.templateVariables.push(command.name);
919
+ }
920
+ return newDoc;
921
+ }
922
+ function executeApplyVariables(doc, command) {
923
+ const newDoc = cloneDocument(doc);
924
+ const body = newDoc.package.document;
925
+ function replaceVariablesInRun(run) {
926
+ for (const content of run.content) {
927
+ if (content.type === "text") {
928
+ for (const [name, value] of Object.entries(command.values)) {
929
+ const pattern = new RegExp(`\\{${name}\\}`, "g");
930
+ content.text = content.text.replace(pattern, value);
931
+ }
932
+ }
933
+ }
934
+ }
935
+ function replaceVariablesInParagraph(paragraph) {
936
+ for (const item of paragraph.content) {
937
+ if (item.type === "run") {
938
+ replaceVariablesInRun(item);
939
+ } else if (item.type === "hyperlink") {
940
+ for (const child of item.children) {
941
+ if (child.type === "run") {
942
+ replaceVariablesInRun(child);
943
+ }
944
+ }
945
+ }
946
+ }
947
+ }
948
+ function replaceVariablesInBlock(block) {
949
+ if (block.type === "paragraph") {
950
+ replaceVariablesInParagraph(block);
951
+ } else if (block.type === "table") {
952
+ for (const row of block.rows) {
953
+ for (const cell of row.cells) {
954
+ for (const cellBlock of cell.content) {
955
+ replaceVariablesInBlock(cellBlock);
956
+ }
957
+ }
958
+ }
959
+ }
960
+ }
961
+ for (const block of body.content) {
962
+ replaceVariablesInBlock(block);
963
+ }
964
+ return newDoc;
965
+ }
966
+
967
+ export { PluginRegistry, createPluginRegistrar, executeCommand, executeCommands, pluginRegistry, registerPlugins };
968
+ //# sourceMappingURL=chunk-OFUT6WUQ.mjs.map
969
+ //# sourceMappingURL=chunk-OFUT6WUQ.mjs.map