pptx-kit-preview 0.6.0 → 0.6.1

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/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as SERIF, c as substituteFamily, i as SANS, n as ARIAL, o as TIMES, r as MONO, s as defaultMeasurer, t as renderSlideSvg } from "./src-DDyW3xOV.js";
1
+ import { a as SERIF, c as substituteFamily, i as SANS, n as ARIAL, o as TIMES, r as MONO, s as defaultMeasurer, t as renderSlideSvg } from "./src-Q2z_XgT6.js";
2
2
  export { ARIAL, MONO, SANS, SERIF, TIMES, defaultMeasurer, renderSlideSvg as renderSlideToSvg, substituteFamily };
package/dist/node.js CHANGED
@@ -1,4 +1,4 @@
1
- import { a as SERIF, c as substituteFamily, i as SANS, n as ARIAL, o as TIMES, r as MONO, s as defaultMeasurer, t as renderSlideSvg } from "./src-DDyW3xOV.js";
1
+ import { a as SERIF, c as substituteFamily, i as SANS, n as ARIAL, o as TIMES, r as MONO, s as defaultMeasurer, t as renderSlideSvg } from "./src-Q2z_XgT6.js";
2
2
  import { getSlideSize } from "pptx-kit";
3
3
  import { Resvg } from "@resvg/resvg-js";
4
4
  import * as fontkit from "fontkit";
@@ -255,22 +255,27 @@ const placeColumns = (frame, columns, anchor, buildLines) => {
255
255
  const { lines } = buildLines(frame.x, frame.x + colW);
256
256
  let col = 0;
257
257
  let colStartTopY = 0;
258
- const colHasLine = [];
258
+ let rowTopY = 0;
259
+ let curColHasLine = false;
259
260
  let tallest = 0;
260
261
  const placed = [];
261
262
  for (const line of lines) {
262
- const localBottom = line.topY - colStartTopY + line.advance;
263
- if (col < columns.count - 1 && localBottom > frame.h && colHasLine[col]) {
264
- col += 1;
263
+ if (line.topY - colStartTopY + line.ascent + line.descent > frame.h && curColHasLine) {
264
+ if (col + 1 < columns.count) col += 1;
265
+ else {
266
+ col = 0;
267
+ rowTopY += frame.h;
268
+ }
265
269
  colStartTopY = line.topY;
270
+ curColHasLine = false;
266
271
  }
267
- const localTopY = line.topY - colStartTopY;
272
+ const localTopY = rowTopY + (line.topY - colStartTopY);
268
273
  placed.push({
269
274
  line,
270
275
  localTopY,
271
276
  col
272
277
  });
273
- colHasLine[col] = true;
278
+ curColHasLine = true;
274
279
  if (localTopY + line.advance > tallest) tallest = localTopY + line.advance;
275
280
  }
276
281
  const offsetY = anchorOffsetY(frame.y, frame.h, tallest, anchor, lines[0]);
@@ -312,27 +317,76 @@ const emitLine = (line, baselineY, dx) => {
312
317
  while (toks.length > 0 && (toks[toks.length - 1].isSpace || toks[toks.length - 1].isBreak)) toks.pop();
313
318
  const content = toks.filter((t) => !t.isBreak);
314
319
  if (content.length === 0) return "";
315
- const tspans = groupTokens(content).map((g) => tspan(g)).join("");
320
+ const groups = groupTokens(content);
321
+ const tspans = groups.map((g) => tspan(g)).join("");
316
322
  if (tspans === "") return "";
317
- return `<text x="${fmt(line.anchorX + dx + GRID_NUDGE_X)}" y="${fmt(baselineY)}" text-anchor="${line.textAnchor}" xml:space="preserve">${tspans}</text>`;
323
+ const x0 = line.anchorX + dx + GRID_NUDGE_X;
324
+ return `<text x="${fmt(x0)}" y="${fmt(baselineY)}" text-anchor="${line.textAnchor}" xml:space="preserve">${tspans}</text>` + emitWavyUnderlines(groups, line.textAnchor, x0, baselineY);
318
325
  };
319
326
  const groupTokens = (toks) => {
320
327
  const groups = [];
321
328
  for (const t of toks) {
322
329
  if (t.isBreak) continue;
323
330
  const last = groups[groups.length - 1];
324
- if (last && samePiece(last.piece, t.piece)) last.text += t.text;
325
- else groups.push({
331
+ if (last && samePiece(last.piece, t.piece)) {
332
+ last.text += t.text;
333
+ last.width += t.width;
334
+ } else groups.push({
326
335
  text: t.text,
327
- piece: t.piece
336
+ piece: t.piece,
337
+ width: t.width
328
338
  });
329
339
  }
330
340
  return groups;
331
341
  };
342
+ const SUPERSCRIPT_SHIFT_RATIO = .33;
343
+ const SUBSCRIPT_SHIFT_RATIO = .16;
344
+ const baselineShiftPxOf = (p) => p.superSub === 1 ? p.sizePx * SUPERSCRIPT_SHIFT_RATIO : p.superSub === -1 ? -p.sizePx * SUBSCRIPT_SHIFT_RATIO : 0;
345
+ const SUPER_SUB_SIZE_RATIO = .65;
346
+ const renderedSizePxOf = (p) => p.superSub !== 0 ? p.sizePx * SUPER_SUB_SIZE_RATIO : p.sizePx;
347
+ const emitWavyUnderlines = (groups, textAnchor, x0, baselineY) => {
348
+ if (!groups.some((g) => g.piece.underline === "wavy")) return "";
349
+ const totalWidth = groups.reduce((sum, g) => sum + g.width, 0);
350
+ let cursor = textAnchor === "middle" ? x0 - totalWidth / 2 : textAnchor === "end" ? x0 - totalWidth : x0;
351
+ const parts = [];
352
+ for (const g of groups) {
353
+ if (g.piece.underline === "wavy" && g.width > 0) {
354
+ const y = baselineY - baselineShiftPxOf(g.piece);
355
+ parts.push(wavyPath(cursor, cursor + g.width, y, g.piece));
356
+ }
357
+ cursor += g.width;
358
+ }
359
+ return parts.join("");
360
+ };
361
+ const WAVY_AMPLITUDE_RATIO = .045;
362
+ const WAVY_AMPLITUDE_MIN_PX = .6;
363
+ const WAVY_PERIOD_RATIO = .18;
364
+ const WAVY_PERIOD_MIN_PX = 2;
365
+ const WAVY_BASELINE_OFFSET_RATIO = .12;
366
+ const WAVY_STROKE_WIDTH_RATIO = .06;
367
+ const WAVY_STROKE_WIDTH_MIN_PX = .6;
368
+ const wavyPath = (x1, x2, baselineY, piece) => {
369
+ const size = renderedSizePxOf(piece);
370
+ const amp = Math.max(WAVY_AMPLITUDE_MIN_PX, size * WAVY_AMPLITUDE_RATIO);
371
+ const period = Math.max(WAVY_PERIOD_MIN_PX, size * WAVY_PERIOD_RATIO);
372
+ const y = baselineY + size * WAVY_BASELINE_OFFSET_RATIO;
373
+ let d = `M${fmt(x1)} ${fmt(y)}`;
374
+ let cx = x1;
375
+ let up = true;
376
+ while (cx < x2 - .01) {
377
+ const half = Math.min(period / 2, x2 - cx);
378
+ const midX = cx + half;
379
+ d += ` Q${fmt(cx + half / 2)} ${fmt(y + (up ? -amp : amp))} ${fmt(midX)} ${fmt(y)}`;
380
+ cx = midX;
381
+ up = !up;
382
+ }
383
+ const strokeWidth = Math.max(WAVY_STROKE_WIDTH_MIN_PX, size * WAVY_STROKE_WIDTH_RATIO);
384
+ return `<path d="${d}" stroke="${piece.fillHex}" stroke-width="${fmt(strokeWidth)}" fill="none"/>`;
385
+ };
332
386
  const samePiece = (a, b) => a.family === b.family && a.sizePx === b.sizePx && a.bold === b.bold && a.italic === b.italic && a.letterSpacingPx === b.letterSpacingPx && a.fillHex === b.fillHex && a.underline === b.underline && a.strike === b.strike && a.superSub === b.superSub && a.href === b.href;
333
387
  const tspan = (g) => {
334
388
  const p = g.piece;
335
- const sizePx = p.superSub !== 0 ? p.sizePx * .65 : p.sizePx;
389
+ const sizePx = renderedSizePxOf(p);
336
390
  const attrs = [
337
391
  `font-family="${escapeXml$1(p.family)}"`,
338
392
  `font-size="${fmt(sizePx)}"`,
@@ -341,12 +395,11 @@ const tspan = (g) => {
341
395
  if (p.bold) attrs.push("font-weight=\"700\"");
342
396
  if (p.italic) attrs.push("font-style=\"italic\"");
343
397
  const deco = [];
344
- if (p.underline) deco.push("underline");
398
+ if (p.underline === "single") deco.push("underline");
345
399
  if (p.strike) deco.push("line-through");
346
400
  if (deco.length) attrs.push(`text-decoration="${deco.join(" ")}"`);
347
401
  if (p.letterSpacingPx !== 0) attrs.push(`letter-spacing="${fmt(p.letterSpacingPx)}"`);
348
- if (p.superSub === 1) attrs.push(`baseline-shift="${fmt(p.sizePx * .33)}"`);
349
- else if (p.superSub === -1) attrs.push(`baseline-shift="${fmt(-p.sizePx * .16)}"`);
402
+ if (p.superSub !== 0) attrs.push(`baseline-shift="${fmt(baselineShiftPxOf(p))}"`);
350
403
  return `<tspan ${attrs.join(" ")}>${escapeXml$1(g.text)}</tspan>`;
351
404
  };
352
405
  const wrapTokens = (tokens, wrap, firstAvail, avail) => {
@@ -617,50 +670,56 @@ const gradientDef = (grad, theme) => {
617
670
  fillAttr: `url(#${id})`
618
671
  };
619
672
  };
673
+ const ORTHO_TILE = 4;
674
+ const ORTHO_WIDE_TILE = 16;
675
+ const DIAG_TILE = 16;
676
+ const MOTIF_TILE = 8;
677
+ const PATTERN_TILE_SIZE = {
678
+ horz: ORTHO_TILE,
679
+ ltHorz: ORTHO_TILE,
680
+ narHorz: ORTHO_TILE,
681
+ dashHorz: ORTHO_TILE,
682
+ horzBrick: ORTHO_TILE,
683
+ dkHorz: ORTHO_TILE,
684
+ vert: ORTHO_TILE,
685
+ ltVert: ORTHO_TILE,
686
+ narVert: ORTHO_TILE,
687
+ dashVert: ORTHO_TILE,
688
+ dkVert: ORTHO_TILE,
689
+ ltHorzCross: ORTHO_TILE,
690
+ cross: ORTHO_TILE,
691
+ dotGrid: ORTHO_TILE,
692
+ smGrid: ORTHO_TILE,
693
+ dkHorzCross: ORTHO_WIDE_TILE,
694
+ lgGrid: ORTHO_WIDE_TILE,
695
+ plaid: ORTHO_WIDE_TILE,
696
+ wave: MOTIF_TILE,
697
+ zigZag: MOTIF_TILE,
698
+ weave: MOTIF_TILE,
699
+ divot: MOTIF_TILE,
700
+ sphere: MOTIF_TILE,
701
+ solidDmnd: MOTIF_TILE,
702
+ openDmnd: MOTIF_TILE
703
+ };
620
704
  const patternDef = (pat) => {
621
705
  const id = mintId();
622
706
  const fg = pat.foreground;
623
707
  const bg = pat.background;
624
708
  const preset = pat.preset;
625
709
  let body = "";
626
- const W = 8;
627
- const H = 8;
710
+ const PCT_DENSITY_FLOOR = .05;
711
+ const PCT_TILE_MIN = 6;
712
+ const pctMatch = /^pct(\d+)$/.exec(preset);
713
+ const pctDensity = pctMatch ? Math.min(100, Math.max(0, Number.parseInt(pctMatch[1], 10))) / 100 : null;
714
+ const W = pctDensity !== null ? Math.max(PCT_TILE_MIN, DIAG_TILE * 2 * Math.sqrt(PCT_DENSITY_FLOOR / Math.max(pctDensity, PCT_DENSITY_FLOOR))) : PATTERN_TILE_SIZE[preset] ?? DIAG_TILE;
715
+ const H = W;
628
716
  const stripe = (orientation, width = 1) => {
629
717
  if (orientation === "h") return `<path d="M0 ${H / 2}H${W}" stroke="${fg}" stroke-width="${width}"/>`;
630
718
  if (orientation === "v") return `<path d="M${W / 2} 0V${H}" stroke="${fg}" stroke-width="${width}"/>`;
631
719
  if (orientation === "d") return `<path d="M0 0L${W} ${H}" stroke="${fg}" stroke-width="${width}"/>`;
632
720
  return `<path d="M${W} 0L0 ${H}" stroke="${fg}" stroke-width="${width}"/>`;
633
721
  };
634
- const BAYER4 = [
635
- 0,
636
- 8,
637
- 2,
638
- 10,
639
- 12,
640
- 4,
641
- 14,
642
- 6,
643
- 3,
644
- 11,
645
- 1,
646
- 9,
647
- 15,
648
- 7,
649
- 13,
650
- 5
651
- ];
652
- const screen = (density) => {
653
- const threshold = density * 16;
654
- const out = [];
655
- for (let i = 0; i < 16; i++) if (BAYER4[i] < threshold) {
656
- const cx = i % 4 * 2;
657
- const cy = Math.floor(i / 4) * 2;
658
- out.push(`<rect x="${cx}" y="${cy}" width="2" height="2" fill="${fg}"/>`);
659
- }
660
- return out.join("");
661
- };
662
- const pctMatch = /^pct(\d+)$/.exec(preset);
663
- if (pctMatch) body = screen(Math.min(100, Math.max(0, Number.parseInt(pctMatch[1], 10))) / 100);
722
+ if (pctDensity !== null) body = pctDensity >= .3 ? stripe("d", .8) + stripe("a", .8) : stripe("d", .8);
664
723
  else if (preset === "horz" || preset === "ltHorz" || preset === "narHorz" || preset === "dashHorz" || preset === "horzBrick") body = stripe("h", .8);
665
724
  else if (preset === "dkHorz") body = stripe("h", 2);
666
725
  else if (preset === "vert" || preset === "ltVert" || preset === "narVert" || preset === "dashVert") body = stripe("v", .8);
@@ -677,7 +736,7 @@ const patternDef = (pat) => {
677
736
  else if (preset === "weave" || preset === "divot") body = `<path d="M0 0L4 4 0 8M4 0L8 4 4 8" stroke="${fg}" stroke-width="0.8" fill="none"/>`;
678
737
  else if (preset === "sphere") body = `<circle cx="4" cy="4" r="3" fill="${fg}" fill-opacity="0.7"/>`;
679
738
  else if (preset === "solidDmnd" || preset === "openDmnd") body = `<path d="M4 1L7 4 4 7 1 4Z" fill="${preset === "solidDmnd" ? fg : "none"}" stroke="${fg}" stroke-width="0.6"/>`;
680
- else body = screen(.5);
739
+ else body = stripe("d", .8) + stripe("a", .8);
681
740
  return {
682
741
  defs: `<defs><pattern id="${id}" patternUnits="userSpaceOnUse" width="${W}" height="${H}"><rect width="${W}" height="${H}" fill="${bg}"/>${body}</pattern></defs>`,
683
742
  fillAttr: `url(#${id})`
@@ -1789,9 +1848,14 @@ const renderRun = (text, format, theme, effectivePt, _wasDefault = false) => {
1789
1848
  const strike = format?.strike;
1790
1849
  const hasUnderline = underline !== void 0 && underline !== false && underline !== "none";
1791
1850
  const hasStrike = strike !== void 0 && strike !== false && strike !== "noStrike";
1792
- if (hasUnderline && hasStrike) styles.push("text-decoration:underline line-through");
1793
- else if (hasUnderline) styles.push("text-decoration:underline");
1794
- else if (hasStrike) styles.push("text-decoration:line-through");
1851
+ const isWavyUnderline = typeof underline === "string" && underline.startsWith("wavy");
1852
+ const nestedWavyUnderline = hasUnderline && hasStrike && isWavyUnderline;
1853
+ if (nestedWavyUnderline) styles.push("text-decoration:line-through");
1854
+ else if (hasUnderline && hasStrike) styles.push("text-decoration:underline line-through");
1855
+ else if (hasUnderline) {
1856
+ styles.push("text-decoration:underline");
1857
+ if (isWavyUnderline) styles.push("text-decoration-style:wavy");
1858
+ } else if (hasStrike) styles.push("text-decoration:line-through");
1795
1859
  if (format?.color !== void 0 && format.color !== null) styles.push(`color:${resolveColor(format.color, theme, "#000000")}`);
1796
1860
  if (format?.spc !== void 0 && format.spc !== 0) {
1797
1861
  const trackingPx = format.spc / 100 * PX_PER_PT;
@@ -1806,15 +1870,18 @@ const renderRun = (text, format, theme, effectivePt, _wasDefault = false) => {
1806
1870
  else if (format?.cap === "small") styles.push("font-variant:small-caps");
1807
1871
  if (format?.highlight !== void 0 && format.highlight !== null) styles.push(`background-color:${resolveColor(format.highlight, theme, "#FFFF00")}`);
1808
1872
  const html = text.split("\n").map((part) => escapeXml(part)).join("<br/>");
1809
- return `<span style="${styles.join(";")}">${html}</span>`;
1873
+ const content = nestedWavyUnderline ? `<span style="text-decoration:underline;text-decoration-style:wavy">${html}</span>` : html;
1874
+ return `<span style="${styles.join(";")}">${content}</span>`;
1810
1875
  };
1811
1876
  const LINE_HEIGHT = 1.05;
1812
1877
  const AVG_GLYPH_W_RATIO = .55;
1813
1878
  const AUTOFIT_FLOOR = .25;
1814
1879
  const AUTOFIT_STEP = .05;
1815
- const hasUnderlineFmt = (fmt) => {
1880
+ const underlineStyleOf = (fmt) => {
1816
1881
  const u = fmt?.underline;
1817
- return u !== void 0 && u !== false && u !== "none";
1882
+ if (u === void 0 || u === false || u === "none") return "none";
1883
+ if (typeof u === "string" && u.startsWith("wavy")) return "wavy";
1884
+ return "single";
1818
1885
  };
1819
1886
  const hasStrikeFmt = (fmt) => {
1820
1887
  const s = fmt?.strike;
@@ -1863,7 +1930,7 @@ const buildSvgTextInput = (a) => {
1863
1930
  italic: fmt?.italic ?? false,
1864
1931
  letterSpacingPx,
1865
1932
  fillHex,
1866
- underline: hasUnderlineFmt(fmt),
1933
+ underline: underlineStyleOf(fmt),
1867
1934
  strike: hasStrikeFmt(fmt),
1868
1935
  superSub,
1869
1936
  href: run.href ?? null
@@ -1935,7 +2002,7 @@ const breakPiece = () => ({
1935
2002
  italic: false,
1936
2003
  letterSpacingPx: 0,
1937
2004
  fillHex: "#000000",
1938
- underline: false,
2005
+ underline: "none",
1939
2006
  strike: false,
1940
2007
  superSub: 0,
1941
2008
  href: null,
@@ -3097,6 +3164,7 @@ const renderLineChart = (f, spec, colors, fill) => {
3097
3164
  const out = [];
3098
3165
  out.push(`<line x1="${px(f.plotX)}" y1="${px(baseY)}" x2="${px(f.plotX + f.plotW)}" y2="${px(baseY)}" stroke="#E5E7EB" stroke-width="0.5"/>`);
3099
3166
  const accumulated = Array.from({ length: N }, () => 0);
3167
+ const perSeries = [];
3100
3168
  for (let s = 0; s < spec.series.length; s++) {
3101
3169
  const series = spec.series[s];
3102
3170
  if (!series) continue;
@@ -3144,10 +3212,22 @@ const renderLineChart = (f, spec, colors, fill) => {
3144
3212
  }
3145
3213
  return path.trim();
3146
3214
  })();
3147
- if (fill) {
3148
- const back = basePts.slice().reverse().map(([xp, yp]) => `L${px(xp)},${px(yp)}`).join(" ");
3149
- out.push(`<path d="${dPath} ${back} Z" fill="${color}" stroke="none"/>`);
3150
- }
3215
+ perSeries.push({
3216
+ s,
3217
+ series,
3218
+ color,
3219
+ ptsRaw,
3220
+ pts,
3221
+ basePts,
3222
+ dPath
3223
+ });
3224
+ }
3225
+ const paintOrder = fill && !isStacked ? perSeries.slice().reverse() : perSeries;
3226
+ if (fill) for (const { color, basePts, dPath } of paintOrder) {
3227
+ const back = basePts.slice().reverse().map(([xp, yp]) => `L${px(xp)},${px(yp)}`).join(" ");
3228
+ out.push(`<path d="${dPath} ${back} Z" fill="${color}" stroke="none"/>`);
3229
+ }
3230
+ for (const { s, series, color, ptsRaw, pts, dPath } of paintOrder) {
3151
3231
  const lineWPx = series.lineWidthEmu ? Math.max(.3, series.lineWidthEmu / EMU_PER_PX) : 1.5;
3152
3232
  const dashAttr = series.lineDash ? (() => {
3153
3233
  const sw = lineWPx;
@@ -3298,12 +3378,12 @@ const renderPieChart = (f, spec, colors, doughnut) => {
3298
3378
  const labelX = sx + labelR * Math.cos(labelMid);
3299
3379
  const labelY = sy + labelR * Math.sin(labelMid);
3300
3380
  const labels = [];
3301
- if (spec.dataLabels?.showValue) labels.push(formatDataLabelValue(spec, 0, v));
3302
- if (spec.dataLabels?.showPercent) labels.push(`${(v / total * 100).toFixed(0)}%`);
3303
3381
  if (spec.dataLabels?.showCategory) {
3304
3382
  const catLabel = spec.categories[i];
3305
3383
  if (catLabel) labels.push(catLabel);
3306
3384
  }
3385
+ if (spec.dataLabels?.showValue) labels.push(formatDataLabelValue(spec, 0, v));
3386
+ if (spec.dataLabels?.showPercent) labels.push(`${(v / total * 100).toFixed(0)}%`);
3307
3387
  if (labels.length > 0) out.push(`<text x="${px(labelX)}" y="${px(labelY)}" text-anchor="middle" dominant-baseline="middle" ${dataLabelTextAttrs(spec, 0, labelFill, 10, true)}>${escapeXml(labels.join(spec.series[0]?.dataLabels?.separator ?? spec.dataLabels?.separator ?? " "))}</text>`);
3308
3388
  }
3309
3389
  return out.join("");
@@ -3611,7 +3691,7 @@ const renderChart = (shape, x, y, w, h, transform, theme) => {
3611
3691
  const valueAxisTitleSvg = spec.valueAxisTitle ? `<text x="${px(f.plotX - 26)}" y="${px(f.plotY + f.plotH / 2)}" text-anchor="middle" ${axisTitleAttrs(spec.valueAxisTitleStyle)} transform="rotate(${valueAxisTitleRot} ${px(f.plotX - 26)} ${px(f.plotY + f.plotH / 2)})">${escapeXml(spec.valueAxisTitle)}</text>` : "";
3612
3692
  const catTitleRot = spec.categoryAxisTitleRotationDeg ?? 0;
3613
3693
  const catTitleCx = f.plotX + f.plotW / 2;
3614
- const catTitleCy = f.plotY + f.plotH + 16;
3694
+ const catTitleCy = f.plotY + f.plotH + 28;
3615
3695
  const catTitleTransform = catTitleRot !== 0 ? ` transform="rotate(${catTitleRot} ${px(catTitleCx)} ${px(catTitleCy)})"` : "";
3616
3696
  const categoryAxisTitleSvg = spec.categoryAxisTitle ? `<text x="${px(catTitleCx)}" y="${px(catTitleCy)}" text-anchor="middle" ${axisTitleAttrs(spec.categoryAxisTitleStyle)}${catTitleTransform}>${escapeXml(spec.categoryAxisTitle)}</text>` : "";
3617
3697
  return [
@@ -3746,7 +3826,8 @@ const renderTable = (shape, pres, x, y, w, h, transform, theme, ctx) => {
3746
3826
  const flags = getTableStyleFlags(shape);
3747
3827
  const accent = theme ? normalizeHex(theme.accent1) : "#4472C4";
3748
3828
  const headerFill = accent;
3749
- const bandFill = mixHex(accent, "#FFFFFF", .92);
3829
+ const bandFill = mixHex(accent, "#FFFFFF", .12);
3830
+ const bandFill2 = mixHex(accent, "#FFFFFF", .27);
3750
3831
  const textColor = activeDeckTextColor;
3751
3832
  const tableThemeFace = getPresentationFonts(pres)?.minorLatin ?? null;
3752
3833
  const out = [];
@@ -3772,8 +3853,8 @@ const renderTable = (shape, pres, x, y, w, h, transform, theme, ctx) => {
3772
3853
  else if (flags.lastRow && r === dims.rows - 1) resolvedFill = headerFill;
3773
3854
  else if (flags.firstCol && c === 0) resolvedFill = bandFill;
3774
3855
  else if (flags.lastCol && c === dims.cols - 1) resolvedFill = bandFill;
3775
- else if (flags.bandRow && r % 2 === (flags.firstRow ? 0 : 1)) resolvedFill = bandFill;
3776
- else if (flags.bandCol && c % 2 === (flags.firstCol ? 0 : 1)) resolvedFill = bandFill;
3856
+ else if (flags.bandRow) resolvedFill = (r - (flags.firstRow ? 1 : 0)) % 2 === 0 ? bandFill : bandFill2;
3857
+ else if (flags.bandCol) resolvedFill = (c - (flags.firstCol ? 1 : 0)) % 2 === 0 ? bandFill : bandFill2;
3777
3858
  else resolvedFill = "none";
3778
3859
  const cellTextColor = resolvedFill === headerFill ? "#FFFFFF" : textColor;
3779
3860
  out.push(`<rect x="${px(cx)}" y="${px(cy)}" width="${px(cw)}" height="${px(ch)}" fill="${resolvedFill}"/>`);
@@ -3956,7 +4037,8 @@ const renderShape = (shape, pres, theme, ctx) => {
3956
4037
  if (flip.horizontal) transforms.push(`translate(${E(2 * cx)} 0) scale(-1 1)`);
3957
4038
  if (flip.vertical) transforms.push(`translate(0 ${E(2 * cy)}) scale(1 -1)`);
3958
4039
  const transform = transforms.length > 0 ? ` transform="${transforms.join(" ")}"` : "";
3959
- const textTransform = rotation !== 0 ? ` transform="rotate(${rotation} ${E(cx)} ${E(cy)})"` : "";
4040
+ const textRotation = (flip.vertical ? rotation + 180 : rotation) % 360;
4041
+ const textTransform = textRotation !== 0 ? ` transform="rotate(${textRotation} ${E(cx)} ${E(cy)})"` : "";
3960
4042
  const textOverlay = kind === "shape" || kind === "graphicFrame" ? renderTextBody(pres, shape, {
3961
4043
  x,
3962
4044
  y,
@@ -3980,13 +4062,14 @@ const renderShape = (shape, pres, theme, ctx) => {
3980
4062
  y1 = y + h;
3981
4063
  y2 = y;
3982
4064
  }
4065
+ const connectorTransform = rotation !== 0 ? ` transform="rotate(${rotation} ${E(cx)} ${E(cy)})"` : "";
3983
4066
  const strokeColor = p.stroke === "none" ? resolveColor("scheme:tx1", theme, "#1F2937") : p.stroke;
3984
4067
  const sa = p.strokeAttrs ? ` ${p.strokeAttrs}` : "";
3985
4068
  const ma = p.markerAttrs ?? "";
3986
4069
  const capDefault = sa.includes("stroke-linecap") ? "" : " stroke-linecap=\"round\"";
3987
4070
  const joinDefault = sa.includes("stroke-linejoin") ? "" : " stroke-linejoin=\"round\"";
3988
4071
  const preset = getShapePreset(shape) ?? "line";
3989
- if (preset === "straightConnector1" || preset === "line") return `${p.defs}<line x1="${E(x1)}" y1="${E(y1)}" x2="${E(x2)}" y2="${E(y2)}" stroke="${strokeColor}" stroke-width="${E(sw)}"${capDefault}${sa}${ma}${transform}/>`;
4072
+ if (preset === "straightConnector1" || preset === "line") return `${p.defs}<line x1="${E(x1)}" y1="${E(y1)}" x2="${E(x2)}" y2="${E(y2)}" stroke="${strokeColor}" stroke-width="${E(sw)}"${capDefault}${sa}${ma}${connectorTransform}/>`;
3990
4073
  const px1 = x1 / EMU_PER_PX;
3991
4074
  const py1 = y1 / EMU_PER_PX;
3992
4075
  const px2 = x2 / EMU_PER_PX;
@@ -4011,7 +4094,7 @@ const renderShape = (shape, pres, theme, ctx) => {
4011
4094
  const c2x = px1 + 2 * (px2 - px1) / 3;
4012
4095
  d += ` C${c1x.toFixed(2)} ${py1.toFixed(2)} ${c2x.toFixed(2)} ${py2.toFixed(2)} ${px2.toFixed(2)} ${py2.toFixed(2)}`;
4013
4096
  } else d += ` L${px2.toFixed(2)} ${py2.toFixed(2)}`;
4014
- return `${p.defs}<path d="${d}" fill="none" stroke="${strokeColor}" stroke-width="${E(sw)}"${capDefault}${joinDefault}${sa}${ma}${transform}/>`;
4097
+ return `${p.defs}<path d="${d}" fill="none" stroke="${strokeColor}" stroke-width="${E(sw)}"${capDefault}${joinDefault}${sa}${ma}${connectorTransform}/>`;
4015
4098
  }
4016
4099
  if (kind === "group") {
4017
4100
  const xform = getGroupTransform(shape);
@@ -4340,4 +4423,4 @@ const detectImageFormatLocal = (bytes) => {
4340
4423
  //#endregion
4341
4424
  export { SERIF as a, substituteFamily as c, SANS as i, ARIAL as n, TIMES as o, MONO as r, defaultMeasurer as s, renderSlideSvg as t };
4342
4425
 
4343
- //# sourceMappingURL=src-DDyW3xOV.js.map
4426
+ //# sourceMappingURL=src-Q2z_XgT6.js.map