pptx-viewer-mcp 2.1.7 → 2.3.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.
- package/CHANGELOG.md +12 -0
- package/README.md +20 -19
- package/dist/index.d.ts +279 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +347 -6
- package/dist/index.mjs +336 -8
- package/dist/mcp/index.js +914 -39
- package/dist/mcp/index.mjs +915 -40
- package/dist/schemas/index.d.ts +679 -1
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +373 -0
- package/dist/schemas/index.mjs +356 -1
- package/package.json +2 -2
package/dist/mcp/index.js
CHANGED
|
@@ -68,6 +68,32 @@ var ConvertToMarkdownSchema = zod.z.object({
|
|
|
68
68
|
var AccessibilityCheckSchema = zod.z.object({
|
|
69
69
|
filePath: zod.z.string().describe("Path to the PPTX file")
|
|
70
70
|
});
|
|
71
|
+
var ThemeColorRefSchema = zod.z.object({
|
|
72
|
+
scheme: zod.z.enum([
|
|
73
|
+
"dk1",
|
|
74
|
+
"lt1",
|
|
75
|
+
"dk2",
|
|
76
|
+
"lt2",
|
|
77
|
+
"accent1",
|
|
78
|
+
"accent2",
|
|
79
|
+
"accent3",
|
|
80
|
+
"accent4",
|
|
81
|
+
"accent5",
|
|
82
|
+
"accent6",
|
|
83
|
+
"hlink",
|
|
84
|
+
"folHlink",
|
|
85
|
+
"bg1",
|
|
86
|
+
"tx1",
|
|
87
|
+
"bg2",
|
|
88
|
+
"tx2",
|
|
89
|
+
"phClr"
|
|
90
|
+
]),
|
|
91
|
+
lumMod: zod.z.number().optional().describe("Multiply HSL luminance (0..1)"),
|
|
92
|
+
lumOff: zod.z.number().optional().describe("Add to HSL luminance after lumMod (0..1)"),
|
|
93
|
+
tint: zod.z.number().optional().describe("Blend towards white (0..1)"),
|
|
94
|
+
shade: zod.z.number().optional().describe("Blend towards black (0..1)"),
|
|
95
|
+
alpha: zod.z.number().optional().describe("Opacity fraction, 1 = opaque")
|
|
96
|
+
});
|
|
71
97
|
var AddElementSchema = zod.z.object({
|
|
72
98
|
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
73
99
|
slideIndex: zod.z.number().int().min(0).describe("Zero-based slide index"),
|
|
@@ -112,6 +138,12 @@ var UpdateElementSchema = zod.z.object({
|
|
|
112
138
|
fontSize: zod.z.number().optional(),
|
|
113
139
|
fontFamily: zod.z.string().optional(),
|
|
114
140
|
fontColor: zod.z.string().optional(),
|
|
141
|
+
/**
|
|
142
|
+
* A theme colour for the run text. Wins on save; resolves `fontColor`
|
|
143
|
+
* immediately when `fontColor` was not also given. Passing `fontColor`
|
|
144
|
+
* alone clears a previously-set text theme colour.
|
|
145
|
+
*/
|
|
146
|
+
fontThemeColor: ThemeColorRefSchema.optional(),
|
|
115
147
|
bold: zod.z.boolean().optional(),
|
|
116
148
|
italic: zod.z.boolean().optional(),
|
|
117
149
|
underline: zod.z.boolean().optional(),
|
|
@@ -184,6 +216,32 @@ var BatchUpdateElementsSchema = zod.z.object({
|
|
|
184
216
|
opacity: zod.z.number().min(0).max(1).optional(),
|
|
185
217
|
hidden: zod.z.boolean().optional()
|
|
186
218
|
});
|
|
219
|
+
var ThemeColorRefSchema2 = zod.z.object({
|
|
220
|
+
scheme: zod.z.enum([
|
|
221
|
+
"dk1",
|
|
222
|
+
"lt1",
|
|
223
|
+
"dk2",
|
|
224
|
+
"lt2",
|
|
225
|
+
"accent1",
|
|
226
|
+
"accent2",
|
|
227
|
+
"accent3",
|
|
228
|
+
"accent4",
|
|
229
|
+
"accent5",
|
|
230
|
+
"accent6",
|
|
231
|
+
"hlink",
|
|
232
|
+
"folHlink",
|
|
233
|
+
"bg1",
|
|
234
|
+
"tx1",
|
|
235
|
+
"bg2",
|
|
236
|
+
"tx2",
|
|
237
|
+
"phClr"
|
|
238
|
+
]),
|
|
239
|
+
lumMod: zod.z.number().optional().describe("Multiply HSL luminance (0..1)"),
|
|
240
|
+
lumOff: zod.z.number().optional().describe("Add to HSL luminance after lumMod (0..1)"),
|
|
241
|
+
tint: zod.z.number().optional().describe("Blend towards white (0..1)"),
|
|
242
|
+
shade: zod.z.number().optional().describe("Blend towards black (0..1)"),
|
|
243
|
+
alpha: zod.z.number().optional().describe("Opacity fraction, 1 = opaque")
|
|
244
|
+
});
|
|
187
245
|
var UpdateTableCellsSchema = zod.z.object({
|
|
188
246
|
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
189
247
|
slideIndex: zod.z.number().int().min(0),
|
|
@@ -210,6 +268,14 @@ var UpdateElementStyleSchema = zod.z.object({
|
|
|
210
268
|
slideIndex: zod.z.number().int().min(0),
|
|
211
269
|
elementId: zod.z.string(),
|
|
212
270
|
fillColor: zod.z.string().optional(),
|
|
271
|
+
/**
|
|
272
|
+
* A theme colour for the fill (e.g. `{ scheme: 'accent1', lumMod: 0.8 }`
|
|
273
|
+
* for "Accent 1, Lighter 80%"). When set, the shape saves as
|
|
274
|
+
* `<a:schemeClr>` and keeps following the theme after a later theme
|
|
275
|
+
* change, instead of freezing today's resolved hex. Setting `fillColor`
|
|
276
|
+
* without this clears any previously-set fill theme colour.
|
|
277
|
+
*/
|
|
278
|
+
fillThemeColor: ThemeColorRefSchema2.optional(),
|
|
213
279
|
fillMode: zod.z.string().optional(),
|
|
214
280
|
fillGradientStops: zod.z.array(
|
|
215
281
|
zod.z.object({
|
|
@@ -222,6 +288,8 @@ var UpdateElementStyleSchema = zod.z.object({
|
|
|
222
288
|
fillGradientType: zod.z.string().optional(),
|
|
223
289
|
fillOpacity: zod.z.number().optional(),
|
|
224
290
|
strokeColor: zod.z.string().optional(),
|
|
291
|
+
/** A theme colour for the outline; see `fillThemeColor` above. */
|
|
292
|
+
strokeThemeColor: ThemeColorRefSchema2.optional(),
|
|
225
293
|
strokeWidth: zod.z.number().optional(),
|
|
226
294
|
strokeDash: zod.z.string().optional(),
|
|
227
295
|
strokeOpacity: zod.z.number().optional(),
|
|
@@ -268,6 +336,116 @@ var ManageCommentsSchema = zod.z.object({
|
|
|
268
336
|
resolved: zod.z.boolean().optional(),
|
|
269
337
|
includeResolved: zod.z.boolean().optional()
|
|
270
338
|
});
|
|
339
|
+
var TABLE_STYLE_SECTIONS = [
|
|
340
|
+
"wholeTbl",
|
|
341
|
+
"band1H",
|
|
342
|
+
"band2H",
|
|
343
|
+
"band1V",
|
|
344
|
+
"band2V",
|
|
345
|
+
"lastCol",
|
|
346
|
+
"firstCol",
|
|
347
|
+
"lastRow",
|
|
348
|
+
"seCell",
|
|
349
|
+
"swCell",
|
|
350
|
+
"firstRow",
|
|
351
|
+
"neCell",
|
|
352
|
+
"nwCell"
|
|
353
|
+
];
|
|
354
|
+
var TableStyleSimpleColorSchema = zod.z.object({
|
|
355
|
+
schemeColor: zod.z.string().describe('Theme colour key (e.g. "accent1"), or "" for a non-scheme fill'),
|
|
356
|
+
tint: zod.z.number().optional().describe("0-100000"),
|
|
357
|
+
shade: zod.z.number().optional().describe("0-100000"),
|
|
358
|
+
color: zod.z.string().optional().describe('Explicit hex colour, e.g. "#FF8800"')
|
|
359
|
+
});
|
|
360
|
+
var TableStyleFillSchema = zod.z.object({
|
|
361
|
+
schemeColor: zod.z.string(),
|
|
362
|
+
tint: zod.z.number().optional(),
|
|
363
|
+
shade: zod.z.number().optional(),
|
|
364
|
+
color: zod.z.string().optional(),
|
|
365
|
+
noFill: zod.z.boolean().optional(),
|
|
366
|
+
gradient: zod.z.object({
|
|
367
|
+
type: zod.z.enum(["linear", "radial"]),
|
|
368
|
+
angle: zod.z.number().optional(),
|
|
369
|
+
stops: zod.z.array(zod.z.object({ position: zod.z.number(), fill: TableStyleSimpleColorSchema }))
|
|
370
|
+
}).optional(),
|
|
371
|
+
pattern: zod.z.object({
|
|
372
|
+
preset: zod.z.string(),
|
|
373
|
+
foreground: TableStyleSimpleColorSchema.optional(),
|
|
374
|
+
background: TableStyleSimpleColorSchema.optional()
|
|
375
|
+
}).optional(),
|
|
376
|
+
image: zod.z.object({ path: zod.z.string().optional(), data: zod.z.string().optional() }).optional()
|
|
377
|
+
});
|
|
378
|
+
var TableStyleTextSchema = zod.z.object({
|
|
379
|
+
bold: zod.z.boolean().optional(),
|
|
380
|
+
italic: zod.z.boolean().optional(),
|
|
381
|
+
underline: zod.z.boolean().optional(),
|
|
382
|
+
fontSchemeColor: zod.z.string().optional(),
|
|
383
|
+
fontTint: zod.z.number().optional(),
|
|
384
|
+
fontShade: zod.z.number().optional(),
|
|
385
|
+
fontColor: zod.z.string().optional(),
|
|
386
|
+
fontFace: zod.z.string().optional(),
|
|
387
|
+
fontRefIdx: zod.z.string().optional()
|
|
388
|
+
});
|
|
389
|
+
var TableStyleBorderSideSchema = zod.z.object({
|
|
390
|
+
width: zod.z.number().optional(),
|
|
391
|
+
dash: zod.z.string().optional(),
|
|
392
|
+
fill: TableStyleSimpleColorSchema.optional(),
|
|
393
|
+
color: zod.z.string().optional(),
|
|
394
|
+
noFill: zod.z.boolean().optional()
|
|
395
|
+
});
|
|
396
|
+
var TableStyleBordersSchema = zod.z.object({
|
|
397
|
+
left: TableStyleBorderSideSchema.optional(),
|
|
398
|
+
right: TableStyleBorderSideSchema.optional(),
|
|
399
|
+
top: TableStyleBorderSideSchema.optional(),
|
|
400
|
+
bottom: TableStyleBorderSideSchema.optional(),
|
|
401
|
+
insideH: TableStyleBorderSideSchema.optional(),
|
|
402
|
+
insideV: TableStyleBorderSideSchema.optional(),
|
|
403
|
+
tl2br: TableStyleBorderSideSchema.optional(),
|
|
404
|
+
tr2bl: TableStyleBorderSideSchema.optional()
|
|
405
|
+
});
|
|
406
|
+
var TableStyleCell3DSchema = zod.z.object({
|
|
407
|
+
bevelWidth: zod.z.number().optional(),
|
|
408
|
+
bevelHeight: zod.z.number().optional(),
|
|
409
|
+
bevelPreset: zod.z.string().optional(),
|
|
410
|
+
material: zod.z.string().optional(),
|
|
411
|
+
lightRig: zod.z.string().optional(),
|
|
412
|
+
lightRigDirection: zod.z.string().optional()
|
|
413
|
+
});
|
|
414
|
+
var SetTableStyleSectionSchema = zod.z.object({
|
|
415
|
+
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
416
|
+
styleId: zod.z.string().describe('Table style GUID, e.g. "{5C22544A-7EE6-4342-B048-85BDC9FD1C3A}"'),
|
|
417
|
+
section: zod.z.enum(TABLE_STYLE_SECTIONS).describe("Which of the 13 CT_TableStyle parts to patch"),
|
|
418
|
+
styleName: zod.z.string().optional().describe("Rename the style"),
|
|
419
|
+
fill: TableStyleFillSchema.optional(),
|
|
420
|
+
text: TableStyleTextSchema.optional(),
|
|
421
|
+
borders: TableStyleBordersSchema.optional(),
|
|
422
|
+
cell3D: TableStyleCell3DSchema.optional()
|
|
423
|
+
});
|
|
424
|
+
var CreateTableStyleSchema = zod.z.object({
|
|
425
|
+
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
426
|
+
styleName: zod.z.string().describe("Display name for the new style"),
|
|
427
|
+
basedOnStyleId: zod.z.string().optional().describe("Deep-clone every section from this existing style GUID as the starting point"),
|
|
428
|
+
setAsDefault: zod.z.boolean().optional().describe("Repoint ppt/tableStyles.xml's default style at the new one")
|
|
429
|
+
});
|
|
430
|
+
var DeleteTableStyleSchema = zod.z.object({
|
|
431
|
+
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
432
|
+
styleId: zod.z.string().describe("Table style GUID to remove"),
|
|
433
|
+
force: zod.z.boolean().optional().describe("Delete even though a table on this deck still references the style")
|
|
434
|
+
});
|
|
435
|
+
var AssignTableStyleSchema = zod.z.object({
|
|
436
|
+
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
437
|
+
slideIndex: zod.z.number().int().min(0),
|
|
438
|
+
elementId: zod.z.string().describe("Table element ID"),
|
|
439
|
+
styleId: zod.z.string().optional().describe(
|
|
440
|
+
"Table style GUID to assign. Defaults to the presentation's current default table style when omitted."
|
|
441
|
+
),
|
|
442
|
+
bandedRows: zod.z.boolean().optional(),
|
|
443
|
+
bandedColumns: zod.z.boolean().optional(),
|
|
444
|
+
firstRowHeader: zod.z.boolean().optional(),
|
|
445
|
+
lastRow: zod.z.boolean().optional(),
|
|
446
|
+
firstCol: zod.z.boolean().optional(),
|
|
447
|
+
lastCol: zod.z.boolean().optional()
|
|
448
|
+
});
|
|
271
449
|
var GetThemeInfoSchema = zod.z.object({
|
|
272
450
|
filePath: zod.z.string().describe("Path to the PPTX file")
|
|
273
451
|
});
|
|
@@ -297,6 +475,139 @@ var UpdateThemeFontsSchema = zod.z.object({
|
|
|
297
475
|
majorFont: zod.z.string().optional().describe("Heading (major) font family"),
|
|
298
476
|
minorFont: zod.z.string().optional().describe("Body (minor) font family")
|
|
299
477
|
});
|
|
478
|
+
var MarkerSymbolSchema = zod.z.enum([
|
|
479
|
+
"circle",
|
|
480
|
+
"dash",
|
|
481
|
+
"diamond",
|
|
482
|
+
"dot",
|
|
483
|
+
"none",
|
|
484
|
+
"picture",
|
|
485
|
+
"plus",
|
|
486
|
+
"square",
|
|
487
|
+
"star",
|
|
488
|
+
"triangle",
|
|
489
|
+
"x",
|
|
490
|
+
"auto"
|
|
491
|
+
]);
|
|
492
|
+
var DataLabelPositionSchema = zod.z.enum([
|
|
493
|
+
"bestFit",
|
|
494
|
+
"b",
|
|
495
|
+
"ctr",
|
|
496
|
+
"inBase",
|
|
497
|
+
"inEnd",
|
|
498
|
+
"l",
|
|
499
|
+
"outEnd",
|
|
500
|
+
"r",
|
|
501
|
+
"t"
|
|
502
|
+
]);
|
|
503
|
+
var FormatChartDataPointSchema = zod.z.object({
|
|
504
|
+
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
505
|
+
slideIndex: zod.z.number().int().min(0).describe("Zero-based slide index"),
|
|
506
|
+
elementId: zod.z.string().describe("Chart element ID"),
|
|
507
|
+
seriesIndex: zod.z.number().int().min(0).describe("Zero-based series index"),
|
|
508
|
+
pointIndex: zod.z.number().int().min(0).describe("Zero-based data point (category) index"),
|
|
509
|
+
fillColor: zod.z.string().optional().describe("Fill colour (hex) for this point only"),
|
|
510
|
+
strokeColor: zod.z.string().optional().describe("Outline colour (hex) for this point only"),
|
|
511
|
+
strokeWidth: zod.z.number().optional().describe("Outline width in points"),
|
|
512
|
+
strokeDashStyle: zod.z.string().optional().describe("Outline dash style, e.g. solid, dash, dashDot, sysDot"),
|
|
513
|
+
clearStyle: zod.z.boolean().optional().describe("Remove all per-point shape formatting"),
|
|
514
|
+
explosion: zod.z.number().nullable().optional().describe("Pie/doughnut slice pull-out distance 0-100; null clears it"),
|
|
515
|
+
marker: zod.z.object({
|
|
516
|
+
symbol: MarkerSymbolSchema.optional(),
|
|
517
|
+
size: zod.z.number().optional(),
|
|
518
|
+
fillColor: zod.z.string().optional()
|
|
519
|
+
}).nullable().optional().describe("Per-point marker override (line/scatter/bubble); null clears it")
|
|
520
|
+
});
|
|
521
|
+
var FormatChartDataLabelSchema = zod.z.object({
|
|
522
|
+
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
523
|
+
slideIndex: zod.z.number().int().min(0).describe("Zero-based slide index"),
|
|
524
|
+
elementId: zod.z.string().describe("Chart element ID"),
|
|
525
|
+
seriesIndex: zod.z.number().int().min(0).describe("Zero-based series index"),
|
|
526
|
+
pointIndex: zod.z.number().int().min(0).describe("Zero-based data point (category) index"),
|
|
527
|
+
remove: zod.z.boolean().optional().describe("Remove the per-point label override entirely"),
|
|
528
|
+
showValue: zod.z.boolean().optional(),
|
|
529
|
+
showCategory: zod.z.boolean().optional(),
|
|
530
|
+
showSeriesName: zod.z.boolean().optional(),
|
|
531
|
+
showPercent: zod.z.boolean().optional(),
|
|
532
|
+
showLegendKey: zod.z.boolean().optional(),
|
|
533
|
+
position: DataLabelPositionSchema.optional(),
|
|
534
|
+
text: zod.z.string().optional().describe("Custom label text override; '' clears it"),
|
|
535
|
+
spPr: zod.z.object({
|
|
536
|
+
fillColor: zod.z.string().optional(),
|
|
537
|
+
strokeColor: zod.z.string().optional(),
|
|
538
|
+
strokeWidth: zod.z.number().optional(),
|
|
539
|
+
strokeDashStyle: zod.z.string().optional()
|
|
540
|
+
}).nullable().optional().describe("This label's own fill/line formatting; null removes it"),
|
|
541
|
+
txPr: zod.z.object({
|
|
542
|
+
fontFamily: zod.z.string().optional(),
|
|
543
|
+
fontSize: zod.z.number().optional(),
|
|
544
|
+
bold: zod.z.boolean().optional(),
|
|
545
|
+
italic: zod.z.boolean().optional(),
|
|
546
|
+
color: zod.z.string().optional()
|
|
547
|
+
}).nullable().optional().describe("This label's own font; null removes it")
|
|
548
|
+
});
|
|
549
|
+
var FormatChartSeriesSchema = zod.z.object({
|
|
550
|
+
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
551
|
+
slideIndex: zod.z.number().int().min(0).describe("Zero-based slide index"),
|
|
552
|
+
elementId: zod.z.string().describe("Chart element ID"),
|
|
553
|
+
seriesIndex: zod.z.number().int().min(0).describe("Zero-based series index"),
|
|
554
|
+
marker: zod.z.object({
|
|
555
|
+
symbol: MarkerSymbolSchema.optional(),
|
|
556
|
+
size: zod.z.number().optional(),
|
|
557
|
+
fillColor: zod.z.string().optional(),
|
|
558
|
+
strokeColor: zod.z.string().optional(),
|
|
559
|
+
strokeWidth: zod.z.number().optional(),
|
|
560
|
+
strokeDashStyle: zod.z.string().optional()
|
|
561
|
+
}).nullable().optional().describe("Series marker (line/scatter/bubble/radar); null removes it"),
|
|
562
|
+
trendline: zod.z.object({
|
|
563
|
+
trendlineType: zod.z.enum([
|
|
564
|
+
"linear",
|
|
565
|
+
"exponential",
|
|
566
|
+
"logarithmic",
|
|
567
|
+
"polynomial",
|
|
568
|
+
"power",
|
|
569
|
+
"movingAvg"
|
|
570
|
+
]),
|
|
571
|
+
color: zod.z.string().optional(),
|
|
572
|
+
lineWidth: zod.z.number().optional().describe("Trendline width in points"),
|
|
573
|
+
lineDashStyle: zod.z.string().optional(),
|
|
574
|
+
order: zod.z.number().optional().describe("Polynomial order, 2-6"),
|
|
575
|
+
period: zod.z.number().optional().describe("Moving-average period"),
|
|
576
|
+
displayEq: zod.z.boolean().optional(),
|
|
577
|
+
displayRSq: zod.z.boolean().optional()
|
|
578
|
+
}).nullable().optional().describe("Series trendline; null removes it"),
|
|
579
|
+
errorBars: zod.z.object({
|
|
580
|
+
direction: zod.z.enum(["x", "y"]),
|
|
581
|
+
barType: zod.z.enum(["both", "minus", "plus"]),
|
|
582
|
+
valType: zod.z.enum(["cust", "fixedVal", "percentage", "stdDev", "stdErr"]),
|
|
583
|
+
val: zod.z.number().optional(),
|
|
584
|
+
customPlus: zod.z.array(zod.z.number()).optional(),
|
|
585
|
+
customMinus: zod.z.array(zod.z.number()).optional(),
|
|
586
|
+
noEndCap: zod.z.boolean().optional(),
|
|
587
|
+
color: zod.z.string().optional(),
|
|
588
|
+
width: zod.z.number().optional().describe("Error-bar line width in points"),
|
|
589
|
+
dashStyle: zod.z.string().optional()
|
|
590
|
+
}).nullable().optional().describe("Series error bars; null removes them")
|
|
591
|
+
});
|
|
592
|
+
var SetChartHelperLineSchema = zod.z.object({
|
|
593
|
+
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
594
|
+
slideIndex: zod.z.number().int().min(0).describe("Zero-based slide index"),
|
|
595
|
+
elementId: zod.z.string().describe("Chart element ID"),
|
|
596
|
+
line: zod.z.enum(["dropLines", "hiLowLines"]).describe("Which helper line to set"),
|
|
597
|
+
style: zod.z.object({
|
|
598
|
+
color: zod.z.string().optional(),
|
|
599
|
+
width: zod.z.number().optional(),
|
|
600
|
+
dashStyle: zod.z.string().optional()
|
|
601
|
+
}).nullable().describe("Line colour/width/dash; {} shows the line with defaults, null removes it")
|
|
602
|
+
});
|
|
603
|
+
var SetChartColorMapOverrideSchema = zod.z.object({
|
|
604
|
+
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
605
|
+
slideIndex: zod.z.number().int().min(0).describe("Zero-based slide index"),
|
|
606
|
+
elementId: zod.z.string().describe("Chart element ID"),
|
|
607
|
+
overrides: zod.z.record(zod.z.string(), zod.z.string()).nullable().describe(
|
|
608
|
+
'Theme colour role remap (bg1/tx1/bg2/tx2/accent1-6/hlink/folHlink -> role), e.g. { "accent1": "accent2" }; null removes the override'
|
|
609
|
+
)
|
|
610
|
+
});
|
|
300
611
|
var UpdateChartSchema = zod.z.object({
|
|
301
612
|
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
302
613
|
slideIndex: zod.z.number().int().min(0).describe("Zero-based slide index"),
|
|
@@ -376,6 +687,50 @@ var CreateChartSchema = zod.z.object({
|
|
|
376
687
|
position: zod.z.string().optional()
|
|
377
688
|
}).optional().describe("Legend configuration")
|
|
378
689
|
});
|
|
690
|
+
var PointSchema = zod.z.object({ x: zod.z.number(), y: zod.z.number() });
|
|
691
|
+
var ExtentSchema = zod.z.object({ cx: zod.z.number(), cy: zod.z.number() });
|
|
692
|
+
var ChartUserShapeInputSchema = zod.z.object({
|
|
693
|
+
kind: zod.z.enum(["sp", "cxnSp"]).optional().describe('Overlay shape kind: "sp" (text/preset shape, default) or "cxnSp" (connector).'),
|
|
694
|
+
anchor: zod.z.enum(["rel", "abs"]).optional().describe(
|
|
695
|
+
'Anchor kind: "rel" (default, resizes with the chart; needs `to`) or "abs" (fixed EMU size; needs `ext`).'
|
|
696
|
+
),
|
|
697
|
+
from: PointSchema.describe("Top-left corner as chart-relative fractions (0-1 each)."),
|
|
698
|
+
to: PointSchema.optional().describe(
|
|
699
|
+
"Bottom-right corner as chart-relative fractions; rel anchors only."
|
|
700
|
+
),
|
|
701
|
+
ext: ExtentSchema.optional().describe("Width/height in EMU; abs anchors only."),
|
|
702
|
+
prst: zod.z.string().optional().describe('Preset geometry name (e.g. "rect", "roundRect"); default "rect".'),
|
|
703
|
+
fill: zod.z.string().optional().describe('Solid fill colour, hex (e.g. "#FFFF00").'),
|
|
704
|
+
stroke: zod.z.string().optional().describe("Line colour, hex."),
|
|
705
|
+
strokeWidth: zod.z.number().optional().describe("Line width in points."),
|
|
706
|
+
text: zod.z.string().optional().describe("Plain text content, centred in the shape.")
|
|
707
|
+
});
|
|
708
|
+
var ListChartUserShapesSchema = zod.z.object({
|
|
709
|
+
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
710
|
+
slideIndex: zod.z.number().int().min(0).describe("Zero-based slide index"),
|
|
711
|
+
elementId: zod.z.string().describe("Chart element ID")
|
|
712
|
+
});
|
|
713
|
+
var AddChartUserShapeSchema = zod.z.object({
|
|
714
|
+
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
715
|
+
slideIndex: zod.z.number().int().min(0).describe("Zero-based slide index"),
|
|
716
|
+
elementId: zod.z.string().describe("Chart element ID"),
|
|
717
|
+
shape: ChartUserShapeInputSchema.describe("The overlay shape to add.")
|
|
718
|
+
});
|
|
719
|
+
var UpdateChartUserShapeSchema = zod.z.object({
|
|
720
|
+
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
721
|
+
slideIndex: zod.z.number().int().min(0).describe("Zero-based slide index"),
|
|
722
|
+
elementId: zod.z.string().describe("Chart element ID"),
|
|
723
|
+
index: zod.z.number().int().min(0).describe("Zero-based overlay-shape index (from chart_user_shape_list)"),
|
|
724
|
+
patch: ChartUserShapeInputSchema.partial().describe(
|
|
725
|
+
"Fields to overwrite; anything omitted is left as-is."
|
|
726
|
+
)
|
|
727
|
+
});
|
|
728
|
+
var RemoveChartUserShapeSchema = zod.z.object({
|
|
729
|
+
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
730
|
+
slideIndex: zod.z.number().int().min(0).describe("Zero-based slide index"),
|
|
731
|
+
elementId: zod.z.string().describe("Chart element ID"),
|
|
732
|
+
index: zod.z.number().int().min(0).describe("Zero-based overlay-shape index to remove")
|
|
733
|
+
});
|
|
379
734
|
var ManageSmartArtSchema = zod.z.object({
|
|
380
735
|
filePath: zod.z.string().describe("Path to the PPTX file"),
|
|
381
736
|
slideIndex: zod.z.number().int().min(0).describe("Zero-based slide index"),
|
|
@@ -515,39 +870,6 @@ var ApplyLayoutSchema = zod.z.object({
|
|
|
515
870
|
layoutName: zod.z.string().optional().describe("Layout name to apply"),
|
|
516
871
|
layoutType: zod.z.string().optional().describe("Layout type to apply (alternative to name)")
|
|
517
872
|
});
|
|
518
|
-
|
|
519
|
-
// src/tools/chart-pareto.ts
|
|
520
|
-
function cumulativePercent(values) {
|
|
521
|
-
const total = values.reduce((sum, value) => sum + value, 0);
|
|
522
|
-
if (total === 0) {
|
|
523
|
-
return values.map(() => 0);
|
|
524
|
-
}
|
|
525
|
-
let running = 0;
|
|
526
|
-
return values.map((value) => {
|
|
527
|
-
running += value;
|
|
528
|
-
return Math.round(running / total * 1e4) / 100;
|
|
529
|
-
});
|
|
530
|
-
}
|
|
531
|
-
function applyParetoChartTypeAlias(chart, requestedType) {
|
|
532
|
-
if (requestedType.trim().toLowerCase() !== "pareto" || !chart.chartData) {
|
|
533
|
-
return;
|
|
534
|
-
}
|
|
535
|
-
const data = chart.chartData;
|
|
536
|
-
data.chartType = "histogram";
|
|
537
|
-
const [frequency] = data.series;
|
|
538
|
-
if (!frequency) {
|
|
539
|
-
return;
|
|
540
|
-
}
|
|
541
|
-
frequency.histogramOptions = { ...frequency.histogramOptions, layout: "histogram" };
|
|
542
|
-
const hasParetoLine = data.series.some((s) => s.histogramOptions?.layout === "pareto");
|
|
543
|
-
if (!hasParetoLine) {
|
|
544
|
-
data.series.push({
|
|
545
|
-
name: "Cumulative %",
|
|
546
|
-
values: cumulativePercent(frequency.values),
|
|
547
|
-
histogramOptions: { layout: "pareto" }
|
|
548
|
-
});
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
873
|
function generateElementId() {
|
|
552
874
|
return `el-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
553
875
|
}
|
|
@@ -655,6 +977,133 @@ function validateSlideIndex(slideIndex, slideCount) {
|
|
|
655
977
|
return null;
|
|
656
978
|
}
|
|
657
979
|
|
|
980
|
+
// src/tools/chart-formatting-tools.ts
|
|
981
|
+
function findChartElement(ctx, slideIndex, elementId) {
|
|
982
|
+
const err = validateSlideIndex(slideIndex, ctx.pptxData.slides.length);
|
|
983
|
+
if (err) {
|
|
984
|
+
throw new Error(err);
|
|
985
|
+
}
|
|
986
|
+
const slide = ctx.pptxData.slides[slideIndex];
|
|
987
|
+
const el = slide.elements.find((e) => e.id === elementId);
|
|
988
|
+
if (!el) {
|
|
989
|
+
throw new Error(`Element '${elementId}' not found on slide ${slideIndex}.`);
|
|
990
|
+
}
|
|
991
|
+
if (el.type !== "chart") {
|
|
992
|
+
throw new Error(`Element '${elementId}' is not a chart.`);
|
|
993
|
+
}
|
|
994
|
+
return el;
|
|
995
|
+
}
|
|
996
|
+
function formatChartDataPoint(ctx, params) {
|
|
997
|
+
const chart = findChartElement(ctx, params.slideIndex, params.elementId);
|
|
998
|
+
if (params.clearStyle) {
|
|
999
|
+
pptxViewerCore.setChartDataPointStyle(chart, params.seriesIndex, params.pointIndex, null);
|
|
1000
|
+
} else if (params.fillColor !== void 0 || params.strokeColor !== void 0 || params.strokeWidth !== void 0 || params.strokeDashStyle !== void 0) {
|
|
1001
|
+
pptxViewerCore.setChartDataPointStyle(chart, params.seriesIndex, params.pointIndex, {
|
|
1002
|
+
...params.fillColor !== void 0 ? { fillColor: params.fillColor } : {},
|
|
1003
|
+
...params.strokeColor !== void 0 ? { strokeColor: params.strokeColor } : {},
|
|
1004
|
+
...params.strokeWidth !== void 0 ? { strokeWidth: params.strokeWidth } : {},
|
|
1005
|
+
...params.strokeDashStyle !== void 0 ? { strokeDashStyle: params.strokeDashStyle } : {}
|
|
1006
|
+
});
|
|
1007
|
+
}
|
|
1008
|
+
if (params.explosion !== void 0) {
|
|
1009
|
+
pptxViewerCore.setChartDataPointExplosion(chart, params.seriesIndex, params.pointIndex, params.explosion);
|
|
1010
|
+
}
|
|
1011
|
+
if (params.marker !== void 0) {
|
|
1012
|
+
pptxViewerCore.setChartDataPointMarker(chart, params.seriesIndex, params.pointIndex, params.marker);
|
|
1013
|
+
}
|
|
1014
|
+
return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
|
|
1015
|
+
}
|
|
1016
|
+
function formatChartDataLabel(ctx, params) {
|
|
1017
|
+
const chart = findChartElement(ctx, params.slideIndex, params.elementId);
|
|
1018
|
+
if (params.remove) {
|
|
1019
|
+
pptxViewerCore.setChartDataPointLabel(chart, params.seriesIndex, params.pointIndex, null);
|
|
1020
|
+
return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
|
|
1021
|
+
}
|
|
1022
|
+
pptxViewerCore.setChartDataPointLabel(chart, params.seriesIndex, params.pointIndex, {
|
|
1023
|
+
...params.showValue !== void 0 ? { showValue: params.showValue } : {},
|
|
1024
|
+
...params.showCategory !== void 0 ? { showCategory: params.showCategory } : {},
|
|
1025
|
+
...params.showSeriesName !== void 0 ? { showSeriesName: params.showSeriesName } : {},
|
|
1026
|
+
...params.showPercent !== void 0 ? { showPercent: params.showPercent } : {},
|
|
1027
|
+
...params.showLegendKey !== void 0 ? { showLegendKey: params.showLegendKey } : {},
|
|
1028
|
+
...params.position !== void 0 ? { position: params.position } : {},
|
|
1029
|
+
...params.text !== void 0 ? { text: params.text } : {},
|
|
1030
|
+
...params.spPr !== void 0 ? { spPr: params.spPr } : {},
|
|
1031
|
+
...params.txPr !== void 0 ? { txPr: params.txPr } : {}
|
|
1032
|
+
});
|
|
1033
|
+
return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
|
|
1034
|
+
}
|
|
1035
|
+
function formatChartSeries(ctx, params) {
|
|
1036
|
+
const chart = findChartElement(ctx, params.slideIndex, params.elementId);
|
|
1037
|
+
if (params.marker !== void 0) {
|
|
1038
|
+
if (params.marker === null) {
|
|
1039
|
+
pptxViewerCore.setChartSeriesMarker(chart, params.seriesIndex, null);
|
|
1040
|
+
} else if (params.marker.strokeColor !== void 0 || params.marker.strokeWidth !== void 0 || params.marker.strokeDashStyle !== void 0) {
|
|
1041
|
+
pptxViewerCore.setChartSeriesMarker(chart, params.seriesIndex, {
|
|
1042
|
+
symbol: params.marker.symbol ?? "circle",
|
|
1043
|
+
...params.marker.size !== void 0 ? { size: params.marker.size } : {},
|
|
1044
|
+
spPr: {
|
|
1045
|
+
...params.marker.fillColor !== void 0 ? { fillColor: params.marker.fillColor } : {},
|
|
1046
|
+
...params.marker.strokeColor !== void 0 ? { strokeColor: params.marker.strokeColor } : {},
|
|
1047
|
+
...params.marker.strokeWidth !== void 0 ? { strokeWidth: params.marker.strokeWidth } : {},
|
|
1048
|
+
...params.marker.strokeDashStyle !== void 0 ? { strokeDashStyle: params.marker.strokeDashStyle } : {}
|
|
1049
|
+
}
|
|
1050
|
+
});
|
|
1051
|
+
} else {
|
|
1052
|
+
pptxViewerCore.setChartSeriesMarker(chart, params.seriesIndex, params.marker);
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
if (params.trendline !== void 0) {
|
|
1056
|
+
pptxViewerCore.setChartSeriesTrendline(chart, params.seriesIndex, params.trendline);
|
|
1057
|
+
}
|
|
1058
|
+
if (params.errorBars !== void 0) {
|
|
1059
|
+
pptxViewerCore.setChartSeriesErrorBars(chart, params.seriesIndex, params.errorBars);
|
|
1060
|
+
}
|
|
1061
|
+
return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
|
|
1062
|
+
}
|
|
1063
|
+
function setChartHelperLineT(ctx, params) {
|
|
1064
|
+
const chart = findChartElement(ctx, params.slideIndex, params.elementId);
|
|
1065
|
+
pptxViewerCore.setChartHelperLine(chart, params.line, params.style);
|
|
1066
|
+
return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
|
|
1067
|
+
}
|
|
1068
|
+
function setChartColorMapOverrideT(ctx, params) {
|
|
1069
|
+
const chart = findChartElement(ctx, params.slideIndex, params.elementId);
|
|
1070
|
+
pptxViewerCore.setChartColorMapOverride(chart, params.overrides);
|
|
1071
|
+
return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
// src/tools/chart-pareto.ts
|
|
1075
|
+
function cumulativePercent(values) {
|
|
1076
|
+
const total = values.reduce((sum, value) => sum + value, 0);
|
|
1077
|
+
if (total === 0) {
|
|
1078
|
+
return values.map(() => 0);
|
|
1079
|
+
}
|
|
1080
|
+
let running = 0;
|
|
1081
|
+
return values.map((value) => {
|
|
1082
|
+
running += value;
|
|
1083
|
+
return Math.round(running / total * 1e4) / 100;
|
|
1084
|
+
});
|
|
1085
|
+
}
|
|
1086
|
+
function applyParetoChartTypeAlias(chart, requestedType) {
|
|
1087
|
+
if (requestedType.trim().toLowerCase() !== "pareto" || !chart.chartData) {
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
const data = chart.chartData;
|
|
1091
|
+
data.chartType = "histogram";
|
|
1092
|
+
const [frequency] = data.series;
|
|
1093
|
+
if (!frequency) {
|
|
1094
|
+
return;
|
|
1095
|
+
}
|
|
1096
|
+
frequency.histogramOptions = { ...frequency.histogramOptions, layout: "histogram" };
|
|
1097
|
+
const hasParetoLine = data.series.some((s) => s.histogramOptions?.layout === "pareto");
|
|
1098
|
+
if (!hasParetoLine) {
|
|
1099
|
+
data.series.push({
|
|
1100
|
+
name: "Cumulative %",
|
|
1101
|
+
values: cumulativePercent(frequency.values),
|
|
1102
|
+
histogramOptions: { layout: "pareto" }
|
|
1103
|
+
});
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
|
|
658
1107
|
// src/tools/chart-tools.ts
|
|
659
1108
|
function updateChart(ctx, params) {
|
|
660
1109
|
const err = validateSlideIndex(params.slideIndex, ctx.pptxData.slides.length);
|
|
@@ -795,6 +1244,67 @@ function createChart(ctx, params) {
|
|
|
795
1244
|
result: { elementId: chart.id, slideIndex: params.slideIndex }
|
|
796
1245
|
};
|
|
797
1246
|
}
|
|
1247
|
+
function findChartElement2(ctx, slideIndex, elementId) {
|
|
1248
|
+
const err = validateSlideIndex(slideIndex, ctx.pptxData.slides.length);
|
|
1249
|
+
if (err) {
|
|
1250
|
+
throw new Error(err);
|
|
1251
|
+
}
|
|
1252
|
+
const slide = ctx.pptxData.slides[slideIndex];
|
|
1253
|
+
const el = slide.elements.find((e) => e.id === elementId);
|
|
1254
|
+
if (!el) {
|
|
1255
|
+
throw new Error(`Element '${elementId}' not found on slide ${slideIndex}.`);
|
|
1256
|
+
}
|
|
1257
|
+
if (el.type !== "chart") {
|
|
1258
|
+
throw new Error(`Element '${elementId}' is not a chart.`);
|
|
1259
|
+
}
|
|
1260
|
+
return el;
|
|
1261
|
+
}
|
|
1262
|
+
function buildShape(input) {
|
|
1263
|
+
return {
|
|
1264
|
+
kind: input.kind ?? "sp",
|
|
1265
|
+
anchor: input.anchor ?? "rel",
|
|
1266
|
+
from: input.from,
|
|
1267
|
+
...input.to ? { to: input.to } : {},
|
|
1268
|
+
...input.ext ? { ext: input.ext } : {},
|
|
1269
|
+
...input.prst ? { prst: input.prst } : {},
|
|
1270
|
+
...input.fill ? { fill: input.fill } : {},
|
|
1271
|
+
...input.stroke ? { stroke: input.stroke } : {},
|
|
1272
|
+
...input.strokeWidth !== void 0 ? { strokeWidth: input.strokeWidth } : {},
|
|
1273
|
+
...input.text ? { paragraphs: [{ text: input.text, align: "ctr" }] } : {}
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
1276
|
+
function listChartUserShapesT(ctx, params) {
|
|
1277
|
+
const chart = findChartElement2(ctx, params.slideIndex, params.elementId);
|
|
1278
|
+
return { pptxData: ctx.pptxData, dirty: false, result: { shapes: pptxViewerCore.listChartUserShapes(chart) } };
|
|
1279
|
+
}
|
|
1280
|
+
function addChartUserShapeT(ctx, params) {
|
|
1281
|
+
const chart = findChartElement2(ctx, params.slideIndex, params.elementId);
|
|
1282
|
+
pptxViewerCore.addChartUserShape(chart, buildShape(params.shape));
|
|
1283
|
+
const index = (chart.chartData?.userShapes?.length ?? 1) - 1;
|
|
1284
|
+
return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId, index } };
|
|
1285
|
+
}
|
|
1286
|
+
function updateChartUserShapeT(ctx, params) {
|
|
1287
|
+
const chart = findChartElement2(ctx, params.slideIndex, params.elementId);
|
|
1288
|
+
const patch = {
|
|
1289
|
+
...params.patch.kind ? { kind: params.patch.kind } : {},
|
|
1290
|
+
...params.patch.anchor ? { anchor: params.patch.anchor } : {},
|
|
1291
|
+
...params.patch.from ? { from: params.patch.from } : {},
|
|
1292
|
+
...params.patch.to ? { to: params.patch.to } : {},
|
|
1293
|
+
...params.patch.ext ? { ext: params.patch.ext } : {},
|
|
1294
|
+
...params.patch.prst ? { prst: params.patch.prst } : {},
|
|
1295
|
+
...params.patch.fill ? { fill: params.patch.fill } : {},
|
|
1296
|
+
...params.patch.stroke ? { stroke: params.patch.stroke } : {},
|
|
1297
|
+
...params.patch.strokeWidth !== void 0 ? { strokeWidth: params.patch.strokeWidth } : {},
|
|
1298
|
+
...params.patch.text !== void 0 ? { paragraphs: [{ text: params.patch.text, align: "ctr" }] } : {}
|
|
1299
|
+
};
|
|
1300
|
+
pptxViewerCore.updateChartUserShape(chart, params.index, patch);
|
|
1301
|
+
return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
|
|
1302
|
+
}
|
|
1303
|
+
function removeChartUserShapeT(ctx, params) {
|
|
1304
|
+
const chart = findChartElement2(ctx, params.slideIndex, params.elementId);
|
|
1305
|
+
pptxViewerCore.removeChartUserShape(chart, params.index);
|
|
1306
|
+
return { pptxData: ctx.pptxData, dirty: true, result: { elementId: params.elementId } };
|
|
1307
|
+
}
|
|
798
1308
|
var MAX_REGEX_LEN = 200;
|
|
799
1309
|
function hasNestedUnboundedQuantifier(pattern) {
|
|
800
1310
|
return /\([^)]*[+*]\)[+*]/u.test(pattern);
|
|
@@ -1319,8 +1829,17 @@ function updateElement(ctx, params) {
|
|
|
1319
1829
|
if (params.fontFamily !== void 0) {
|
|
1320
1830
|
textEl.textStyle.fontFamily = params.fontFamily;
|
|
1321
1831
|
}
|
|
1322
|
-
if (params.
|
|
1832
|
+
if (params.fontThemeColor !== void 0) {
|
|
1833
|
+
textEl.textStyle.colorRef = params.fontThemeColor;
|
|
1834
|
+
const resolved = pptxViewerCore.resolveThemeColorRef(params.fontThemeColor, ctx.pptxData.themeColorMap);
|
|
1835
|
+
if (params.fontColor !== void 0) {
|
|
1836
|
+
textEl.textStyle.color = params.fontColor;
|
|
1837
|
+
} else if (resolved) {
|
|
1838
|
+
textEl.textStyle.color = resolved;
|
|
1839
|
+
}
|
|
1840
|
+
} else if (params.fontColor !== void 0) {
|
|
1323
1841
|
textEl.textStyle.color = params.fontColor;
|
|
1842
|
+
textEl.textStyle.colorRef = void 0;
|
|
1324
1843
|
}
|
|
1325
1844
|
if (params.bold !== void 0) {
|
|
1326
1845
|
textEl.textStyle.bold = params.bold;
|
|
@@ -2560,8 +3079,17 @@ function updateElementStyle(ctx, params) {
|
|
|
2560
3079
|
el.shapeStyle = {};
|
|
2561
3080
|
}
|
|
2562
3081
|
const ss = el.shapeStyle;
|
|
2563
|
-
if (params.
|
|
3082
|
+
if (params.fillThemeColor !== void 0) {
|
|
3083
|
+
ss.fillColorRef = params.fillThemeColor;
|
|
3084
|
+
const resolved = pptxViewerCore.resolveThemeColorRef(params.fillThemeColor, ctx.pptxData.themeColorMap);
|
|
3085
|
+
if (params.fillColor !== void 0) {
|
|
3086
|
+
ss.fillColor = params.fillColor;
|
|
3087
|
+
} else if (resolved) {
|
|
3088
|
+
ss.fillColor = resolved;
|
|
3089
|
+
}
|
|
3090
|
+
} else if (params.fillColor !== void 0) {
|
|
2564
3091
|
ss.fillColor = params.fillColor;
|
|
3092
|
+
ss.fillColorRef = void 0;
|
|
2565
3093
|
}
|
|
2566
3094
|
if (params.fillMode !== void 0) {
|
|
2567
3095
|
ss.fillMode = params.fillMode;
|
|
@@ -2578,8 +3106,17 @@ function updateElementStyle(ctx, params) {
|
|
|
2578
3106
|
if (params.fillOpacity !== void 0) {
|
|
2579
3107
|
ss.fillOpacity = params.fillOpacity;
|
|
2580
3108
|
}
|
|
2581
|
-
if (params.
|
|
3109
|
+
if (params.strokeThemeColor !== void 0) {
|
|
3110
|
+
ss.strokeColorRef = params.strokeThemeColor;
|
|
3111
|
+
const resolved = pptxViewerCore.resolveThemeColorRef(params.strokeThemeColor, ctx.pptxData.themeColorMap);
|
|
3112
|
+
if (params.strokeColor !== void 0) {
|
|
3113
|
+
ss.strokeColor = params.strokeColor;
|
|
3114
|
+
} else if (resolved) {
|
|
3115
|
+
ss.strokeColor = resolved;
|
|
3116
|
+
}
|
|
3117
|
+
} else if (params.strokeColor !== void 0) {
|
|
2582
3118
|
ss.strokeColor = params.strokeColor;
|
|
3119
|
+
ss.strokeColorRef = void 0;
|
|
2583
3120
|
}
|
|
2584
3121
|
if (params.strokeWidth !== void 0) {
|
|
2585
3122
|
ss.strokeWidth = params.strokeWidth;
|
|
@@ -2729,6 +3266,142 @@ function runAccessibilityCheck(ctx) {
|
|
|
2729
3266
|
}
|
|
2730
3267
|
};
|
|
2731
3268
|
}
|
|
3269
|
+
function findTableElement(ctx, slideIndex, elementId) {
|
|
3270
|
+
const err = validateSlideIndex(slideIndex, ctx.pptxData.slides.length);
|
|
3271
|
+
if (err) {
|
|
3272
|
+
throw new Error(err);
|
|
3273
|
+
}
|
|
3274
|
+
const slide = ctx.pptxData.slides[slideIndex];
|
|
3275
|
+
const el = slide.elements.find((e) => e.id === elementId);
|
|
3276
|
+
if (!el) {
|
|
3277
|
+
throw new Error(`Element '${elementId}' not found on slide ${slideIndex}.`);
|
|
3278
|
+
}
|
|
3279
|
+
if (el.type !== "table") {
|
|
3280
|
+
throw new Error(`Element '${elementId}' is not a table.`);
|
|
3281
|
+
}
|
|
3282
|
+
return el;
|
|
3283
|
+
}
|
|
3284
|
+
function tableStyleIdsInUse(ctx) {
|
|
3285
|
+
const used = /* @__PURE__ */ new Set();
|
|
3286
|
+
for (const slide of ctx.pptxData.slides) {
|
|
3287
|
+
for (const el of slide.elements) {
|
|
3288
|
+
if (el.type === "table" && el.tableData?.tableStyleId) {
|
|
3289
|
+
used.add(pptxViewerCore.normalizeTableStyleGuid(el.tableData.tableStyleId));
|
|
3290
|
+
}
|
|
3291
|
+
}
|
|
3292
|
+
}
|
|
3293
|
+
return used;
|
|
3294
|
+
}
|
|
3295
|
+
function setTableStyleSection(ctx, params) {
|
|
3296
|
+
if (!pptxViewerCore.TABLE_STYLE_PART_SEQUENCE.includes(params.section)) {
|
|
3297
|
+
throw new Error(
|
|
3298
|
+
`Unknown table style section '${params.section}'. Valid sections: ${pptxViewerCore.TABLE_STYLE_PART_SEQUENCE.join(", ")}.`
|
|
3299
|
+
);
|
|
3300
|
+
}
|
|
3301
|
+
const map = ctx.pptxData.tableStyleMap ?? {};
|
|
3302
|
+
ctx.pptxData.tableStyleMap = map;
|
|
3303
|
+
const normalizedId = pptxViewerCore.normalizeTableStyleGuid(params.styleId);
|
|
3304
|
+
const entry = map[normalizedId];
|
|
3305
|
+
if (!entry) {
|
|
3306
|
+
throw new Error(
|
|
3307
|
+
`Table style '${params.styleId}' is not loaded in this presentation. Use create_table_style to add a new one.`
|
|
3308
|
+
);
|
|
3309
|
+
}
|
|
3310
|
+
if (params.styleName !== void 0) {
|
|
3311
|
+
entry.styleName = params.styleName;
|
|
3312
|
+
}
|
|
3313
|
+
const mutableEntry = entry;
|
|
3314
|
+
if (params.fill !== void 0) {
|
|
3315
|
+
mutableEntry[`${params.section}Fill`] = params.fill;
|
|
3316
|
+
}
|
|
3317
|
+
if (params.text !== void 0) {
|
|
3318
|
+
mutableEntry[`${params.section}Text`] = params.text;
|
|
3319
|
+
}
|
|
3320
|
+
if (params.borders !== void 0) {
|
|
3321
|
+
mutableEntry[`${params.section}Borders`] = params.borders;
|
|
3322
|
+
}
|
|
3323
|
+
if (params.cell3D !== void 0) {
|
|
3324
|
+
mutableEntry[`${params.section}Cell3D`] = params.cell3D;
|
|
3325
|
+
}
|
|
3326
|
+
return {
|
|
3327
|
+
pptxData: ctx.pptxData,
|
|
3328
|
+
dirty: true,
|
|
3329
|
+
result: { styleId: normalizedId, section: params.section }
|
|
3330
|
+
};
|
|
3331
|
+
}
|
|
3332
|
+
function createTableStyle(ctx, params) {
|
|
3333
|
+
const map = ctx.pptxData.tableStyleMap ?? {};
|
|
3334
|
+
ctx.pptxData.tableStyleMap = map;
|
|
3335
|
+
const basedOn = params.basedOnStyleId ? map[pptxViewerCore.normalizeTableStyleGuid(params.basedOnStyleId)] : void 0;
|
|
3336
|
+
if (params.basedOnStyleId && !basedOn) {
|
|
3337
|
+
throw new Error(`basedOnStyleId '${params.basedOnStyleId}' is not a loaded table style.`);
|
|
3338
|
+
}
|
|
3339
|
+
const entry = pptxViewerCore.createTableStyleEntry(map, { styleName: params.styleName, basedOn });
|
|
3340
|
+
pptxViewerCore.addTableStyleToMap(map, entry);
|
|
3341
|
+
return {
|
|
3342
|
+
pptxData: ctx.pptxData,
|
|
3343
|
+
dirty: true,
|
|
3344
|
+
result: { styleId: entry.styleId },
|
|
3345
|
+
...params.setAsDefault ? { saveOptions: { tableStylesDefaultId: entry.styleId } } : {}
|
|
3346
|
+
};
|
|
3347
|
+
}
|
|
3348
|
+
function deleteTableStyle(ctx, params) {
|
|
3349
|
+
const normalizedId = pptxViewerCore.normalizeTableStyleGuid(params.styleId);
|
|
3350
|
+
if (!params.force) {
|
|
3351
|
+
const used = tableStyleIdsInUse(ctx);
|
|
3352
|
+
if (used.has(normalizedId)) {
|
|
3353
|
+
throw new Error(
|
|
3354
|
+
`Table style '${params.styleId}' is assigned to at least one table on this deck. Reassign those tables first, or pass force: true.`
|
|
3355
|
+
);
|
|
3356
|
+
}
|
|
3357
|
+
}
|
|
3358
|
+
const map = ctx.pptxData.tableStyleMap ?? {};
|
|
3359
|
+
ctx.pptxData.tableStyleMap = map;
|
|
3360
|
+
pptxViewerCore.deleteTableStyleFromMap(map, normalizedId);
|
|
3361
|
+
return {
|
|
3362
|
+
pptxData: ctx.pptxData,
|
|
3363
|
+
dirty: true,
|
|
3364
|
+
result: { deleted: true },
|
|
3365
|
+
saveOptions: { tableStylesToDelete: [normalizedId] }
|
|
3366
|
+
};
|
|
3367
|
+
}
|
|
3368
|
+
function assignTableStyle(ctx, params) {
|
|
3369
|
+
const el = findTableElement(ctx, params.slideIndex, params.elementId);
|
|
3370
|
+
if (!el.tableData) {
|
|
3371
|
+
throw new Error(`Table '${params.elementId}' has no tableData.`);
|
|
3372
|
+
}
|
|
3373
|
+
const styleId = params.styleId ?? ctx.pptxData.tableStylesDefaultId;
|
|
3374
|
+
if (!styleId) {
|
|
3375
|
+
throw new Error(
|
|
3376
|
+
"styleId was not provided and this presentation has no tableStylesDefaultId to fall back to."
|
|
3377
|
+
);
|
|
3378
|
+
}
|
|
3379
|
+
const normalizedId = pptxViewerCore.normalizeTableStyleGuid(styleId);
|
|
3380
|
+
el.tableData.tableStyleId = normalizedId;
|
|
3381
|
+
if (params.bandedRows !== void 0) {
|
|
3382
|
+
el.tableData.bandedRows = params.bandedRows;
|
|
3383
|
+
}
|
|
3384
|
+
if (params.bandedColumns !== void 0) {
|
|
3385
|
+
el.tableData.bandedColumns = params.bandedColumns;
|
|
3386
|
+
}
|
|
3387
|
+
if (params.firstRowHeader !== void 0) {
|
|
3388
|
+
el.tableData.firstRowHeader = params.firstRowHeader;
|
|
3389
|
+
}
|
|
3390
|
+
if (params.lastRow !== void 0) {
|
|
3391
|
+
el.tableData.lastRow = params.lastRow;
|
|
3392
|
+
}
|
|
3393
|
+
if (params.firstCol !== void 0) {
|
|
3394
|
+
el.tableData.firstCol = params.firstCol;
|
|
3395
|
+
}
|
|
3396
|
+
if (params.lastCol !== void 0) {
|
|
3397
|
+
el.tableData.lastCol = params.lastCol;
|
|
3398
|
+
}
|
|
3399
|
+
return {
|
|
3400
|
+
pptxData: ctx.pptxData,
|
|
3401
|
+
dirty: true,
|
|
3402
|
+
result: { elementId: params.elementId, styleId: normalizedId }
|
|
3403
|
+
};
|
|
3404
|
+
}
|
|
2732
3405
|
|
|
2733
3406
|
// src/tools/table-tools.ts
|
|
2734
3407
|
function updateTableCells(ctx, params) {
|
|
@@ -3008,11 +3681,17 @@ async function loadPresentation(filePath, execCtx) {
|
|
|
3008
3681
|
const pptxData = await handler.load(rawBytes.buffer);
|
|
3009
3682
|
return { pptxData, rawBytes };
|
|
3010
3683
|
}
|
|
3011
|
-
async function savePresentation(filePath, pptxData, rawBytes, execCtx) {
|
|
3684
|
+
async function savePresentation(filePath, pptxData, rawBytes, execCtx, tableStyleSaveOptions) {
|
|
3012
3685
|
const handler = new pptxViewerCore.PptxHandler();
|
|
3013
3686
|
await handler.load(rawBytes.buffer);
|
|
3014
3687
|
const outputBytes = await handler.save(pptxData.slides, {
|
|
3015
|
-
headerFooter: pptxData.headerFooter
|
|
3688
|
+
headerFooter: pptxData.headerFooter,
|
|
3689
|
+
// `pptxData.tableStyleMap` carries any in-memory table-style edits a
|
|
3690
|
+
// tool made (e.g. `set_table_style_section`, `create_table_style`);
|
|
3691
|
+
// without forwarding it here those edits were silently dropped on
|
|
3692
|
+
// save even though the core save pipeline already supports them.
|
|
3693
|
+
tableStyles: pptxData.tableStyleMap,
|
|
3694
|
+
...tableStyleSaveOptions
|
|
3016
3695
|
});
|
|
3017
3696
|
if (execCtx.collaboration) {
|
|
3018
3697
|
const room = execCtx.collaboration.getRoom(filePath);
|
|
@@ -3044,7 +3723,13 @@ async function executeToolWithContext(filePath, execCtx, toolFn) {
|
|
|
3044
3723
|
const { pptxData, rawBytes } = await loadPresentation(filePath, execCtx);
|
|
3045
3724
|
const toolResult = await toolFn({ pptxData });
|
|
3046
3725
|
if (toolResult.dirty) {
|
|
3047
|
-
const saveResult = await savePresentation(
|
|
3726
|
+
const saveResult = await savePresentation(
|
|
3727
|
+
filePath,
|
|
3728
|
+
toolResult.pptxData,
|
|
3729
|
+
rawBytes,
|
|
3730
|
+
execCtx,
|
|
3731
|
+
toolResult.saveOptions
|
|
3732
|
+
);
|
|
3048
3733
|
return { ...toolResult.result, ...saveResult };
|
|
3049
3734
|
}
|
|
3050
3735
|
return toolResult.result;
|
|
@@ -3524,6 +4209,70 @@ function createServer() {
|
|
|
3524
4209
|
};
|
|
3525
4210
|
}
|
|
3526
4211
|
);
|
|
4212
|
+
server2.registerTool(
|
|
4213
|
+
"set_table_style_section",
|
|
4214
|
+
{
|
|
4215
|
+
description: "Patch the fill, text, borders, or cell3D of one section (wholeTbl, banding, first/last row/col, or a corner cell) of an existing loaded table style",
|
|
4216
|
+
inputSchema: SetTableStyleSectionSchema.shape
|
|
4217
|
+
},
|
|
4218
|
+
async (params) => {
|
|
4219
|
+
const result = await runMcpTool(
|
|
4220
|
+
params.filePath,
|
|
4221
|
+
(ctx) => setTableStyleSection(ctx, params)
|
|
4222
|
+
);
|
|
4223
|
+
return {
|
|
4224
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
4225
|
+
};
|
|
4226
|
+
}
|
|
4227
|
+
);
|
|
4228
|
+
server2.registerTool(
|
|
4229
|
+
"create_table_style",
|
|
4230
|
+
{
|
|
4231
|
+
description: "Create a new table style (optionally cloned from an existing one) and optionally set it as the default",
|
|
4232
|
+
inputSchema: CreateTableStyleSchema.shape
|
|
4233
|
+
},
|
|
4234
|
+
async (params) => {
|
|
4235
|
+
const result = await runMcpTool(
|
|
4236
|
+
params.filePath,
|
|
4237
|
+
(ctx) => createTableStyle(ctx, params)
|
|
4238
|
+
);
|
|
4239
|
+
return {
|
|
4240
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
4241
|
+
};
|
|
4242
|
+
}
|
|
4243
|
+
);
|
|
4244
|
+
server2.registerTool(
|
|
4245
|
+
"delete_table_style",
|
|
4246
|
+
{
|
|
4247
|
+
description: "Remove a table style from the presentation",
|
|
4248
|
+
inputSchema: DeleteTableStyleSchema.shape
|
|
4249
|
+
},
|
|
4250
|
+
async (params) => {
|
|
4251
|
+
const result = await runMcpTool(
|
|
4252
|
+
params.filePath,
|
|
4253
|
+
(ctx) => deleteTableStyle(ctx, params)
|
|
4254
|
+
);
|
|
4255
|
+
return {
|
|
4256
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
4257
|
+
};
|
|
4258
|
+
}
|
|
4259
|
+
);
|
|
4260
|
+
server2.registerTool(
|
|
4261
|
+
"assign_table_style",
|
|
4262
|
+
{
|
|
4263
|
+
description: "Assign a table style (and row/column emphasis flags) to an existing table",
|
|
4264
|
+
inputSchema: AssignTableStyleSchema.shape
|
|
4265
|
+
},
|
|
4266
|
+
async (params) => {
|
|
4267
|
+
const result = await runMcpTool(
|
|
4268
|
+
params.filePath,
|
|
4269
|
+
(ctx) => assignTableStyle(ctx, params)
|
|
4270
|
+
);
|
|
4271
|
+
return {
|
|
4272
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
4273
|
+
};
|
|
4274
|
+
}
|
|
4275
|
+
);
|
|
3527
4276
|
server2.registerTool(
|
|
3528
4277
|
"update_element_style",
|
|
3529
4278
|
{
|
|
@@ -3770,6 +4519,132 @@ function createServer() {
|
|
|
3770
4519
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
3771
4520
|
}
|
|
3772
4521
|
);
|
|
4522
|
+
server2.registerTool(
|
|
4523
|
+
"format_chart_data_point",
|
|
4524
|
+
{
|
|
4525
|
+
description: "Set per-data-point chart formatting: fill/stroke colour, stroke width, dash style (c:dPt/c:spPr), explosion, and marker override",
|
|
4526
|
+
inputSchema: FormatChartDataPointSchema.shape
|
|
4527
|
+
},
|
|
4528
|
+
async (params) => {
|
|
4529
|
+
const result = await runMcpTool(
|
|
4530
|
+
params.filePath,
|
|
4531
|
+
(ctx) => formatChartDataPoint(ctx, params)
|
|
4532
|
+
);
|
|
4533
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
4534
|
+
}
|
|
4535
|
+
);
|
|
4536
|
+
server2.registerTool(
|
|
4537
|
+
"format_chart_data_label",
|
|
4538
|
+
{
|
|
4539
|
+
description: "Set a per-data-point data-label override (c:dLbl): show flags, position, custom text, and the label's own fill/line formatting (c:spPr) and font (c:txPr)",
|
|
4540
|
+
inputSchema: FormatChartDataLabelSchema.shape
|
|
4541
|
+
},
|
|
4542
|
+
async (params) => {
|
|
4543
|
+
const result = await runMcpTool(
|
|
4544
|
+
params.filePath,
|
|
4545
|
+
(ctx) => formatChartDataLabel(ctx, params)
|
|
4546
|
+
);
|
|
4547
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
4548
|
+
}
|
|
4549
|
+
);
|
|
4550
|
+
server2.registerTool(
|
|
4551
|
+
"format_chart_series",
|
|
4552
|
+
{
|
|
4553
|
+
description: "Set a chart series marker (c:marker), trendline (c:trendline, incl. line width/dash), or error bars (c:errBars, incl. line width/dash)",
|
|
4554
|
+
inputSchema: FormatChartSeriesSchema.shape
|
|
4555
|
+
},
|
|
4556
|
+
async (params) => {
|
|
4557
|
+
const result = await runMcpTool(
|
|
4558
|
+
params.filePath,
|
|
4559
|
+
(ctx) => formatChartSeries(ctx, params)
|
|
4560
|
+
);
|
|
4561
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
4562
|
+
}
|
|
4563
|
+
);
|
|
4564
|
+
server2.registerTool(
|
|
4565
|
+
"set_chart_helper_line",
|
|
4566
|
+
{
|
|
4567
|
+
description: "Set or remove a chart-level helper line on a line/stock/combo chart: c:dropLines or c:hiLowLines",
|
|
4568
|
+
inputSchema: SetChartHelperLineSchema.shape
|
|
4569
|
+
},
|
|
4570
|
+
async (params) => {
|
|
4571
|
+
const result = await runMcpTool(
|
|
4572
|
+
params.filePath,
|
|
4573
|
+
(ctx) => setChartHelperLineT(ctx, params)
|
|
4574
|
+
);
|
|
4575
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
4576
|
+
}
|
|
4577
|
+
);
|
|
4578
|
+
server2.registerTool(
|
|
4579
|
+
"set_chart_color_map_override",
|
|
4580
|
+
{
|
|
4581
|
+
description: "Set or remove a chart's theme colour-map override (c:clrMapOvr), remapping theme colour roles for this chart only",
|
|
4582
|
+
inputSchema: SetChartColorMapOverrideSchema.shape
|
|
4583
|
+
},
|
|
4584
|
+
async (params) => {
|
|
4585
|
+
const result = await runMcpTool(
|
|
4586
|
+
params.filePath,
|
|
4587
|
+
(ctx) => setChartColorMapOverrideT(ctx, params)
|
|
4588
|
+
);
|
|
4589
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
4590
|
+
}
|
|
4591
|
+
);
|
|
4592
|
+
server2.registerTool(
|
|
4593
|
+
"chart_user_shape_list",
|
|
4594
|
+
{
|
|
4595
|
+
description: "List a chart's drawing-overlay shapes (c:userShapes)",
|
|
4596
|
+
inputSchema: ListChartUserShapesSchema.shape
|
|
4597
|
+
},
|
|
4598
|
+
async (params) => {
|
|
4599
|
+
const result = await runMcpTool(
|
|
4600
|
+
params.filePath,
|
|
4601
|
+
(ctx) => listChartUserShapesT(ctx, params)
|
|
4602
|
+
);
|
|
4603
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
4604
|
+
}
|
|
4605
|
+
);
|
|
4606
|
+
server2.registerTool(
|
|
4607
|
+
"chart_user_shape_add",
|
|
4608
|
+
{
|
|
4609
|
+
description: "Add a drawing-overlay shape (text box or connector) to a chart's c:userShapes",
|
|
4610
|
+
inputSchema: AddChartUserShapeSchema.shape
|
|
4611
|
+
},
|
|
4612
|
+
async (params) => {
|
|
4613
|
+
const result = await runMcpTool(
|
|
4614
|
+
params.filePath,
|
|
4615
|
+
(ctx) => addChartUserShapeT(ctx, params)
|
|
4616
|
+
);
|
|
4617
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
4618
|
+
}
|
|
4619
|
+
);
|
|
4620
|
+
server2.registerTool(
|
|
4621
|
+
"chart_user_shape_update",
|
|
4622
|
+
{
|
|
4623
|
+
description: "Move, resize, or restyle one of a chart's drawing-overlay shapes by index",
|
|
4624
|
+
inputSchema: UpdateChartUserShapeSchema.shape
|
|
4625
|
+
},
|
|
4626
|
+
async (params) => {
|
|
4627
|
+
const result = await runMcpTool(
|
|
4628
|
+
params.filePath,
|
|
4629
|
+
(ctx) => updateChartUserShapeT(ctx, params)
|
|
4630
|
+
);
|
|
4631
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
4632
|
+
}
|
|
4633
|
+
);
|
|
4634
|
+
server2.registerTool(
|
|
4635
|
+
"chart_user_shape_remove",
|
|
4636
|
+
{
|
|
4637
|
+
description: "Remove one of a chart's drawing-overlay shapes by index",
|
|
4638
|
+
inputSchema: RemoveChartUserShapeSchema.shape
|
|
4639
|
+
},
|
|
4640
|
+
async (params) => {
|
|
4641
|
+
const result = await runMcpTool(
|
|
4642
|
+
params.filePath,
|
|
4643
|
+
(ctx) => removeChartUserShapeT(ctx, params)
|
|
4644
|
+
);
|
|
4645
|
+
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
4646
|
+
}
|
|
4647
|
+
);
|
|
3773
4648
|
server2.registerTool(
|
|
3774
4649
|
"manage_smart_art",
|
|
3775
4650
|
{
|