yumiamd 0.1.25 → 0.1.27
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/dist/bin.js +1 -1
- package/dist/{chunk-PRZ5CFRH.js → chunk-FTPWLNJL.js} +517 -157
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +10 -10
package/dist/bin.js
CHANGED
|
@@ -1560,9 +1560,21 @@ var NativeYumiaParser = class {
|
|
|
1560
1560
|
case "h1":
|
|
1561
1561
|
case "h2":
|
|
1562
1562
|
case "h3": {
|
|
1563
|
-
const
|
|
1564
|
-
|
|
1565
|
-
|
|
1563
|
+
const lvlMatch = tok.args.match(/^(?:level=)?([1-4])\b/);
|
|
1564
|
+
let level = 2;
|
|
1565
|
+
let text = tok.args;
|
|
1566
|
+
if (tok.command === "h1") {
|
|
1567
|
+
level = 1;
|
|
1568
|
+
} else if (tok.command === "h2") {
|
|
1569
|
+
level = 2;
|
|
1570
|
+
} else if (tok.command === "h3") {
|
|
1571
|
+
level = 3;
|
|
1572
|
+
} else if (lvlMatch && lvlMatch[1]) {
|
|
1573
|
+
level = parseInt(lvlMatch[1], 10);
|
|
1574
|
+
text = tok.args.replace(/^(?:level=)?[1-4]\s*/, "");
|
|
1575
|
+
}
|
|
1576
|
+
text = this.stripQuotes(text);
|
|
1577
|
+
const el = createHeading(text, Math.min(6, Math.max(1, level)));
|
|
1566
1578
|
el.loc = {
|
|
1567
1579
|
start: { line: tok.lineNum, column: 1 },
|
|
1568
1580
|
end: { line: tok.lineNum, column: tok.text.length }
|
|
@@ -1612,6 +1624,20 @@ var NativeYumiaParser = class {
|
|
|
1612
1624
|
}
|
|
1613
1625
|
return { element: createCard(children, title, variant), nextIdx };
|
|
1614
1626
|
}
|
|
1627
|
+
case "column": {
|
|
1628
|
+
const children = [];
|
|
1629
|
+
let nextIdx = idx + 1;
|
|
1630
|
+
while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
|
|
1631
|
+
const childRes = this.parseElement(tokens, nextIdx, components);
|
|
1632
|
+
if (childRes) {
|
|
1633
|
+
children.push(childRes.element);
|
|
1634
|
+
nextIdx = childRes.nextIdx;
|
|
1635
|
+
} else {
|
|
1636
|
+
nextIdx++;
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
return { element: createColumn(children), nextIdx };
|
|
1640
|
+
}
|
|
1615
1641
|
case "columns": {
|
|
1616
1642
|
const ratios = tok.args || "50:50";
|
|
1617
1643
|
const cols = [];
|
|
@@ -1791,35 +1817,64 @@ var NativeYumiaParser = class {
|
|
|
1791
1817
|
const nodes = [];
|
|
1792
1818
|
const edges = [];
|
|
1793
1819
|
const nodeMap = /* @__PURE__ */ new Map();
|
|
1794
|
-
const ensureNode = (
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1820
|
+
const ensureNode = (rawInput, shape, variant, explicitLabel) => {
|
|
1821
|
+
let id = "";
|
|
1822
|
+
let label = "";
|
|
1823
|
+
let detectedShape = shape || "round";
|
|
1824
|
+
const inlineMatch = rawInput.match(/^([a-zA-Z0-9_-]+)(\[\([^)]+\)\]|\(\([^)]+\)\)|\{[^}]+\}|\[[^\]]+\])$/);
|
|
1825
|
+
if (inlineMatch) {
|
|
1826
|
+
id = inlineMatch[1].toLowerCase();
|
|
1827
|
+
const body = inlineMatch[2];
|
|
1828
|
+
if (body.startsWith("[("))
|
|
1829
|
+
detectedShape = "database";
|
|
1830
|
+
else if (body.startsWith("(("))
|
|
1831
|
+
detectedShape = "circle";
|
|
1832
|
+
else if (body.startsWith("{"))
|
|
1833
|
+
detectedShape = "diamond";
|
|
1834
|
+
label = body.replace(/^[[({]+|[\])}]+$/g, "").trim();
|
|
1835
|
+
} else {
|
|
1836
|
+
const clean = rawInput.replace(/^[[({]+|[\])}]+$/g, "").trim();
|
|
1837
|
+
if (rawInput.startsWith("[(") || shape === "database")
|
|
1800
1838
|
detectedShape = "database";
|
|
1801
|
-
else if (
|
|
1839
|
+
else if (rawInput.startsWith("((") || shape === "circle")
|
|
1802
1840
|
detectedShape = "circle";
|
|
1803
|
-
else if (
|
|
1841
|
+
else if (rawInput.startsWith("{") || shape === "diamond")
|
|
1804
1842
|
detectedShape = "diamond";
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1843
|
+
label = explicitLabel || clean;
|
|
1844
|
+
id = clean.replace(/[^a-zA-Z0-9_-]/g, "_").toLowerCase();
|
|
1845
|
+
}
|
|
1846
|
+
let existing = nodeMap.get(id) || nodeMap.get(label.toLowerCase()) || nodeMap.get(label.replace(/[^a-zA-Z0-9_-]/g, "_").toLowerCase());
|
|
1847
|
+
if (!existing && explicitLabel) {
|
|
1848
|
+
const labelSlug = explicitLabel.replace(/[^a-zA-Z0-9_-]/g, "_").toLowerCase();
|
|
1849
|
+
existing = nodeMap.get(labelSlug) || nodeMap.get(explicitLabel.toLowerCase());
|
|
1850
|
+
}
|
|
1851
|
+
if (!existing) {
|
|
1852
|
+
existing = {
|
|
1808
1853
|
id,
|
|
1809
|
-
label
|
|
1854
|
+
label,
|
|
1810
1855
|
shape: detectedShape,
|
|
1811
1856
|
variant: variant || (nodes.length === 0 ? "primary" : "accent")
|
|
1812
1857
|
};
|
|
1813
|
-
|
|
1814
|
-
|
|
1858
|
+
nodes.push(existing);
|
|
1859
|
+
} else {
|
|
1860
|
+
if (shape)
|
|
1861
|
+
existing.shape = detectedShape;
|
|
1862
|
+
if (variant)
|
|
1863
|
+
existing.variant = variant;
|
|
1864
|
+
if (explicitLabel)
|
|
1865
|
+
existing.label = explicitLabel;
|
|
1815
1866
|
}
|
|
1816
|
-
|
|
1867
|
+
nodeMap.set(id, existing);
|
|
1868
|
+
nodeMap.set(existing.id, existing);
|
|
1869
|
+
nodeMap.set(existing.label.toLowerCase(), existing);
|
|
1870
|
+
nodeMap.set(existing.label.replace(/[^a-zA-Z0-9_-]/g, "_").toLowerCase(), existing);
|
|
1871
|
+
return existing;
|
|
1817
1872
|
};
|
|
1818
1873
|
let nextIdx = idx + 1;
|
|
1819
1874
|
while (nextIdx < tokens.length && tokens[nextIdx].indent > baseIndent) {
|
|
1820
1875
|
const dLine = tokens[nextIdx].text;
|
|
1821
1876
|
if (dLine.includes("->") || dLine.includes("-->") || dLine.includes("-[")) {
|
|
1822
|
-
const segRegex = /(\[[^\]]+\]|\
|
|
1877
|
+
const segRegex = /([a-zA-Z0-9_-]+\[\([^)]+\)\]|[a-zA-Z0-9_-]+\(\([^)]+\)\)|[a-zA-Z0-9_-]+\{[^}]+\}|[a-zA-Z0-9_-]+\[[^\]]+\]|\[\([^)]+\)\]|\(\([^)]+\)\)|\{[^}]+\}|\[[^\]]+\]|\S+)(?:\s*(?:-\[([^\]]+)\]->|-->|->)\s*)?/g;
|
|
1823
1878
|
let m;
|
|
1824
1879
|
let prevNode = null;
|
|
1825
1880
|
let pendingEdgeLabel = void 0;
|
|
@@ -1849,10 +1904,9 @@ var NativeYumiaParser = class {
|
|
|
1849
1904
|
const nVarMatch = nParts.match(/\bvariant=["']?([^"'\s]+)["']?/);
|
|
1850
1905
|
if (nIdMatch) {
|
|
1851
1906
|
const nId = nIdMatch[1];
|
|
1852
|
-
const
|
|
1853
|
-
node
|
|
1854
|
-
|
|
1855
|
-
node.label = nLabelMatch[1];
|
|
1907
|
+
const explicitLabel = nLabelMatch ? nLabelMatch[1] : void 0;
|
|
1908
|
+
const node = ensureNode(nId, nShapeMatch ? nShapeMatch[1] : void 0, nVarMatch ? nVarMatch[1] : void 0, explicitLabel);
|
|
1909
|
+
nodeMap.set(nId.toLowerCase(), node);
|
|
1856
1910
|
}
|
|
1857
1911
|
}
|
|
1858
1912
|
nextIdx++;
|
|
@@ -2165,7 +2219,7 @@ var VIEWPORT_PRESETS = {
|
|
|
2165
2219
|
var DefaultLayoutEngine = class {
|
|
2166
2220
|
computeSlide(slide, viewport = DEFAULT_VIEWPORT, options = {}) {
|
|
2167
2221
|
const padding = options.padding ?? 64;
|
|
2168
|
-
const gap = options.gap ??
|
|
2222
|
+
const gap = options.gap ?? 28;
|
|
2169
2223
|
const availableWidth = Math.max(100, viewport.width - padding * 2);
|
|
2170
2224
|
const availableHeight = Math.max(100, viewport.height - padding * 2);
|
|
2171
2225
|
if (slide.elements.length === 0) {
|
|
@@ -2208,6 +2262,9 @@ var DefaultLayoutEngine = class {
|
|
|
2208
2262
|
}
|
|
2209
2263
|
layoutSingleElement(element, x, y, width, gap) {
|
|
2210
2264
|
switch (element.type) {
|
|
2265
|
+
case "hero": {
|
|
2266
|
+
return this.layoutHero(element, x, y, width, gap);
|
|
2267
|
+
}
|
|
2211
2268
|
case "heading": {
|
|
2212
2269
|
const height = this.estimateHeadingHeight(element, width);
|
|
2213
2270
|
return { element, bounds: { x, y, width, height } };
|
|
@@ -2240,16 +2297,37 @@ var DefaultLayoutEngine = class {
|
|
|
2240
2297
|
const height = this.estimateMetricHeight(element);
|
|
2241
2298
|
return { element, bounds: { x, y, width, height } };
|
|
2242
2299
|
}
|
|
2300
|
+
case "callout": {
|
|
2301
|
+
const c = element;
|
|
2302
|
+
const lines = Math.ceil(c.text.length / Math.max(15, Math.floor(width / 14))) || 1;
|
|
2303
|
+
const height = Math.max(80, lines * 28 + (c.title ? 45 : 0) + 30);
|
|
2304
|
+
return { element, bounds: { x, y, width, height } };
|
|
2305
|
+
}
|
|
2306
|
+
case "badge": {
|
|
2307
|
+
return { element, bounds: { x, y, width, height: 45 } };
|
|
2308
|
+
}
|
|
2243
2309
|
case "math": {
|
|
2244
2310
|
const height = 90;
|
|
2245
2311
|
return { element, bounds: { x, y, width, height } };
|
|
2246
2312
|
}
|
|
2313
|
+
case "chart": {
|
|
2314
|
+
const height = 280;
|
|
2315
|
+
return { element, bounds: { x, y, width, height } };
|
|
2316
|
+
}
|
|
2317
|
+
case "diagram": {
|
|
2318
|
+
const height = 320;
|
|
2319
|
+
return { element, bounds: { x, y, width, height } };
|
|
2320
|
+
}
|
|
2321
|
+
case "timeline": {
|
|
2322
|
+
const height = 160;
|
|
2323
|
+
return { element, bounds: { x, y, width, height } };
|
|
2324
|
+
}
|
|
2247
2325
|
case "section": {
|
|
2248
2326
|
const height = 280;
|
|
2249
2327
|
return { element, bounds: { x, y, width, height } };
|
|
2250
2328
|
}
|
|
2251
2329
|
case "toc": {
|
|
2252
|
-
const height =
|
|
2330
|
+
const height = 340;
|
|
2253
2331
|
return { element, bounds: { x, y, width, height } };
|
|
2254
2332
|
}
|
|
2255
2333
|
case "card": {
|
|
@@ -2258,12 +2336,94 @@ var DefaultLayoutEngine = class {
|
|
|
2258
2336
|
case "columns": {
|
|
2259
2337
|
return this.layoutColumns(element, x, y, width, gap);
|
|
2260
2338
|
}
|
|
2339
|
+
case "grid": {
|
|
2340
|
+
return this.layoutGrid(element, x, y, width, gap);
|
|
2341
|
+
}
|
|
2342
|
+
case "compare": {
|
|
2343
|
+
return this.layoutCompare(element, x, y, width, gap);
|
|
2344
|
+
}
|
|
2345
|
+
case "stack": {
|
|
2346
|
+
return this.layoutStack(element, x, y, width, gap);
|
|
2347
|
+
}
|
|
2261
2348
|
default: {
|
|
2262
2349
|
const height = 60;
|
|
2263
2350
|
return { element, bounds: { x, y, width, height } };
|
|
2264
2351
|
}
|
|
2265
2352
|
}
|
|
2266
2353
|
}
|
|
2354
|
+
layoutHero(element, x, y, width, gap) {
|
|
2355
|
+
let curY = y;
|
|
2356
|
+
if (element.tagline)
|
|
2357
|
+
curY += 35;
|
|
2358
|
+
curY += 85;
|
|
2359
|
+
if (element.subtitle)
|
|
2360
|
+
curY += 65;
|
|
2361
|
+
const children = [];
|
|
2362
|
+
if (element.elements) {
|
|
2363
|
+
for (const child of element.elements) {
|
|
2364
|
+
const node = this.layoutSingleElement(child, x, curY, width, gap);
|
|
2365
|
+
children.push(node);
|
|
2366
|
+
curY += node.bounds.height + gap;
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
return { element, bounds: { x, y, width, height: curY - y }, children };
|
|
2370
|
+
}
|
|
2371
|
+
layoutGrid(element, x, y, width, gap) {
|
|
2372
|
+
const colCount = typeof element.columns === "number" ? element.columns : parseInt(String(element.columns), 10) || 2;
|
|
2373
|
+
const totalGap = gap * (colCount - 1);
|
|
2374
|
+
const colWidth = Math.max(10, (width - totalGap) / colCount);
|
|
2375
|
+
const children = [];
|
|
2376
|
+
const colYs = Array(colCount).fill(y);
|
|
2377
|
+
for (let i = 0; i < element.elements.length; i++) {
|
|
2378
|
+
const colIdx = i % colCount;
|
|
2379
|
+
const colX = x + colIdx * (colWidth + gap);
|
|
2380
|
+
const childEl = element.elements[i];
|
|
2381
|
+
const childNode = this.layoutSingleElement(childEl, colX, colYs[colIdx], colWidth, gap);
|
|
2382
|
+
children.push(childNode);
|
|
2383
|
+
colYs[colIdx] += childNode.bounds.height + gap;
|
|
2384
|
+
}
|
|
2385
|
+
const maxGridHeight = Math.max(...colYs.map((cy) => cy - y), 100);
|
|
2386
|
+
return {
|
|
2387
|
+
element,
|
|
2388
|
+
bounds: { x, y, width, height: maxGridHeight },
|
|
2389
|
+
children
|
|
2390
|
+
};
|
|
2391
|
+
}
|
|
2392
|
+
layoutCompare(element, x, y, width, gap) {
|
|
2393
|
+
const colW = (width - gap) / 2;
|
|
2394
|
+
const titleH = 45;
|
|
2395
|
+
const pad = 24;
|
|
2396
|
+
const leftStartY = y + pad + (element.leftTitle ? titleH : 0);
|
|
2397
|
+
const { nodes: leftChildren, totalHeight: leftInnerH } = this.layoutElementList(element.left, x + pad, leftStartY, colW - pad * 2, gap / 2);
|
|
2398
|
+
const rightX = x + colW + gap;
|
|
2399
|
+
const rightStartY = y + pad + (element.rightTitle ? titleH : 0);
|
|
2400
|
+
const { nodes: rightChildren, totalHeight: rightInnerH } = this.layoutElementList(element.right, rightX + pad, rightStartY, colW - pad * 2, gap / 2);
|
|
2401
|
+
const totalHeight = Math.max(leftInnerH, rightInnerH, 120) + (element.leftTitle || element.rightTitle ? titleH : 0) + pad * 2;
|
|
2402
|
+
return {
|
|
2403
|
+
element,
|
|
2404
|
+
bounds: { x, y, width, height: totalHeight },
|
|
2405
|
+
children: [...leftChildren, ...rightChildren]
|
|
2406
|
+
};
|
|
2407
|
+
}
|
|
2408
|
+
layoutStack(element, x, y, width, gap) {
|
|
2409
|
+
if (element.direction === "horizontal") {
|
|
2410
|
+
const count = element.elements.length;
|
|
2411
|
+
const itemW = (width - gap * (count - 1)) / Math.max(1, count);
|
|
2412
|
+
let curX = x;
|
|
2413
|
+
const children = [];
|
|
2414
|
+
let maxH = 0;
|
|
2415
|
+
for (const child of element.elements) {
|
|
2416
|
+
const node = this.layoutSingleElement(child, curX, y, itemW, gap);
|
|
2417
|
+
children.push(node);
|
|
2418
|
+
maxH = Math.max(maxH, node.bounds.height);
|
|
2419
|
+
curX += itemW + gap;
|
|
2420
|
+
}
|
|
2421
|
+
return { element, bounds: { x, y, width, height: maxH }, children };
|
|
2422
|
+
} else {
|
|
2423
|
+
const { nodes: children, totalHeight } = this.layoutElementList(element.elements, x, y, width, gap);
|
|
2424
|
+
return { element, bounds: { x, y, width, height: totalHeight }, children };
|
|
2425
|
+
}
|
|
2426
|
+
}
|
|
2267
2427
|
layoutCard(element, x, y, width, gap) {
|
|
2268
2428
|
const cardPadding = 32;
|
|
2269
2429
|
const innerWidth = Math.max(10, width - cardPadding * 2);
|
|
@@ -4542,6 +4702,19 @@ var PptxRenderer = class {
|
|
|
4542
4702
|
for (const node of slideLayout.nodes) {
|
|
4543
4703
|
this.renderNode(pptxSlide, pptx, node, scaleX, scaleY, theme, presentation);
|
|
4544
4704
|
}
|
|
4705
|
+
if (presentation.metadata.watermark) {
|
|
4706
|
+
const watermarkText = typeof presentation.metadata.watermark === "string" ? presentation.metadata.watermark : "CONFIDENTIAL";
|
|
4707
|
+
pptxSlide.addText(watermarkText.toUpperCase(), {
|
|
4708
|
+
x: 0.5,
|
|
4709
|
+
y: slideHeightInches - 0.4,
|
|
4710
|
+
w: slideWidthInches - 1,
|
|
4711
|
+
h: 0.25,
|
|
4712
|
+
fontSize: 9,
|
|
4713
|
+
bold: true,
|
|
4714
|
+
color: this.cleanHexColor(theme.colors.muted || "#888888"),
|
|
4715
|
+
fontFace: cleanFontFace(theme.typography.headingFont)
|
|
4716
|
+
});
|
|
4717
|
+
}
|
|
4545
4718
|
if (slide.notes) {
|
|
4546
4719
|
pptxSlide.addNotes(slide.notes);
|
|
4547
4720
|
}
|
|
@@ -4919,7 +5092,7 @@ var PptxRenderer = class {
|
|
|
4919
5092
|
}
|
|
4920
5093
|
renderCode(pptxSlide, pptx, code, rect, theme) {
|
|
4921
5094
|
const codeTheme = theme.components?.code;
|
|
4922
|
-
const bgColor = this.cleanHexColor(codeTheme?.background || "#
|
|
5095
|
+
const bgColor = this.cleanHexColor(codeTheme?.background || "#0f172a");
|
|
4923
5096
|
const textColor = this.cleanHexColor(codeTheme?.textColor || "#f8fafc");
|
|
4924
5097
|
const primaryColor = this.cleanHexColor(theme.colors.primary || "#00F0FF");
|
|
4925
5098
|
const mutedColor = this.cleanHexColor(theme.colors.muted || "#64748b");
|
|
@@ -4929,8 +5102,32 @@ var PptxRenderer = class {
|
|
|
4929
5102
|
w: rect.w,
|
|
4930
5103
|
h: rect.h,
|
|
4931
5104
|
fill: { color: bgColor },
|
|
4932
|
-
line: { color: this.cleanHexColor(theme.colors.border || "#
|
|
4933
|
-
rectRadius: 0.
|
|
5105
|
+
line: { color: this.cleanHexColor(theme.colors.border || "#334155"), width: 1.5 },
|
|
5106
|
+
rectRadius: 0.08
|
|
5107
|
+
});
|
|
5108
|
+
pptxSlide.addShape(pptx.ShapeType.ellipse || "ellipse", {
|
|
5109
|
+
x: rect.x + 0.15,
|
|
5110
|
+
y: rect.y + 0.12,
|
|
5111
|
+
w: 0.1,
|
|
5112
|
+
h: 0.1,
|
|
5113
|
+
fill: { color: "ef4444" },
|
|
5114
|
+
line: { color: "ef4444", width: 0 }
|
|
5115
|
+
});
|
|
5116
|
+
pptxSlide.addShape(pptx.ShapeType.ellipse || "ellipse", {
|
|
5117
|
+
x: rect.x + 0.3,
|
|
5118
|
+
y: rect.y + 0.12,
|
|
5119
|
+
w: 0.1,
|
|
5120
|
+
h: 0.1,
|
|
5121
|
+
fill: { color: "f59e0b" },
|
|
5122
|
+
line: { color: "f59e0b", width: 0 }
|
|
5123
|
+
});
|
|
5124
|
+
pptxSlide.addShape(pptx.ShapeType.ellipse || "ellipse", {
|
|
5125
|
+
x: rect.x + 0.45,
|
|
5126
|
+
y: rect.y + 0.12,
|
|
5127
|
+
w: 0.1,
|
|
5128
|
+
h: 0.1,
|
|
5129
|
+
fill: { color: "10b981" },
|
|
5130
|
+
line: { color: "10b981", width: 0 }
|
|
4934
5131
|
});
|
|
4935
5132
|
const lines = code.code.split("\n");
|
|
4936
5133
|
if (code.highlight) {
|
|
@@ -4960,11 +5157,11 @@ var PptxRenderer = class {
|
|
|
4960
5157
|
const isHl = highlightSet.has(lineNum);
|
|
4961
5158
|
const lineNumPad = String(lineNum).padStart(2, "0");
|
|
4962
5159
|
const numColor = isHl ? primaryColor : mutedColor;
|
|
4963
|
-
const contentColor = isHl ? primaryColor :
|
|
5160
|
+
const contentColor = isHl ? primaryColor : textColor;
|
|
4964
5161
|
chunks.push({
|
|
4965
5162
|
text: `${lineNumPad} `,
|
|
4966
5163
|
options: {
|
|
4967
|
-
fontSize:
|
|
5164
|
+
fontSize: 11,
|
|
4968
5165
|
fontFace: "Consolas",
|
|
4969
5166
|
color: numColor,
|
|
4970
5167
|
bold: isHl
|
|
@@ -4973,7 +5170,7 @@ var PptxRenderer = class {
|
|
|
4973
5170
|
chunks.push({
|
|
4974
5171
|
text: line || " ",
|
|
4975
5172
|
options: {
|
|
4976
|
-
fontSize:
|
|
5173
|
+
fontSize: 11,
|
|
4977
5174
|
fontFace: "Consolas",
|
|
4978
5175
|
color: contentColor,
|
|
4979
5176
|
bold: isHl,
|
|
@@ -4983,19 +5180,19 @@ var PptxRenderer = class {
|
|
|
4983
5180
|
});
|
|
4984
5181
|
pptxSlide.addText(chunks, {
|
|
4985
5182
|
x: rect.x + 0.2,
|
|
4986
|
-
y: rect.y + 0.
|
|
5183
|
+
y: rect.y + 0.32,
|
|
4987
5184
|
w: rect.w - 0.4,
|
|
4988
|
-
h: rect.h - 0.
|
|
5185
|
+
h: rect.h - 0.4,
|
|
4989
5186
|
valign: "top",
|
|
4990
5187
|
margin: 0
|
|
4991
5188
|
});
|
|
4992
5189
|
} else {
|
|
4993
5190
|
pptxSlide.addText(code.code, {
|
|
4994
5191
|
x: rect.x + 0.2,
|
|
4995
|
-
y: rect.y + 0.
|
|
5192
|
+
y: rect.y + 0.32,
|
|
4996
5193
|
w: rect.w - 0.4,
|
|
4997
|
-
h: rect.h - 0.
|
|
4998
|
-
fontSize:
|
|
5194
|
+
h: rect.h - 0.4,
|
|
5195
|
+
fontSize: 11.5,
|
|
4999
5196
|
fontFace: "Consolas",
|
|
5000
5197
|
color: textColor,
|
|
5001
5198
|
valign: "top"
|
|
@@ -5321,6 +5518,11 @@ ${item.description}` : "";
|
|
|
5321
5518
|
align: "center",
|
|
5322
5519
|
valign: "middle"
|
|
5323
5520
|
});
|
|
5521
|
+
if (node.children) {
|
|
5522
|
+
for (const childNode of node.children) {
|
|
5523
|
+
this.renderNode(pptxSlide, pptx, childNode, scaleX, scaleY, theme);
|
|
5524
|
+
}
|
|
5525
|
+
}
|
|
5324
5526
|
}
|
|
5325
5527
|
renderSection(pptxSlide, pptx, section, rect, theme) {
|
|
5326
5528
|
const cardBg = this.cleanHexColor(theme.colors.surface || "#0f172a");
|
|
@@ -5662,22 +5864,30 @@ ${mermaid.code}`, {
|
|
|
5662
5864
|
const nodeH = isLR ? Math.min(0.65, (rect.h - 0.5) / maxLane) : Math.min(0.6, (rect.h - 0.5) / (numRanks * 1.4));
|
|
5663
5865
|
const gapX = isLR ? numRanks > 1 ? (rect.w - numRanks * nodeW) / (numRanks - 1) : 0 : maxLane > 1 ? (rect.w - maxLane * nodeW) / (maxLane - 1) : 0;
|
|
5664
5866
|
const gapY = isLR ? maxLane > 1 ? (rect.h - maxLane * nodeH) / (maxLane - 1) : 0 : numRanks > 1 ? (rect.h - numRanks * nodeH) / (numRanks - 1) : 0;
|
|
5867
|
+
const maxLaneHeight = isLR ? maxLane * (nodeH + gapY) - gapY : numRanks * (nodeH + gapY) - gapY;
|
|
5868
|
+
const maxRankWidth = isLR ? numRanks * (nodeW + gapX) - gapX : maxLane * (nodeW + gapX) - gapX;
|
|
5665
5869
|
const positions = {};
|
|
5666
5870
|
sortedRanks.forEach((r, rIdx) => {
|
|
5667
5871
|
const ids = rankGroups[r];
|
|
5668
|
-
|
|
5669
|
-
|
|
5872
|
+
if (isLR) {
|
|
5873
|
+
const colHeight = ids.length * (nodeH + gapY) - gapY;
|
|
5874
|
+
const offsetY = (maxLaneHeight - colHeight) / 2;
|
|
5875
|
+
ids.forEach((id, lIdx) => {
|
|
5670
5876
|
positions[id] = {
|
|
5671
5877
|
x: rect.x + rIdx * (nodeW + gapX),
|
|
5672
|
-
y: rect.y + lIdx * (nodeH + gapY)
|
|
5878
|
+
y: rect.y + offsetY + lIdx * (nodeH + gapY)
|
|
5673
5879
|
};
|
|
5674
|
-
}
|
|
5880
|
+
});
|
|
5881
|
+
} else {
|
|
5882
|
+
const rowWidth = ids.length * (nodeW + gapX) - gapX;
|
|
5883
|
+
const offsetX = (maxRankWidth - rowWidth) / 2;
|
|
5884
|
+
ids.forEach((id, lIdx) => {
|
|
5675
5885
|
positions[id] = {
|
|
5676
|
-
x: rect.x + lIdx * (nodeW + gapX),
|
|
5886
|
+
x: rect.x + offsetX + lIdx * (nodeW + gapX),
|
|
5677
5887
|
y: rect.y + rIdx * (nodeH + gapY)
|
|
5678
5888
|
};
|
|
5679
|
-
}
|
|
5680
|
-
}
|
|
5889
|
+
});
|
|
5890
|
+
}
|
|
5681
5891
|
});
|
|
5682
5892
|
const surfaceColor = this.cleanHexColor(theme.colors.surface || "1e293b");
|
|
5683
5893
|
const arrowColor = this.cleanHexColor(theme.colors.accent || theme.colors.primary);
|
|
@@ -5690,11 +5900,19 @@ ${mermaid.code}`, {
|
|
|
5690
5900
|
const y1 = isLR ? p1.y + nodeH / 2 : p1.y + nodeH;
|
|
5691
5901
|
const x2 = isLR ? p2.x : p2.x + nodeW / 2;
|
|
5692
5902
|
const y2 = isLR ? p2.y + nodeH / 2 : p2.y;
|
|
5903
|
+
const minX = Math.min(x1, x2);
|
|
5904
|
+
const minY = Math.min(y1, y2);
|
|
5905
|
+
const lineW = Math.max(0.01, Math.abs(x2 - x1));
|
|
5906
|
+
const lineH = Math.max(0.01, Math.abs(y2 - y1));
|
|
5907
|
+
const flipH = x2 < x1;
|
|
5908
|
+
const flipV = y2 < y1;
|
|
5693
5909
|
pptxSlide.addShape(pptx.ShapeType.line, {
|
|
5694
|
-
x:
|
|
5695
|
-
y:
|
|
5696
|
-
w:
|
|
5697
|
-
h:
|
|
5910
|
+
x: minX,
|
|
5911
|
+
y: minY,
|
|
5912
|
+
w: lineW,
|
|
5913
|
+
h: lineH,
|
|
5914
|
+
flipH,
|
|
5915
|
+
flipV,
|
|
5698
5916
|
line: {
|
|
5699
5917
|
color: arrowColor,
|
|
5700
5918
|
width: 2,
|
|
@@ -5705,13 +5923,25 @@ ${mermaid.code}`, {
|
|
|
5705
5923
|
if (e.label) {
|
|
5706
5924
|
const midX = (x1 + x2) / 2;
|
|
5707
5925
|
const midY = (y1 + y2) / 2;
|
|
5926
|
+
const pillW = Math.min(1.4, Math.max(0.7, e.label.length * 0.08 + 0.25));
|
|
5927
|
+
pptxSlide.addShape(pptx.ShapeType.roundRect, {
|
|
5928
|
+
x: midX - pillW / 2,
|
|
5929
|
+
y: midY - 0.13,
|
|
5930
|
+
w: pillW,
|
|
5931
|
+
h: 0.26,
|
|
5932
|
+
fill: { color: surfaceColor },
|
|
5933
|
+
line: { color: this.cleanHexColor(theme.colors.border || "cbd5e1"), width: 1 },
|
|
5934
|
+
rectRadius: 0.06
|
|
5935
|
+
});
|
|
5708
5936
|
pptxSlide.addText(e.label, {
|
|
5709
|
-
x: midX -
|
|
5710
|
-
y: midY - 0.
|
|
5711
|
-
w:
|
|
5712
|
-
h: 0.
|
|
5937
|
+
x: midX - pillW / 2,
|
|
5938
|
+
y: midY - 0.13,
|
|
5939
|
+
w: pillW,
|
|
5940
|
+
h: 0.26,
|
|
5713
5941
|
fontSize: 9,
|
|
5714
|
-
|
|
5942
|
+
bold: true,
|
|
5943
|
+
color: this.cleanHexColor(theme.colors.muted || "64748b"),
|
|
5944
|
+
fontFace: cleanFontFace(theme.typography.headingFont),
|
|
5715
5945
|
align: "center",
|
|
5716
5946
|
valign: "middle"
|
|
5717
5947
|
});
|
|
@@ -5737,7 +5967,7 @@ ${mermaid.code}`, {
|
|
|
5737
5967
|
else if (n.shape === "database")
|
|
5738
5968
|
shapeType = pptx.ShapeType.can;
|
|
5739
5969
|
else if (n.shape === "circle")
|
|
5740
|
-
shapeType = pptx.ShapeType.
|
|
5970
|
+
shapeType = pptx.ShapeType.ellipse || "ellipse";
|
|
5741
5971
|
pptxSlide.addShape(shapeType, {
|
|
5742
5972
|
x: p.x,
|
|
5743
5973
|
y: p.y,
|
|
@@ -5747,14 +5977,24 @@ ${mermaid.code}`, {
|
|
|
5747
5977
|
line: { color: nodeBorderColor, width: 2 },
|
|
5748
5978
|
rectRadius: 0.08
|
|
5749
5979
|
});
|
|
5980
|
+
if (n.shape === "database") {
|
|
5981
|
+
pptxSlide.addShape(pptx.ShapeType.rect, {
|
|
5982
|
+
x: p.x + 0.15,
|
|
5983
|
+
y: p.y + 0.1,
|
|
5984
|
+
w: Math.max(0.1, nodeW - 0.3),
|
|
5985
|
+
h: 0.02,
|
|
5986
|
+
fill: { color: nodeBorderColor },
|
|
5987
|
+
line: { color: nodeBorderColor, width: 1 }
|
|
5988
|
+
});
|
|
5989
|
+
}
|
|
5750
5990
|
pptxSlide.addText(n.label, {
|
|
5751
|
-
x: p.x + 0.
|
|
5752
|
-
y: p.y + 0.
|
|
5753
|
-
w: nodeW - 0.
|
|
5754
|
-
h: nodeH - 0.
|
|
5991
|
+
x: p.x + 0.06,
|
|
5992
|
+
y: p.y + 0.06,
|
|
5993
|
+
w: Math.max(0.1, nodeW - 0.12),
|
|
5994
|
+
h: Math.max(0.1, nodeH - 0.12),
|
|
5755
5995
|
align: "center",
|
|
5756
5996
|
valign: "middle",
|
|
5757
|
-
fontSize: 11,
|
|
5997
|
+
fontSize: n.label.length > 18 ? 10 : 11,
|
|
5758
5998
|
bold: true,
|
|
5759
5999
|
color: this.cleanHexColor(theme.colors.text || "ffffff"),
|
|
5760
6000
|
fontFace: cleanFontFace(theme.typography.headingFont)
|
|
@@ -5776,6 +6016,13 @@ ${mermaid.code}`, {
|
|
|
5776
6016
|
if (CSS_NAMED_COLORS[trimmed]) {
|
|
5777
6017
|
return CSS_NAMED_COLORS[trimmed];
|
|
5778
6018
|
}
|
|
6019
|
+
const rgbMatch = trimmed.match(/^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i);
|
|
6020
|
+
if (rgbMatch && rgbMatch[1] && rgbMatch[2] && rgbMatch[3]) {
|
|
6021
|
+
const r = Math.min(255, Math.max(0, parseInt(rgbMatch[1], 10))).toString(16).padStart(2, "0");
|
|
6022
|
+
const g = Math.min(255, Math.max(0, parseInt(rgbMatch[2], 10))).toString(16).padStart(2, "0");
|
|
6023
|
+
const b = Math.min(255, Math.max(0, parseInt(rgbMatch[3], 10))).toString(16).padStart(2, "0");
|
|
6024
|
+
return `${r}${g}${b}`;
|
|
6025
|
+
}
|
|
5779
6026
|
const hexMatch = trimmed.match(/^#?([0-9a-f]{3}|[0-9a-f]{6})$/i);
|
|
5780
6027
|
if (hexMatch && hexMatch[1]) {
|
|
5781
6028
|
const hex = hexMatch[1];
|
|
@@ -5978,7 +6225,7 @@ var HtmlRenderer = class {
|
|
|
5978
6225
|
flex-direction: column;
|
|
5979
6226
|
justify-content: flex-start;
|
|
5980
6227
|
align-items: stretch;
|
|
5981
|
-
padding: clamp(2rem, 4vw, 3.
|
|
6228
|
+
padding: clamp(1.4rem, 2.8vw, 2.2rem) clamp(2rem, 4vw, 3.8rem) clamp(2.2rem, 3.5vw, 3.2rem);
|
|
5982
6229
|
box-sizing: border-box;
|
|
5983
6230
|
animation: fadeIn 0.25s cubic-bezier(0.16, 1, 0.3, 1);
|
|
5984
6231
|
}
|
|
@@ -5997,31 +6244,40 @@ var HtmlRenderer = class {
|
|
|
5997
6244
|
font-family: var(--yumia-font-heading), system-ui, -apple-system, sans-serif;
|
|
5998
6245
|
font-weight: 700;
|
|
5999
6246
|
line-height: var(--yumia-line-height-tight);
|
|
6000
|
-
margin-bottom: 0.
|
|
6247
|
+
margin-bottom: 0.35em;
|
|
6001
6248
|
letter-spacing: var(--yumia-letter-spacing-tight);
|
|
6002
6249
|
overflow-wrap: break-word;
|
|
6003
6250
|
word-break: break-word;
|
|
6004
6251
|
}
|
|
6005
6252
|
|
|
6006
6253
|
h1 {
|
|
6007
|
-
font-size: clamp(1.
|
|
6254
|
+
font-size: clamp(1.6rem, 2.8vw, 2.5rem);
|
|
6008
6255
|
color: var(--yumia-primary);
|
|
6009
6256
|
line-height: 1.15;
|
|
6010
6257
|
}
|
|
6011
6258
|
|
|
6259
|
+
h1 + h2 {
|
|
6260
|
+
margin-top: -0.15em;
|
|
6261
|
+
margin-bottom: 0.75em;
|
|
6262
|
+
font-size: clamp(1rem, 1.6vw, 1.35rem);
|
|
6263
|
+
color: var(--yumia-muted);
|
|
6264
|
+
font-weight: 600;
|
|
6265
|
+
letter-spacing: 0.02em;
|
|
6266
|
+
}
|
|
6267
|
+
|
|
6012
6268
|
h2 {
|
|
6013
|
-
font-size: clamp(1.
|
|
6269
|
+
font-size: clamp(1.3rem, 2.2vw, 1.9rem);
|
|
6014
6270
|
color: var(--yumia-text);
|
|
6015
6271
|
line-height: 1.2;
|
|
6016
6272
|
}
|
|
6017
6273
|
|
|
6018
6274
|
h3 {
|
|
6019
|
-
font-size: clamp(1.
|
|
6275
|
+
font-size: clamp(1.15rem, 1.8vw, 1.5rem);
|
|
6020
6276
|
color: var(--yumia-text);
|
|
6021
6277
|
}
|
|
6022
6278
|
|
|
6023
6279
|
h4 {
|
|
6024
|
-
font-size: clamp(
|
|
6280
|
+
font-size: clamp(1rem, 1.4vw, 1.25rem);
|
|
6025
6281
|
color: var(--yumia-muted);
|
|
6026
6282
|
}
|
|
6027
6283
|
|
|
@@ -6113,6 +6369,7 @@ var HtmlRenderer = class {
|
|
|
6113
6369
|
flex-direction: column;
|
|
6114
6370
|
gap: 0.8rem;
|
|
6115
6371
|
height: 100%;
|
|
6372
|
+
min-width: 0;
|
|
6116
6373
|
}
|
|
6117
6374
|
|
|
6118
6375
|
/* Cards */
|
|
@@ -6458,24 +6715,25 @@ var HtmlRenderer = class {
|
|
|
6458
6715
|
.yumia-compare {
|
|
6459
6716
|
display: grid;
|
|
6460
6717
|
grid-template-columns: 1fr auto 1fr;
|
|
6461
|
-
gap: 20px;
|
|
6718
|
+
gap: clamp(12px, 1.8vw, 20px);
|
|
6462
6719
|
align-items: stretch;
|
|
6463
|
-
margin:
|
|
6720
|
+
margin: 0.5rem 0;
|
|
6464
6721
|
}
|
|
6465
6722
|
.yumia-compare-col {
|
|
6466
6723
|
background: var(--yumia-surface);
|
|
6467
|
-
border:
|
|
6724
|
+
border: 1.5px solid var(--yumia-border);
|
|
6468
6725
|
border-radius: var(--yumia-radius-card);
|
|
6469
|
-
padding: 1.
|
|
6726
|
+
padding: clamp(1rem, 1.6vw, 1.3rem);
|
|
6470
6727
|
display: flex;
|
|
6471
6728
|
flex-direction: column;
|
|
6729
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
|
|
6472
6730
|
}
|
|
6473
6731
|
.yumia-compare-title {
|
|
6474
|
-
font-size: 1.
|
|
6732
|
+
font-size: clamp(1rem, 1.4vw, 1.15rem);
|
|
6475
6733
|
font-weight: 700;
|
|
6476
6734
|
color: var(--yumia-primary);
|
|
6477
|
-
margin-bottom:
|
|
6478
|
-
padding-bottom: 0.
|
|
6735
|
+
margin-bottom: 0.6rem;
|
|
6736
|
+
padding-bottom: 0.4rem;
|
|
6479
6737
|
border-bottom: 1px solid var(--yumia-divider);
|
|
6480
6738
|
}
|
|
6481
6739
|
.yumia-compare-divider {
|
|
@@ -6483,49 +6741,80 @@ var HtmlRenderer = class {
|
|
|
6483
6741
|
align-items: center;
|
|
6484
6742
|
justify-content: center;
|
|
6485
6743
|
font-weight: 800;
|
|
6486
|
-
font-size: 0.
|
|
6744
|
+
font-size: 0.85rem;
|
|
6487
6745
|
color: var(--yumia-muted);
|
|
6488
|
-
background:
|
|
6746
|
+
background: var(--yumia-surface);
|
|
6489
6747
|
border-radius: 50%;
|
|
6490
|
-
width:
|
|
6491
|
-
height:
|
|
6748
|
+
width: 32px;
|
|
6749
|
+
height: 32px;
|
|
6492
6750
|
align-self: center;
|
|
6493
|
-
border:
|
|
6751
|
+
border: 1.5px solid var(--yumia-border);
|
|
6752
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
6494
6753
|
}
|
|
6495
6754
|
|
|
6496
6755
|
/* Native SVG Chart Container */
|
|
6497
6756
|
.yumia-chart-container {
|
|
6498
6757
|
background: var(--yumia-surface);
|
|
6499
|
-
border:
|
|
6758
|
+
border: 1.5px solid var(--yumia-border);
|
|
6500
6759
|
border-radius: var(--yumia-radius-card);
|
|
6501
|
-
padding: 1.25rem;
|
|
6502
|
-
margin:
|
|
6760
|
+
padding: clamp(0.8rem, 1.4vw, 1.25rem);
|
|
6761
|
+
margin: 0.6rem 0;
|
|
6503
6762
|
display: flex;
|
|
6504
6763
|
flex-direction: column;
|
|
6505
6764
|
align-items: center;
|
|
6506
6765
|
width: 100%;
|
|
6766
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
|
|
6507
6767
|
}
|
|
6508
6768
|
.yumia-chart-title {
|
|
6509
|
-
font-size: 1.
|
|
6769
|
+
font-size: 1.05rem;
|
|
6510
6770
|
font-weight: 700;
|
|
6511
6771
|
color: var(--yumia-text);
|
|
6512
|
-
margin-bottom: 0.
|
|
6772
|
+
margin-bottom: 0.6rem;
|
|
6513
6773
|
align-self: flex-start;
|
|
6514
6774
|
}
|
|
6515
6775
|
|
|
6776
|
+
/* Diagram Container */
|
|
6777
|
+
.yumia-diagram-container {
|
|
6778
|
+
width: 100%;
|
|
6779
|
+
display: flex;
|
|
6780
|
+
flex-direction: column;
|
|
6781
|
+
align-items: center;
|
|
6782
|
+
justify-content: center;
|
|
6783
|
+
margin: 0.5rem 0;
|
|
6784
|
+
max-height: 52vh;
|
|
6785
|
+
}
|
|
6786
|
+
.yumia-diagram {
|
|
6787
|
+
max-width: 100%;
|
|
6788
|
+
max-height: 48vh;
|
|
6789
|
+
height: auto;
|
|
6790
|
+
background: var(--yumia-surface);
|
|
6791
|
+
border: 1.5px solid var(--yumia-border);
|
|
6792
|
+
border-radius: var(--yumia-radius-card);
|
|
6793
|
+
padding: 12px;
|
|
6794
|
+
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
|
|
6795
|
+
box-sizing: border-box;
|
|
6796
|
+
}
|
|
6797
|
+
.yumia-diag-node {
|
|
6798
|
+
transition: transform 0.2s ease, filter 0.2s ease;
|
|
6799
|
+
cursor: pointer;
|
|
6800
|
+
}
|
|
6801
|
+
.yumia-diag-node:hover {
|
|
6802
|
+
filter: brightness(1.1);
|
|
6803
|
+
}
|
|
6804
|
+
|
|
6516
6805
|
/* Mermaid Container */
|
|
6517
6806
|
.mermaid-container {
|
|
6518
|
-
background:
|
|
6807
|
+
background: var(--yumia-surface);
|
|
6519
6808
|
border: 1.5px solid var(--yumia-border);
|
|
6520
6809
|
border-radius: var(--yumia-radius-card);
|
|
6521
|
-
padding: 1.
|
|
6522
|
-
margin:
|
|
6810
|
+
padding: 1.2rem;
|
|
6811
|
+
margin: 0.6rem 0;
|
|
6523
6812
|
display: flex;
|
|
6524
6813
|
justify-content: center;
|
|
6525
6814
|
align-items: center;
|
|
6526
6815
|
overflow: auto;
|
|
6527
6816
|
width: 100%;
|
|
6528
|
-
min-height:
|
|
6817
|
+
min-height: 200px;
|
|
6529
6818
|
}
|
|
6530
6819
|
|
|
6531
6820
|
.mermaid-container pre.mermaid,
|
|
@@ -6535,7 +6824,7 @@ var HtmlRenderer = class {
|
|
|
6535
6824
|
padding: 0 !important;
|
|
6536
6825
|
margin: 0 !important;
|
|
6537
6826
|
font-size: 1rem;
|
|
6538
|
-
color:
|
|
6827
|
+
color: var(--yumia-text);
|
|
6539
6828
|
display: flex;
|
|
6540
6829
|
justify-content: center;
|
|
6541
6830
|
align-items: center;
|
|
@@ -6554,18 +6843,18 @@ var HtmlRenderer = class {
|
|
|
6554
6843
|
border: 1.5px solid var(--yumia-border);
|
|
6555
6844
|
border-left: 4px solid var(--yumia-primary);
|
|
6556
6845
|
border-radius: var(--yumia-radius-card);
|
|
6557
|
-
padding: 0.
|
|
6558
|
-
margin: 0.
|
|
6846
|
+
padding: 0.55rem 1.2rem;
|
|
6847
|
+
margin: 0.45rem 0;
|
|
6559
6848
|
display: flex;
|
|
6560
6849
|
align-items: center;
|
|
6561
6850
|
justify-content: center;
|
|
6562
|
-
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.
|
|
6851
|
+
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15);
|
|
6563
6852
|
overflow-x: auto;
|
|
6564
6853
|
max-width: 100%;
|
|
6565
6854
|
}
|
|
6566
6855
|
|
|
6567
6856
|
.yumia-math-equation {
|
|
6568
|
-
font-size: clamp(
|
|
6857
|
+
font-size: clamp(1rem, 1.6vw, 1.35rem);
|
|
6569
6858
|
color: var(--yumia-text);
|
|
6570
6859
|
letter-spacing: 0.03em;
|
|
6571
6860
|
}
|
|
@@ -7510,7 +7799,7 @@ var HtmlRenderer = class {
|
|
|
7510
7799
|
const colorVar = sev === "warning" ? "var(--yumia-warning)" : sev === "danger" ? "var(--yumia-danger)" : sev === "success" ? "var(--yumia-success)" : "var(--yumia-info)";
|
|
7511
7800
|
const titleHtml = c.title ? `<div style="font-weight:700; font-size:1.05rem; color:${colorVar}; margin-bottom:4px;">${this.formatInline(c.title)}</div>` : "";
|
|
7512
7801
|
return `
|
|
7513
|
-
<div class="yumia-callout" data-severity="${sev}" data-yumia-role="callout" style="background:var(--yumia-surface); border-left:4px solid ${colorVar}; border-radius:var(--yumia-radius-card); padding:1rem 1.4rem; margin:0.8rem 0; width:100%;">
|
|
7802
|
+
<div class="yumia-callout" data-severity="${sev}" data-yumia-role="callout" style="background:var(--yumia-surface); border-left:4px solid ${colorVar}; border-radius:var(--yumia-radius-card); padding:1rem 1.4rem; margin:0.8rem 0; width:100%; display:flex; flex-direction:column; gap:6px; box-sizing:border-box;">
|
|
7514
7803
|
${titleHtml}
|
|
7515
7804
|
<div style="font-size:0.95rem; color:var(--yumia-text); line-height:1.5;">${this.formatInline(c.text)}</div>
|
|
7516
7805
|
</div>`;
|
|
@@ -7759,10 +8048,10 @@ var HtmlRenderer = class {
|
|
|
7759
8048
|
}
|
|
7760
8049
|
renderDiagram(d, theme) {
|
|
7761
8050
|
const isLR = (d.direction || "LR").toUpperCase() === "LR";
|
|
7762
|
-
const nodeW =
|
|
7763
|
-
const nodeH =
|
|
7764
|
-
const gapX = isLR ?
|
|
7765
|
-
const gapY = isLR ?
|
|
8051
|
+
const nodeW = 155;
|
|
8052
|
+
const nodeH = 48;
|
|
8053
|
+
const gapX = isLR ? 60 : 35;
|
|
8054
|
+
const gapY = isLR ? 30 : 50;
|
|
7766
8055
|
const nodeIds = d.nodes.map((n) => n.id);
|
|
7767
8056
|
const inDegree = {};
|
|
7768
8057
|
const adj = {};
|
|
@@ -7813,28 +8102,42 @@ var HtmlRenderer = class {
|
|
|
7813
8102
|
});
|
|
7814
8103
|
const sortedRanks = Object.keys(rankGroups).map(Number).sort((a, b) => a - b);
|
|
7815
8104
|
const positions = {};
|
|
7816
|
-
let maxLaneIndex =
|
|
8105
|
+
let maxLaneIndex = 1;
|
|
8106
|
+
sortedRanks.forEach((r) => {
|
|
8107
|
+
maxLaneIndex = Math.max(maxLaneIndex, rankGroups[r].length);
|
|
8108
|
+
});
|
|
8109
|
+
const maxLaneHeight = isLR ? maxLaneIndex * (nodeH + gapY) - gapY : sortedRanks.length * (nodeH + gapY) - gapY;
|
|
8110
|
+
const maxRankWidth = isLR ? sortedRanks.length * (nodeW + gapX) - gapX : maxLaneIndex * (nodeW + gapX) - gapX;
|
|
7817
8111
|
sortedRanks.forEach((r, rIdx) => {
|
|
7818
8112
|
const ids = rankGroups[r];
|
|
7819
|
-
|
|
7820
|
-
|
|
7821
|
-
|
|
8113
|
+
if (isLR) {
|
|
8114
|
+
const colHeight = ids.length * (nodeH + gapY) - gapY;
|
|
8115
|
+
const offsetY = (maxLaneHeight - colHeight) / 2;
|
|
8116
|
+
ids.forEach((id, lIdx) => {
|
|
7822
8117
|
positions[id] = {
|
|
7823
8118
|
x: 40 + rIdx * (nodeW + gapX),
|
|
7824
|
-
y: 40 + lIdx * (nodeH + gapY)
|
|
8119
|
+
y: 40 + offsetY + lIdx * (nodeH + gapY)
|
|
7825
8120
|
};
|
|
7826
|
-
}
|
|
8121
|
+
});
|
|
8122
|
+
} else {
|
|
8123
|
+
const rowWidth = ids.length * (nodeW + gapX) - gapX;
|
|
8124
|
+
const offsetX = (maxRankWidth - rowWidth) / 2;
|
|
8125
|
+
ids.forEach((id, lIdx) => {
|
|
7827
8126
|
positions[id] = {
|
|
7828
|
-
x: 40 + lIdx * (nodeW + gapX),
|
|
8127
|
+
x: 40 + offsetX + lIdx * (nodeW + gapX),
|
|
7829
8128
|
y: 40 + rIdx * (nodeH + gapY)
|
|
7830
8129
|
};
|
|
7831
|
-
}
|
|
7832
|
-
}
|
|
8130
|
+
});
|
|
8131
|
+
}
|
|
7833
8132
|
});
|
|
7834
8133
|
const totalWidth = isLR ? 80 + Math.max(1, sortedRanks.length) * (nodeW + gapX) - gapX : 80 + Math.max(1, maxLaneIndex) * (nodeW + gapX) - gapX;
|
|
7835
|
-
const totalHeight = isLR ? 80 +
|
|
8134
|
+
const totalHeight = isLR ? 80 + maxLaneHeight : 80 + Math.max(1, sortedRanks.length) * (nodeH + gapY) - gapY;
|
|
7836
8135
|
const arrowColor = theme.colors.accent || theme.colors.primary;
|
|
7837
8136
|
const markerId = `arrow-${Math.random().toString(36).slice(2, 8)}`;
|
|
8137
|
+
const surfaceFill = theme.colors.surface || "rgba(15, 23, 42, 0.85)";
|
|
8138
|
+
const textFill = theme.colors.text || "#ffffff";
|
|
8139
|
+
const mutedColor = theme.colors.muted || "#64748b";
|
|
8140
|
+
const borderColor = theme.colors.border || "rgba(255, 255, 255, 0.15)";
|
|
7838
8141
|
let edgesSvg = "";
|
|
7839
8142
|
d.edges.forEach((e) => {
|
|
7840
8143
|
const p1 = positions[e.from];
|
|
@@ -7862,8 +8165,8 @@ var HtmlRenderer = class {
|
|
|
7862
8165
|
edgesSvg += `<path d="M ${x1} ${y1} C ${midX} ${y1}, ${midX} ${y2}, ${x2} ${y2}" fill="none" stroke="${arrowColor}" stroke-width="2" ${dash} marker-end="url(#${markerId})" />`;
|
|
7863
8166
|
if (e.label) {
|
|
7864
8167
|
edgesSvg += `<g transform="translate(${midX}, ${midY})">
|
|
7865
|
-
<rect x="-
|
|
7866
|
-
<text x="0" y="
|
|
8168
|
+
<rect x="-42" y="-11" width="84" height="22" rx="6" fill="${surfaceFill}" stroke="${borderColor}" stroke-width="1.2"/>
|
|
8169
|
+
<text x="0" y="4" text-anchor="middle" fill="${mutedColor}" font-size="10.5" font-weight="600" font-family="sans-serif">${this.escapeHtml(e.label)}</text>
|
|
7867
8170
|
</g>`;
|
|
7868
8171
|
}
|
|
7869
8172
|
});
|
|
@@ -7885,28 +8188,28 @@ var HtmlRenderer = class {
|
|
|
7885
8188
|
let shapeSvg = "";
|
|
7886
8189
|
if (n.shape === "database") {
|
|
7887
8190
|
shapeSvg = `
|
|
7888
|
-
<rect x="${p.x}" y="${p.y}" width="${nodeW}" height="${nodeH}" rx="
|
|
7889
|
-
<path d="M ${p.x} ${p.y +
|
|
8191
|
+
<rect x="${p.x}" y="${p.y}" width="${nodeW}" height="${nodeH}" rx="8" fill="${surfaceFill}" stroke="${nodeColor}" stroke-width="2" />
|
|
8192
|
+
<path d="M ${p.x} ${p.y + 11} C ${p.x + nodeW / 2} ${p.y + 18}, ${p.x + nodeW / 2} ${p.y + 18}, ${p.x + nodeW} ${p.y + 11}" fill="none" stroke="${nodeColor}" stroke-width="1.5"/>
|
|
7890
8193
|
`;
|
|
7891
8194
|
} else if (n.shape === "diamond") {
|
|
7892
8195
|
const cx = p.x + nodeW / 2;
|
|
7893
8196
|
const cy = p.y + nodeH / 2;
|
|
7894
|
-
shapeSvg = `<polygon points="${cx},${p.y} ${p.x + nodeW},${cy} ${cx},${p.y + nodeH} ${p.x},${cy}" fill="
|
|
8197
|
+
shapeSvg = `<polygon points="${cx},${p.y} ${p.x + nodeW},${cy} ${cx},${p.y + nodeH} ${p.x},${cy}" fill="${surfaceFill}" stroke="${nodeColor}" stroke-width="2"/>`;
|
|
7895
8198
|
} else {
|
|
7896
|
-
shapeSvg = `<rect x="${p.x}" y="${p.y}" width="${nodeW}" height="${nodeH}" rx="
|
|
8199
|
+
shapeSvg = `<rect x="${p.x}" y="${p.y}" width="${nodeW}" height="${nodeH}" rx="10" fill="${surfaceFill}" stroke="${nodeColor}" stroke-width="2" />`;
|
|
7897
8200
|
}
|
|
7898
8201
|
nodesSvg += `
|
|
7899
8202
|
<g class="yumia-diag-node" data-id="${n.id}">
|
|
7900
8203
|
${shapeSvg}
|
|
7901
|
-
<text x="${p.x + nodeW / 2}" y="${p.y + nodeH / 2 + 4}" text-anchor="middle" fill="
|
|
8204
|
+
<text x="${p.x + nodeW / 2}" y="${p.y + nodeH / 2 + 4}" text-anchor="middle" fill="${textFill}" font-size="11.5" font-weight="700" font-family="sans-serif">${this.escapeHtml(n.label)}</text>
|
|
7902
8205
|
</g>
|
|
7903
8206
|
`;
|
|
7904
8207
|
});
|
|
7905
|
-
const titleHtml = d.title ? `<div style="font-weight:700; font-size:1.
|
|
8208
|
+
const titleHtml = d.title ? `<div style="font-weight:700; font-size:1.05rem; color:var(--yumia-primary); margin-bottom:0.4rem; text-align:center;">${this.escapeHtml(d.title)}</div>` : "";
|
|
7906
8209
|
return `
|
|
7907
|
-
<div class="yumia-diagram-container"
|
|
8210
|
+
<div class="yumia-diagram-container">
|
|
7908
8211
|
${titleHtml}
|
|
7909
|
-
<svg class="yumia-diagram" viewBox="0 0 ${totalWidth} ${totalHeight}"
|
|
8212
|
+
<svg class="yumia-diagram" viewBox="0 0 ${totalWidth} ${totalHeight}" preserveAspectRatio="xMidYMid meet">
|
|
7910
8213
|
<defs>
|
|
7911
8214
|
<marker id="${markerId}" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
|
|
7912
8215
|
<path d="M 0 1.5 L 8 5 L 0 8.5 z" fill="${arrowColor}" />
|
|
@@ -8149,7 +8452,14 @@ var PdfRenderer = class {
|
|
|
8149
8452
|
}
|
|
8150
8453
|
const progressWidth = slideNum / totalSlides * pageWidth;
|
|
8151
8454
|
doc.rect(0, pageHeight - 4, progressWidth, 4).fill(theme.colors.primary);
|
|
8152
|
-
|
|
8455
|
+
if (presentation?.metadata.watermark) {
|
|
8456
|
+
const watermarkText = typeof presentation.metadata.watermark === "string" ? presentation.metadata.watermark : "CONFIDENTIAL";
|
|
8457
|
+
doc.font("Helvetica-Bold").fontSize(9).fillColor(theme.colors.muted || "#888888").text(watermarkText.toUpperCase(), padX, pageHeight - 22, {
|
|
8458
|
+
width: contentWidth - 80,
|
|
8459
|
+
align: "left"
|
|
8460
|
+
});
|
|
8461
|
+
}
|
|
8462
|
+
doc.font("Helvetica").fontSize(10).fillColor(theme.colors.muted || "#888888").text(`${slideNum} / ${totalSlides}`, pageWidth - padX - 60, pageHeight - 22, {
|
|
8153
8463
|
width: 60,
|
|
8154
8464
|
align: "right"
|
|
8155
8465
|
});
|
|
@@ -8158,18 +8468,19 @@ var PdfRenderer = class {
|
|
|
8158
8468
|
switch (element.type) {
|
|
8159
8469
|
case "hero": {
|
|
8160
8470
|
const hero = element;
|
|
8471
|
+
const align = hero.align || "center";
|
|
8161
8472
|
let curY = y;
|
|
8162
8473
|
if (hero.tagline) {
|
|
8163
8474
|
doc.font("Helvetica-Bold").fontSize(11).fillColor(theme.colors.primary);
|
|
8164
|
-
doc.text(this.stripFormatting(hero.tagline).toUpperCase(), x, curY, { width });
|
|
8475
|
+
doc.text(this.stripFormatting(hero.tagline).toUpperCase(), x, curY, { width, align });
|
|
8165
8476
|
curY += 20;
|
|
8166
8477
|
}
|
|
8167
8478
|
doc.font("Helvetica-Bold").fontSize(34).fillColor(theme.colors.text);
|
|
8168
|
-
doc.text(this.stripFormatting(hero.title), x, curY, { width, lineGap: 6 });
|
|
8479
|
+
doc.text(this.stripFormatting(hero.title), x, curY, { width, lineGap: 6, align });
|
|
8169
8480
|
curY += doc.heightOfString(this.stripFormatting(hero.title), { width }) + 8;
|
|
8170
8481
|
if (hero.subtitle) {
|
|
8171
8482
|
doc.font("Helvetica").fontSize(16).fillColor(theme.colors.muted || "#888888");
|
|
8172
|
-
doc.text(this.stripFormatting(hero.subtitle), x, curY, { width, lineGap: 4 });
|
|
8483
|
+
doc.text(this.stripFormatting(hero.subtitle), x, curY, { width, lineGap: 4, align });
|
|
8173
8484
|
curY += doc.heightOfString(this.stripFormatting(hero.subtitle), { width }) + 12;
|
|
8174
8485
|
}
|
|
8175
8486
|
if (hero.elements) {
|
|
@@ -8290,20 +8601,24 @@ var PdfRenderer = class {
|
|
|
8290
8601
|
const card = element;
|
|
8291
8602
|
const variantColor = this.getVariantColor(card.variant, theme);
|
|
8292
8603
|
const cardPad = 14;
|
|
8293
|
-
let
|
|
8604
|
+
let estHeight = cardPad * 2;
|
|
8294
8605
|
if (card.title) {
|
|
8295
|
-
doc.font("Helvetica-Bold").fontSize(15)
|
|
8296
|
-
|
|
8297
|
-
});
|
|
8298
|
-
cardCursorY += 22;
|
|
8606
|
+
doc.font("Helvetica-Bold").fontSize(15);
|
|
8607
|
+
estHeight += doc.heightOfString(this.stripFormatting(card.title), { width: width - cardPad * 2 }) + 8;
|
|
8299
8608
|
}
|
|
8300
8609
|
if (card.elements) {
|
|
8301
8610
|
for (const child of card.elements) {
|
|
8302
|
-
|
|
8303
|
-
|
|
8611
|
+
if (child.type === "metric")
|
|
8612
|
+
estHeight += 95;
|
|
8613
|
+
else if (child.type === "paragraph") {
|
|
8614
|
+
doc.font("Helvetica").fontSize(12);
|
|
8615
|
+
estHeight += doc.heightOfString(this.stripFormatting(child.text), { width: width - cardPad * 2 }) + 8;
|
|
8616
|
+
} else {
|
|
8617
|
+
estHeight += 45;
|
|
8618
|
+
}
|
|
8304
8619
|
}
|
|
8305
8620
|
}
|
|
8306
|
-
const totalCardHeight = Math.max(
|
|
8621
|
+
const totalCardHeight = Math.max(80, estHeight);
|
|
8307
8622
|
doc.save();
|
|
8308
8623
|
doc.roundedRect(x, y, width, totalCardHeight, 8).fill(theme.colors.surface || "rgba(255,255,255,0.06)");
|
|
8309
8624
|
doc.roundedRect(x, y, width, totalCardHeight, 8).lineWidth(1.5).strokeColor(variantColor).stroke();
|
|
@@ -8313,12 +8628,11 @@ var PdfRenderer = class {
|
|
|
8313
8628
|
doc.font("Helvetica-Bold").fontSize(15).fillColor(variantColor).text(this.stripFormatting(card.title), x + cardPad, renderTop, {
|
|
8314
8629
|
width: width - cardPad * 2
|
|
8315
8630
|
});
|
|
8316
|
-
renderTop +=
|
|
8631
|
+
renderTop += doc.heightOfString(this.stripFormatting(card.title), { width: width - cardPad * 2 }) + 8;
|
|
8317
8632
|
}
|
|
8318
8633
|
if (card.elements) {
|
|
8319
8634
|
for (const child of card.elements) {
|
|
8320
|
-
renderTop = this.renderElement(doc, child, x + cardPad, renderTop, width - cardPad * 2, theme);
|
|
8321
|
-
renderTop += 8;
|
|
8635
|
+
renderTop = this.renderElement(doc, child, x + cardPad, renderTop, width - cardPad * 2, theme, presentation) + 6;
|
|
8322
8636
|
}
|
|
8323
8637
|
}
|
|
8324
8638
|
return y + totalCardHeight;
|
|
@@ -8326,15 +8640,15 @@ var PdfRenderer = class {
|
|
|
8326
8640
|
case "metric": {
|
|
8327
8641
|
const m = element;
|
|
8328
8642
|
const variantColor = this.getVariantColor(m.variant, theme);
|
|
8329
|
-
const boxHeight =
|
|
8643
|
+
const boxHeight = 85;
|
|
8330
8644
|
doc.roundedRect(x, y, width, boxHeight, 8).fill(theme.colors.surface || "rgba(255,255,255,0.06)");
|
|
8331
8645
|
doc.roundedRect(x, y, width, boxHeight, 8).lineWidth(1.5).strokeColor(variantColor).stroke();
|
|
8332
|
-
doc.font("Helvetica-Bold").fontSize(
|
|
8646
|
+
doc.font("Helvetica-Bold").fontSize(10).fillColor(theme.colors.muted || "#888888").text(m.label.toUpperCase(), x + 14, y + 12, { width: width - 28 });
|
|
8333
8647
|
const displayVal = m.unit ? `${m.value} ${m.unit}` : m.value;
|
|
8334
|
-
doc.font("Helvetica-Bold").fontSize(
|
|
8648
|
+
doc.font("Helvetica-Bold").fontSize(26).fillColor(variantColor).text(displayVal, x + 14, y + 28, { width: width - 28 });
|
|
8335
8649
|
if (m.change) {
|
|
8336
8650
|
const changeColor = m.change.startsWith("+") ? "#10b981" : "#ef4444";
|
|
8337
|
-
doc.font("Helvetica-Bold").fontSize(
|
|
8651
|
+
doc.font("Helvetica-Bold").fontSize(11).fillColor(changeColor).text(m.change, x + width - 85, y + 34, { width: 70, align: "right" });
|
|
8338
8652
|
}
|
|
8339
8653
|
return y + boxHeight;
|
|
8340
8654
|
}
|
|
@@ -8357,7 +8671,7 @@ var PdfRenderer = class {
|
|
|
8357
8671
|
const colWidth = ratios[i] / totalRatio * availableWidth;
|
|
8358
8672
|
let colCursorY = y;
|
|
8359
8673
|
for (const child of col.elements) {
|
|
8360
|
-
colCursorY = this.renderElement(doc, child, curX, colCursorY, colWidth, theme);
|
|
8674
|
+
colCursorY = this.renderElement(doc, child, curX, colCursorY, colWidth, theme, presentation);
|
|
8361
8675
|
colCursorY += 8;
|
|
8362
8676
|
}
|
|
8363
8677
|
if (colCursorY > maxY)
|
|
@@ -8448,27 +8762,65 @@ var PdfRenderer = class {
|
|
|
8448
8762
|
}
|
|
8449
8763
|
case "compare": {
|
|
8450
8764
|
const c = element;
|
|
8451
|
-
const colW = (width -
|
|
8452
|
-
|
|
8453
|
-
let
|
|
8765
|
+
const colW = (width - 32) / 2;
|
|
8766
|
+
const pad = 14;
|
|
8767
|
+
let leftContentH = 0;
|
|
8768
|
+
if (c.leftTitle)
|
|
8769
|
+
leftContentH += 24;
|
|
8770
|
+
for (const el of c.left) {
|
|
8771
|
+
if (el.type === "metric")
|
|
8772
|
+
leftContentH += 95;
|
|
8773
|
+
else if (el.type === "paragraph") {
|
|
8774
|
+
doc.font("Helvetica").fontSize(12);
|
|
8775
|
+
leftContentH += doc.heightOfString(this.stripFormatting(el.text), { width: colW - pad * 2 }) + 8;
|
|
8776
|
+
} else if (el.type === "badge")
|
|
8777
|
+
leftContentH += 32;
|
|
8778
|
+
else
|
|
8779
|
+
leftContentH += 45;
|
|
8780
|
+
}
|
|
8781
|
+
let rightContentH = 0;
|
|
8782
|
+
if (c.rightTitle)
|
|
8783
|
+
rightContentH += 24;
|
|
8784
|
+
for (const el of c.right) {
|
|
8785
|
+
if (el.type === "metric")
|
|
8786
|
+
rightContentH += 95;
|
|
8787
|
+
else if (el.type === "paragraph") {
|
|
8788
|
+
doc.font("Helvetica").fontSize(12);
|
|
8789
|
+
rightContentH += doc.heightOfString(this.stripFormatting(el.text), { width: colW - pad * 2 }) + 8;
|
|
8790
|
+
} else if (el.type === "badge")
|
|
8791
|
+
rightContentH += 32;
|
|
8792
|
+
else
|
|
8793
|
+
rightContentH += 45;
|
|
8794
|
+
}
|
|
8795
|
+
const totalH = Math.max(leftContentH, rightContentH, 90) + pad * 2;
|
|
8796
|
+
const rightX = x + colW + 32;
|
|
8797
|
+
doc.save();
|
|
8798
|
+
doc.roundedRect(x, y, colW, totalH, 8).fill(theme.colors.surface || "rgba(255,255,255,0.06)");
|
|
8799
|
+
doc.roundedRect(x, y, colW, totalH, 8).lineWidth(1.5).strokeColor(theme.colors.border || "rgba(255,255,255,0.15)").stroke();
|
|
8800
|
+
doc.roundedRect(rightX, y, colW, totalH, 8).fill(theme.colors.surface || "rgba(255,255,255,0.06)");
|
|
8801
|
+
doc.roundedRect(rightX, y, colW, totalH, 8).lineWidth(1.5).strokeColor(theme.colors.border || "rgba(255,255,255,0.15)").stroke();
|
|
8802
|
+
const vsX = x + colW + 4;
|
|
8803
|
+
const vsY = y + totalH / 2 - 12;
|
|
8804
|
+
doc.roundedRect(vsX, vsY, 24, 24, 12).fill(theme.colors.surface || "#151522");
|
|
8805
|
+
doc.roundedRect(vsX, vsY, 24, 24, 12).lineWidth(1).strokeColor(theme.colors.border || "rgba(255,255,255,0.2)").stroke();
|
|
8806
|
+
doc.font("Helvetica-Bold").fontSize(9).fillColor(theme.colors.muted || "#888888").text("VS", vsX, vsY + 7, { width: 24, align: "center" });
|
|
8807
|
+
doc.restore();
|
|
8808
|
+
let leftY = y + pad;
|
|
8454
8809
|
if (c.leftTitle) {
|
|
8455
|
-
doc.font("Helvetica-Bold").fontSize(14).fillColor(theme.colors.primary).text(this.stripFormatting(c.leftTitle), x +
|
|
8456
|
-
leftY +=
|
|
8810
|
+
doc.font("Helvetica-Bold").fontSize(14).fillColor(theme.colors.primary).text(this.stripFormatting(c.leftTitle), x + pad, leftY, { width: colW - pad * 2 });
|
|
8811
|
+
leftY += 24;
|
|
8457
8812
|
}
|
|
8458
8813
|
for (const el of c.left) {
|
|
8459
|
-
leftY = this.renderElement(doc, el, x +
|
|
8814
|
+
leftY = this.renderElement(doc, el, x + pad, leftY, colW - pad * 2, theme, presentation) + 6;
|
|
8460
8815
|
}
|
|
8461
|
-
|
|
8816
|
+
let rightY = y + pad;
|
|
8462
8817
|
if (c.rightTitle) {
|
|
8463
|
-
doc.font("Helvetica-Bold").fontSize(14).fillColor(theme.colors.primary).text(this.stripFormatting(c.rightTitle), rightX +
|
|
8464
|
-
rightY +=
|
|
8818
|
+
doc.font("Helvetica-Bold").fontSize(14).fillColor(theme.colors.primary).text(this.stripFormatting(c.rightTitle), rightX + pad, rightY, { width: colW - pad * 2 });
|
|
8819
|
+
rightY += 24;
|
|
8465
8820
|
}
|
|
8466
8821
|
for (const el of c.right) {
|
|
8467
|
-
rightY = this.renderElement(doc, el, rightX +
|
|
8822
|
+
rightY = this.renderElement(doc, el, rightX + pad, rightY, colW - pad * 2, theme, presentation) + 6;
|
|
8468
8823
|
}
|
|
8469
|
-
const totalH = Math.max(leftY - y, rightY - y, 60) + 12;
|
|
8470
|
-
doc.roundedRect(x, y, colW, totalH, 8).strokeColor(theme.colors.border || "rgba(255,255,255,0.15)").stroke();
|
|
8471
|
-
doc.roundedRect(rightX, y, colW, totalH, 8).strokeColor(theme.colors.border || "rgba(255,255,255,0.15)").stroke();
|
|
8472
8824
|
return y + totalH + 8;
|
|
8473
8825
|
}
|
|
8474
8826
|
case "chart": {
|
|
@@ -8705,22 +9057,30 @@ var PdfRenderer = class {
|
|
|
8705
9057
|
titleOffset = 24;
|
|
8706
9058
|
}
|
|
8707
9059
|
const startY = y + titleOffset;
|
|
9060
|
+
const maxLaneHeight = isLR ? maxLane * (nodeH + gapY) - gapY : numRanks * (nodeH + gapY) - gapY;
|
|
9061
|
+
const maxRankWidth = isLR ? numRanks * (nodeW + gapX) - gapX : maxLane * (nodeW + gapX) - gapX;
|
|
8708
9062
|
const positions = {};
|
|
8709
9063
|
sortedRanks.forEach((r, rIdx) => {
|
|
8710
9064
|
const ids = rankGroups[r];
|
|
8711
|
-
|
|
8712
|
-
|
|
9065
|
+
if (isLR) {
|
|
9066
|
+
const colHeight = ids.length * (nodeH + gapY) - gapY;
|
|
9067
|
+
const offsetY = (maxLaneHeight - colHeight) / 2;
|
|
9068
|
+
ids.forEach((id, lIdx) => {
|
|
8713
9069
|
positions[id] = {
|
|
8714
9070
|
x: x + 20 + rIdx * (nodeW + gapX),
|
|
8715
|
-
y: startY + 10 + lIdx * (nodeH + gapY)
|
|
9071
|
+
y: startY + 10 + offsetY + lIdx * (nodeH + gapY)
|
|
8716
9072
|
};
|
|
8717
|
-
}
|
|
9073
|
+
});
|
|
9074
|
+
} else {
|
|
9075
|
+
const rowWidth = ids.length * (nodeW + gapX) - gapX;
|
|
9076
|
+
const offsetX = (maxRankWidth - rowWidth) / 2;
|
|
9077
|
+
ids.forEach((id, lIdx) => {
|
|
8718
9078
|
positions[id] = {
|
|
8719
|
-
x: x + 20 + lIdx * (nodeW + gapX),
|
|
9079
|
+
x: x + 20 + offsetX + lIdx * (nodeW + gapX),
|
|
8720
9080
|
y: startY + 10 + rIdx * (nodeH + gapY)
|
|
8721
9081
|
};
|
|
8722
|
-
}
|
|
8723
|
-
}
|
|
9082
|
+
});
|
|
9083
|
+
}
|
|
8724
9084
|
});
|
|
8725
9085
|
const arrowColor = theme.colors.accent || theme.colors.primary;
|
|
8726
9086
|
diagram.edges.forEach((e) => {
|
|
@@ -8768,7 +9128,7 @@ var PdfRenderer = class {
|
|
|
8768
9128
|
doc.roundedRect(p.x, p.y, nodeW, nodeH, 6).fill(theme.colors.surface || "#151522");
|
|
8769
9129
|
doc.roundedRect(p.x, p.y, nodeW, nodeH, 6).lineWidth(1.5).strokeColor(nodeColor).stroke();
|
|
8770
9130
|
doc.restore();
|
|
8771
|
-
doc.font("Helvetica-Bold").fontSize(10).fillColor(
|
|
9131
|
+
doc.font("Helvetica-Bold").fontSize(10).fillColor(theme.colors.text).text(this.stripFormatting(n.label), p.x + 4, p.y + nodeH / 2 - 5, {
|
|
8772
9132
|
width: nodeW - 8,
|
|
8773
9133
|
align: "center"
|
|
8774
9134
|
});
|
|
@@ -8910,7 +9270,7 @@ function startDevServer(filePath, options = {}) {
|
|
|
8910
9270
|
// src/cli.ts
|
|
8911
9271
|
import { mkdirSync, readFileSync as readFileSync3, watch as fsWatch, writeFileSync } from "fs";
|
|
8912
9272
|
import { basename, dirname, extname, join, resolve as resolve2 } from "path";
|
|
8913
|
-
var VERSION = "0.1.
|
|
9273
|
+
var VERSION = "0.1.27";
|
|
8914
9274
|
function printHelp() {
|
|
8915
9275
|
return `
|
|
8916
9276
|
YumiaMD \u2014 Markdown-based presentation compiler (v${VERSION})
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export * from '@yumiamd/renderer-pptx';
|
|
|
9
9
|
export * from '@yumiamd/renderer-html';
|
|
10
10
|
export * from '@yumiamd/renderer-pdf';
|
|
11
11
|
|
|
12
|
-
declare const VERSION = "0.1.
|
|
12
|
+
declare const VERSION = "0.1.27";
|
|
13
13
|
declare function printHelp(): string;
|
|
14
14
|
declare function runCli(argv: string[]): Promise<{
|
|
15
15
|
exitCode: number;
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yumiamd",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.27",
|
|
4
4
|
"description": "Command line interface and compiler for YumiaMD presentations",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -21,15 +21,15 @@
|
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"tsup": "^8.5.1",
|
|
24
|
-
"@yumiamd/ast": "0.1.
|
|
25
|
-
"@yumiamd/
|
|
26
|
-
"@yumiamd/
|
|
27
|
-
"@yumiamd/
|
|
28
|
-
"@yumiamd/
|
|
29
|
-
"@yumiamd/renderer-html": "0.1.
|
|
30
|
-
"@yumiamd/renderer-
|
|
31
|
-
"@yumiamd/
|
|
32
|
-
"@yumiamd/
|
|
24
|
+
"@yumiamd/ast": "0.1.27",
|
|
25
|
+
"@yumiamd/layout": "0.1.27",
|
|
26
|
+
"@yumiamd/core": "0.1.27",
|
|
27
|
+
"@yumiamd/parser": "0.1.27",
|
|
28
|
+
"@yumiamd/renderer": "0.1.27",
|
|
29
|
+
"@yumiamd/renderer-html": "0.1.27",
|
|
30
|
+
"@yumiamd/renderer-pptx": "0.1.27",
|
|
31
|
+
"@yumiamd/theme": "0.1.27",
|
|
32
|
+
"@yumiamd/renderer-pdf": "0.1.27"
|
|
33
33
|
},
|
|
34
34
|
"keywords": [
|
|
35
35
|
"yumia",
|