create-slide-deck 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/dist/index.js +119 -0
  2. package/package.json +36 -0
  3. package/template-full/README.md +99 -0
  4. package/template-full/package.json +47 -0
  5. package/template-full/src/reveal/components/auto-layout.ts +229 -0
  6. package/template-full/src/reveal/components/charts.tsx +213 -0
  7. package/template-full/src/reveal/core/blocks.ts +172 -0
  8. package/template-full/src/reveal/core/deck-init.ts +60 -0
  9. package/template-full/src/reveal/core/design.ts +46 -0
  10. package/template-full/src/reveal/core/layout.ts +187 -0
  11. package/template-full/src/reveal/core/mount-registry.ts +41 -0
  12. package/template-full/src/reveal/core/presets.ts +189 -0
  13. package/template-full/src/reveal/core/runtime.ts +141 -0
  14. package/template-full/src/reveal/core/types.ts +114 -0
  15. package/template-full/src/reveal/data/algorithms.ts +78 -0
  16. package/template-full/src/reveal/data/benchmark.ts +79 -0
  17. package/template-full/src/reveal/decks/demo-showcase/components/demo-arc-progress.tsx +153 -0
  18. package/template-full/src/reveal/decks/demo-showcase/components/demo-before-after.tsx +164 -0
  19. package/template-full/src/reveal/decks/demo-showcase/components/demo-bigtext.tsx +70 -0
  20. package/template-full/src/reveal/decks/demo-showcase/components/demo-card-flip.tsx +118 -0
  21. package/template-full/src/reveal/decks/demo-showcase/components/demo-chat-bubbles.tsx +257 -0
  22. package/template-full/src/reveal/decks/demo-showcase/components/demo-code.tsx +136 -0
  23. package/template-full/src/reveal/decks/demo-showcase/components/demo-concept-map.tsx +336 -0
  24. package/template-full/src/reveal/decks/demo-showcase/components/demo-counter.tsx +194 -0
  25. package/template-full/src/reveal/decks/demo-showcase/components/demo-cover.tsx +188 -0
  26. package/template-full/src/reveal/decks/demo-showcase/components/demo-dark-dashboard.tsx +166 -0
  27. package/template-full/src/reveal/decks/demo-showcase/components/demo-eval-matrix.tsx +191 -0
  28. package/template-full/src/reveal/decks/demo-showcase/components/demo-force-graph.tsx +169 -0
  29. package/template-full/src/reveal/decks/demo-showcase/components/demo-fullbleed-bars.tsx +109 -0
  30. package/template-full/src/reveal/decks/demo-showcase/components/demo-fullbleed-flow.tsx +177 -0
  31. package/template-full/src/reveal/decks/demo-showcase/components/demo-heatmap.tsx +135 -0
  32. package/template-full/src/reveal/decks/demo-showcase/components/demo-icon-wall.tsx +143 -0
  33. package/template-full/src/reveal/decks/demo-showcase/components/demo-math.tsx +103 -0
  34. package/template-full/src/reveal/decks/demo-showcase/components/demo-number-morph.tsx +126 -0
  35. package/template-full/src/reveal/decks/demo-showcase/components/demo-path.tsx +185 -0
  36. package/template-full/src/reveal/decks/demo-showcase/components/demo-radar.tsx +124 -0
  37. package/template-full/src/reveal/decks/demo-showcase/components/demo-rough.tsx +169 -0
  38. package/template-full/src/reveal/decks/demo-showcase/components/demo-sankey.tsx +144 -0
  39. package/template-full/src/reveal/decks/demo-showcase/components/demo-screenshot-annotate.tsx +181 -0
  40. package/template-full/src/reveal/decks/demo-showcase/components/demo-stacked-cards.tsx +159 -0
  41. package/template-full/src/reveal/decks/demo-showcase/components/demo-tabs.tsx +206 -0
  42. package/template-full/src/reveal/decks/demo-showcase/components/demo-timeline.tsx +162 -0
  43. package/template-full/src/reveal/decks/demo-showcase/components/demo-treemap.tsx +161 -0
  44. package/template-full/src/reveal/decks/demo-showcase/components/demo-zoom-focus.tsx +223 -0
  45. package/template-full/src/reveal/decks/demo-showcase/components/registry.ts +63 -0
  46. package/template-full/src/reveal/decks/demo-showcase/demo.css +237 -0
  47. package/template-full/src/reveal/decks/demo-showcase/index.html +24 -0
  48. package/template-full/src/reveal/decks/demo-showcase/main.ts +7 -0
  49. package/template-full/src/reveal/decks/demo-showcase/slides.ts +271 -0
  50. package/template-full/src/reveal/decks/fse26-rca/components/aws-cascade.tsx +295 -0
  51. package/template-full/src/reveal/decks/fse26-rca/components/bench-compare.tsx +64 -0
  52. package/template-full/src/reveal/decks/fse26-rca/components/bench-deficiency.tsx +104 -0
  53. package/template-full/src/reveal/decks/fse26-rca/components/bench-loop.tsx +402 -0
  54. package/template-full/src/reveal/decks/fse26-rca/components/bench-needs.tsx +78 -0
  55. package/template-full/src/reveal/decks/fse26-rca/components/closing-takeaway.tsx +165 -0
  56. package/template-full/src/reveal/decks/fse26-rca/components/cloud-incidents.tsx +88 -0
  57. package/template-full/src/reveal/decks/fse26-rca/components/failure-modes.tsx +59 -0
  58. package/template-full/src/reveal/decks/fse26-rca/components/fault-heatmap.tsx +85 -0
  59. package/template-full/src/reveal/decks/fse26-rca/components/hierarchy-tree.tsx +93 -0
  60. package/template-full/src/reveal/decks/fse26-rca/components/incident-hard.tsx +72 -0
  61. package/template-full/src/reveal/decks/fse26-rca/components/rca-pipeline.tsx +193 -0
  62. package/template-full/src/reveal/decks/fse26-rca/components/registry.ts +37 -0
  63. package/template-full/src/reveal/decks/fse26-rca/components/simple-rca.tsx +216 -0
  64. package/template-full/src/reveal/decks/fse26-rca/components/sota-collapse.tsx +63 -0
  65. package/template-full/src/reveal/decks/fse26-rca/components/srca-results.tsx +115 -0
  66. package/template-full/src/reveal/decks/fse26-rca/images/aws-outage-2025-deployflow.png +0 -0
  67. package/template-full/src/reveal/decks/fse26-rca/images/aws-post-event-summary.png +0 -0
  68. package/template-full/src/reveal/decks/fse26-rca/images/bbc-crowdstrike.png +0 -0
  69. package/template-full/src/reveal/decks/fse26-rca/images/cnn-meta-outage-2021.png +0 -0
  70. package/template-full/src/reveal/decks/fse26-rca/images/cover.png +0 -0
  71. package/template-full/src/reveal/decks/fse26-rca/images/nyt-facebook-2021.png +0 -0
  72. package/template-full/src/reveal/decks/fse26-rca/images/qr-repo.png +0 -0
  73. package/template-full/src/reveal/decks/fse26-rca/images/verge-crowdstrike-2024.png +0 -0
  74. package/template-full/src/reveal/decks/fse26-rca/images/wiki-meta-outage-2021.png +0 -0
  75. package/template-full/src/reveal/decks/fse26-rca/index.html +30 -0
  76. package/template-full/src/reveal/decks/fse26-rca/main.ts +8 -0
  77. package/template-full/src/reveal/decks/fse26-rca/slides.ts +175 -0
  78. package/template-full/src/reveal/env.d.ts +38 -0
  79. package/template-full/src/reveal/theme.css +762 -0
  80. package/template-full/src/reveal/tools/dev.mjs +120 -0
  81. package/template-full/src/reveal/tools/export-pdf.mjs +86 -0
  82. package/template-full/src/reveal/tools/preview.mjs +132 -0
  83. package/template-full/tsconfig.json +19 -0
  84. package/template-full/vite.config.ts +95 -0
  85. package/template-minimal/package.json +42 -0
  86. package/template-minimal/src/reveal/components/auto-layout.ts +229 -0
  87. package/template-minimal/src/reveal/components/charts.tsx +213 -0
  88. package/template-minimal/src/reveal/core/blocks.ts +172 -0
  89. package/template-minimal/src/reveal/core/deck-init.ts +60 -0
  90. package/template-minimal/src/reveal/core/design.ts +46 -0
  91. package/template-minimal/src/reveal/core/layout.ts +187 -0
  92. package/template-minimal/src/reveal/core/mount-registry.ts +41 -0
  93. package/template-minimal/src/reveal/core/presets.ts +189 -0
  94. package/template-minimal/src/reveal/core/runtime.ts +141 -0
  95. package/template-minimal/src/reveal/core/types.ts +114 -0
  96. package/template-minimal/src/reveal/data/.gitkeep +0 -0
  97. package/template-minimal/src/reveal/decks/my-deck/components/example-component.tsx +28 -0
  98. package/template-minimal/src/reveal/decks/my-deck/components/registry.ts +9 -0
  99. package/template-minimal/src/reveal/decks/my-deck/index.html +14 -0
  100. package/template-minimal/src/reveal/decks/my-deck/main.ts +5 -0
  101. package/template-minimal/src/reveal/decks/my-deck/slides.ts +34 -0
  102. package/template-minimal/src/reveal/env.d.ts +38 -0
  103. package/template-minimal/src/reveal/theme.css +762 -0
  104. package/template-minimal/tsconfig.json +19 -0
  105. package/template-minimal/vite.config.ts +95 -0
@@ -0,0 +1,165 @@
1
+ import React from "react";
2
+ import type { SlideComponentProps } from "../../../core/types.ts";
3
+ import { CANVAS, MIN_FONT, SlideCanvas, vis } from "../../../core/presets.ts";
4
+
5
+ const W = 1200, H = 560;
6
+ const COL_W = W / 3;
7
+ const ICON_R = 40;
8
+ const ICON_Y = 60;
9
+ const TITLE_Y = ICON_Y + ICON_R + 28;
10
+ const CONTENT_Y = TITLE_Y + 30;
11
+ const BAR_MAX = 240;
12
+
13
+ export default function ClosingTakeaway({ Reveal }: SlideComponentProps) {
14
+ return (
15
+ <SlideCanvas Reveal={Reveal} W={W} H={H}>{(step, instant) => <>
16
+
17
+ {/* === Section 1: Benchmark shapes research === */}
18
+ <g style={vis(step, 0, instant)}>
19
+ {/* Icon circle with compass arrow */}
20
+ <circle cx={COL_W * 0.5} cy={ICON_Y} r={ICON_R} fill="#C00000" fillOpacity={0.08} stroke="#C00000" strokeWidth={2.5} />
21
+ <path d="M-12,-6 L12,0 L-12,6 L-6,0 Z" transform={"translate(" + (COL_W * 0.5) + "," + ICON_Y + ")"} fill="#C00000" />
22
+
23
+ {/* Title */}
24
+ <text x={COL_W * 0.5} y={TITLE_Y} textAnchor="middle" fontSize={18} fontWeight={900} fill="#313131" fontFamily={CANVAS.fontFamily}>
25
+ Benchmark shapes research
26
+ </text>
27
+
28
+ {/* Mini rank comparison */}
29
+ {(function () {
30
+ const cx = COL_W * 0.5;
31
+ const bx = cx - 120;
32
+ const by = CONTENT_Y + 20;
33
+ const barH = 18;
34
+ const gap = 36;
35
+
36
+ return (
37
+ <g>
38
+ {/* Old benchmarks label */}
39
+ <text x={cx} y={CONTENT_Y} textAnchor="middle" fontSize={MIN_FONT} fontWeight={800} fill="#C00000" fontFamily={CANVAS.fontFamily}>Old benchmarks</text>
40
+ {/* SimpleRCA bar */}
41
+ <rect x={bx} y={by} width={BAR_MAX * 0.85} height={barH} rx={4} fill="#C00000" fillOpacity={0.15} stroke="#C00000" strokeWidth={1.5} />
42
+ <text x={bx + 8} y={by + 13} fontSize={12} fontWeight={800} fill="#C00000" fontFamily={CANVAS.fontFamily}>SimpleRCA</text>
43
+ {/* SOTA bar (similar length) */}
44
+ <rect x={bx} y={by + barH + 4} width={BAR_MAX * 0.88} height={barH} rx={4} fill="#767676" fillOpacity={0.12} stroke="#999" strokeWidth={1} />
45
+ <text x={bx + 8} y={by + barH + 17} fontSize={12} fontWeight={700} fill="#767676" fontFamily={CANVAS.fontFamily}>SOTA best</text>
46
+ {/* Approx equal */}
47
+ <text x={bx + BAR_MAX + 14} y={by + barH + 4} textAnchor="middle" fontSize={20} fontWeight={900} fill="#C00000" fontFamily={CANVAS.fontFamily}>≈</text>
48
+
49
+ {/* New benchmark label */}
50
+ <text x={cx} y={by + gap + barH + 20} textAnchor="middle" fontSize={MIN_FONT} fontWeight={800} fill="#76B82A" fontFamily={CANVAS.fontFamily}>New benchmark</text>
51
+ {/* SOTA bar (longer) */}
52
+ <rect x={bx} y={by + gap + barH + 30} width={BAR_MAX * 0.92} height={barH} rx={4} fill="#76B82A" fillOpacity={0.15} stroke="#76B82A" strokeWidth={1.5} />
53
+ <text x={bx + 8} y={by + gap + barH + 43} fontSize={12} fontWeight={800} fill="#76B82A" fontFamily={CANVAS.fontFamily}>MicroRCA</text>
54
+ <text x={bx + BAR_MAX * 0.92 + 8} y={by + gap + barH + 43} fontSize={14} fontWeight={900} fill="#76B82A" fontFamily={CANVAS.fontFamily}>0.37</text>
55
+ {/* SimpleRCA bar (shorter) */}
56
+ <rect x={bx} y={by + gap + barH + 52} width={BAR_MAX * 0.70} height={barH} rx={4} fill="#C00000" fillOpacity={0.15} stroke="#C00000" strokeWidth={1.5} />
57
+ <text x={bx + 8} y={by + gap + barH + 65} fontSize={12} fontWeight={800} fill="#C00000" fontFamily={CANVAS.fontFamily}>SimpleRCA</text>
58
+ <text x={bx + BAR_MAX * 0.70 + 8} y={by + gap + barH + 65} fontSize={14} fontWeight={900} fill="#C00000" fontFamily={CANVAS.fontFamily}>0.28</text>
59
+ {/* empty */}
60
+ </g>
61
+ );
62
+ })()}
63
+
64
+ {/* Caption */}
65
+ <text x={COL_W * 0.5} y={CONTENT_Y + 200} textAnchor="middle" fontSize={MIN_FONT} fill="#767676" fontFamily={CANVAS.fontFamily}>
66
+ 7/11 datasets shortcutted
67
+ </text>
68
+ </g>
69
+
70
+ {/* === Section 2: Three orthogonal bottlenecks === */}
71
+ <g style={vis(step, 1, instant)}>
72
+ {/* Icon circle with three split bars */}
73
+ <circle cx={COL_W * 1.5} cy={ICON_Y} r={ICON_R} fill="#00A6D6" fillOpacity={0.08} stroke="#00A6D6" strokeWidth={2.5} />
74
+ <rect x={COL_W * 1.5 - 14} y={ICON_Y - 14} width={28} height={6} rx={2} fill="#E8912D" />
75
+ <rect x={COL_W * 1.5 - 14} y={ICON_Y - 3} width={22} height={6} rx={2} fill="#00A6D6" />
76
+ <rect x={COL_W * 1.5 - 14} y={ICON_Y + 8} width={12} height={6} rx={2} fill="#7B61FF" />
77
+
78
+ {/* Title */}
79
+ <text x={COL_W * 1.5} y={TITLE_Y} textAnchor="middle" fontSize={18} fontWeight={900} fill="#313131" fontFamily={CANVAS.fontFamily}>
80
+ Three orthogonal bottlenecks
81
+ </text>
82
+
83
+ {/* Three horizontal bars with stats */}
84
+ {(function () {
85
+ const cx = COL_W * 1.5;
86
+ const bx = cx - 140;
87
+ const items = [
88
+ { pct: 47.4, label: "Modeling", desc: "wrong graph assumptions", color: "#E8912D" },
89
+ { pct: 39.8, label: "Scalability", desc: "CausalRCA: 927s/case", color: "#00A6D6" },
90
+ { pct: 12.8, label: "Observability", desc: "signal + infra gaps", color: "#7B61FF" },
91
+ ];
92
+ const maxPct = 50;
93
+ const barFullW = 180;
94
+
95
+ return items.map(function (item, i) {
96
+ const y = CONTENT_Y + 14 + i * 62;
97
+ const barW = (item.pct / maxPct) * barFullW;
98
+ return (
99
+ <g key={i}>
100
+ <text x={bx} y={y} fontSize={28} fontWeight={900} fill={item.color} fontFamily={CANVAS.fontFamily}>
101
+ {item.pct + "%"}
102
+ </text>
103
+ <text x={bx + 90} y={y - 6} fontSize={16} fontWeight={800} fill="#313131" fontFamily={CANVAS.fontFamily}>
104
+ {item.label}
105
+ </text>
106
+ <text x={bx + 90} y={y + 12} fontSize={13} fill="#767676" fontFamily={CANVAS.fontFamily}>
107
+ {item.desc}
108
+ </text>
109
+ <rect x={bx} y={y + 18} width={barFullW + 100} height={4} rx={2} fill="#eee" />
110
+ <rect x={bx} y={y + 18} width={barW + 100 * (item.pct / maxPct)} height={4} rx={2} fill={item.color} fillOpacity={0.6} />
111
+ </g>
112
+ );
113
+ });
114
+ })()}
115
+ </g>
116
+
117
+ {/* === Section 3: Open benchmark & tools === */}
118
+ <g style={vis(step, 2, instant)}>
119
+ {/* Icon circle with globe shape */}
120
+ <circle cx={COL_W * 2.5} cy={ICON_Y} r={ICON_R} fill="#76B82A" fillOpacity={0.08} stroke="#76B82A" strokeWidth={2.5} />
121
+ <circle cx={COL_W * 2.5} cy={ICON_Y} r={14} fill="none" stroke="#76B82A" strokeWidth={2} />
122
+ <ellipse cx={COL_W * 2.5} cy={ICON_Y} rx={7} ry={14} fill="none" stroke="#76B82A" strokeWidth={1.5} />
123
+ <line x1={COL_W * 2.5 - 14} y1={ICON_Y} x2={COL_W * 2.5 + 14} y2={ICON_Y} stroke="#76B82A" strokeWidth={1.5} />
124
+
125
+ {/* Title */}
126
+ <text x={COL_W * 2.5} y={TITLE_Y} textAnchor="middle" fontSize={18} fontWeight={900} fill="#313131" fontFamily={CANVAS.fontFamily}>
127
+ Open benchmark & tools
128
+ </text>
129
+
130
+ {/* Large stat numbers */}
131
+ {(function () {
132
+ const cx = COL_W * 2.5;
133
+ const stats = [
134
+ { val: "1,430", label: "validated cases" },
135
+ { val: "25", label: "fault types" },
136
+ { val: "12", label: "algorithms evaluated" },
137
+ ];
138
+ return stats.map(function (s, i) {
139
+ const y = CONTENT_Y + 20 + i * 62;
140
+ return (
141
+ <g key={i}>
142
+ <text x={cx - 50} y={y} textAnchor="end" fontSize={36} fontWeight={900} fill="#76B82A" fontFamily={CANVAS.fontFamily}>{s.val}</text>
143
+ <text x={cx - 38} y={y} fontSize={16} fontWeight={700} fill="#555" fontFamily={CANVAS.fontFamily}>{s.label}</text>
144
+ </g>
145
+ );
146
+ });
147
+ })()}
148
+
149
+ {/* QR code */}
150
+ <image href="images/qr-repo.png" x={COL_W * 2.5 - 50} y={CONTENT_Y + 190} width={100} height={100} />
151
+ <text x={COL_W * 2.5} y={CONTENT_Y + 304} textAnchor="middle" fontSize={11} fontWeight={700} fill="#767676" fontFamily={CANVAS.fontFamily}>
152
+ operationspai.github.io/revisiting-rca-evaluation
153
+ </text>
154
+ </g>
155
+
156
+ {/* === Final takeaway banner === */}
157
+ <g style={vis(step, 3, instant)}>
158
+ <rect x={(W - 700) / 2} y={H - 70} width={700} height={50} rx={8} fill="#C00000" fillOpacity={0.06} stroke="#C00000" strokeWidth={2} />
159
+ <text x={W / 2} y={H - 39} textAnchor="middle" fontSize={20} fontWeight={900} fill="#C00000" fontFamily={CANVAS.fontFamily}>
160
+ Do not optimize for an easy benchmark
161
+ </text>
162
+ </g>
163
+ </>}</SlideCanvas>
164
+ );
165
+ }
@@ -0,0 +1,88 @@
1
+ import React from "react";
2
+ import type { SlideComponentProps } from "../../../core/types.ts";
3
+ import { CANVAS, useRevealStep, vis } from "../../../core/presets.ts";
4
+
5
+ const IMG_CSS: React.CSSProperties = {
6
+ borderRadius: 8,
7
+ boxShadow: "0 4px 16px rgba(49,49,49,0.10)",
8
+ overflow: "hidden",
9
+ width: 380,
10
+ height: 340,
11
+ objectFit: "contain",
12
+ objectPosition: "top center",
13
+ };
14
+
15
+ const CARDS = [
16
+ {
17
+ x: 48,
18
+ src: "images/verge-crowdstrike-2024.png",
19
+ alt: "CrowdStrike outage",
20
+ title: "2024.07 · CrowdStrike",
21
+ sub: "~$5.4B Fortune 500 losses",
22
+ },
23
+ {
24
+ x: 450,
25
+ src: "images/aws-outage-2025-deployflow.png",
26
+ alt: "AWS Outage October 2025",
27
+ title: "2025.10 · AWS US-EAST-1",
28
+ sub: ">$1.1B · 15h outage · 1000+ companies",
29
+ },
30
+ {
31
+ x: 852,
32
+ src: "images/wiki-meta-outage-2021.png",
33
+ alt: "Wikipedia: 2021 Facebook outage",
34
+ title: "2021.10 · Meta",
35
+ sub: "~$100M ad revenue · 6h · 3.5B users",
36
+ },
37
+ ];
38
+
39
+ export default function CloudIncidents({ Reveal }: SlideComponentProps) {
40
+ const ref = useRevealStep(Reveal);
41
+ const step = ref[0], ready = ref[1], instant = ref[2];
42
+
43
+ return (
44
+ <div
45
+ style={{
46
+ opacity: ready ? 1 : 0,
47
+ transition: instant ? "none" : "opacity 0.2s ease",
48
+ width: "100%",
49
+ height: "100%",
50
+ position: "relative",
51
+ fontFamily: CANVAS.fontFamily,
52
+ }}
53
+ >
54
+ {CARDS.map(function (c) {
55
+ return (
56
+ <div key={c.x} style={{ position: "absolute", left: c.x, top: 66, width: 380 }}>
57
+ <img src={c.src} alt={c.alt} style={IMG_CSS} />
58
+ <div className="img-caption" style={{ marginTop: 10 }}>
59
+ <strong>{c.title}</strong>
60
+ <span>{c.sub}</span>
61
+ </div>
62
+ </div>
63
+ );
64
+ })}
65
+
66
+ <div
67
+ className="blur-banner-wrap"
68
+ style={{
69
+ position: "absolute",
70
+ left: 0,
71
+ top: 50,
72
+ width: "100%",
73
+ height: 480,
74
+ ...vis(step, 0, instant),
75
+ }}
76
+ >
77
+ <div className="blur-banner">
78
+ <div className="blur-banner-line">
79
+ These outages cost <strong>billions</strong>
80
+ </div>
81
+ <div className="blur-banner-sub">
82
+ every one of them is an <strong>RCA</strong> problem
83
+ </div>
84
+ </div>
85
+ </div>
86
+ </div>
87
+ );
88
+ }
@@ -0,0 +1,59 @@
1
+ import React from "react";
2
+ import type { SlideComponentProps } from "../../../core/types.ts";
3
+ import { CANVAS, SlideCanvas, vis } from "../../../core/presets.ts";
4
+ import { FAILURE_MODES } from "../../../data/benchmark.ts";
5
+
6
+ const BARS = FAILURE_MODES.bars;
7
+ const DESCS = FAILURE_MODES.descs;
8
+
9
+ const SVG_W = 1000;
10
+ const SVG_H = 420;
11
+ const CHART_LEFT = 300;
12
+ const CHART_TOP = 40;
13
+ const CHART_W = 560;
14
+ const BAR_H = 34;
15
+ const BAR_GAP = 18;
16
+ const MAX_PCT = 50;
17
+
18
+ function barW(pct: number) { return (pct / MAX_PCT) * CHART_W; }
19
+
20
+ export default function FailureModes({ Reveal }: SlideComponentProps) {
21
+ function barY(i: number) { return CHART_TOP + i * (BAR_H + BAR_GAP); }
22
+ const chartBottom = barY(BARS.length - 1) + BAR_H;
23
+
24
+ return (
25
+ <SlideCanvas Reveal={Reveal} W={SVG_W} H={SVG_H}>{(step, instant) => <>
26
+
27
+ {BARS.map(function (b, i) {
28
+ const y = barY(i);
29
+ const w = barW(b.pct);
30
+ return (
31
+ <g key={b.key} style={vis(step, b.reveal, instant)}>
32
+ <text x={CHART_LEFT - 16} y={y + BAR_H / 2 + 5} textAnchor="end" fontSize="15" fontWeight="800" fill="#313131" fontFamily={CANVAS.fontFamily}>{b.label}</text>
33
+ <rect x={CHART_LEFT} y={y} width={CHART_W} height={BAR_H} rx="6" fill="#F2F2F2" />
34
+ <rect x={CHART_LEFT} y={y} width={w} height={BAR_H} rx="6" fill={b.color} />
35
+ <text x={CHART_LEFT + w + 12} y={y + BAR_H / 2 + 6} fontSize="17" fontWeight="900" fill={b.color} fontFamily={CANVAS.fontFamily}>{b.pct.toFixed(1)}%</text>
36
+ </g>
37
+ );
38
+ })}
39
+
40
+ {DESCS.map(function (d, i) {
41
+ return (
42
+ <g key={i} style={{ opacity: step === d.reveal ? 1 : 0, transition: instant ? "none" : "opacity 0.35s ease" }}>
43
+ <rect x={CHART_LEFT} y={chartBottom + 24} width={CHART_W} height="54" rx="8" fill="#fff" stroke={d.color} strokeWidth="2" />
44
+ <rect x={CHART_LEFT} y={chartBottom + 24} width="6" height="54" rx="3" fill={d.color} />
45
+ <text x={CHART_LEFT + 22} y={chartBottom + 46} fontSize="16" fontWeight="900" fill={d.color} fontFamily={CANVAS.fontFamily}>{d.title}</text>
46
+ <text x={CHART_LEFT + 22} y={chartBottom + 68} fontSize="14" fontWeight="700" fill="#767676" fontFamily={CANVAS.fontFamily}>{d.text}</text>
47
+ </g>
48
+ );
49
+ })}
50
+
51
+ <g style={vis(step, 3, instant)}>
52
+ <text x={SVG_W / 2} y={chartBottom + 50} textAnchor="middle" fontSize="20" fontWeight="900" fill="#313131" fontFamily={CANVAS.fontFamily}>
53
+ <tspan fill="#C00000">262 hardest cases analyzed</tspan>
54
+ <tspan fill="#767676" fontWeight="800"> — three orthogonal bottlenecks</tspan>
55
+ </text>
56
+ </g>
57
+ </>}</SlideCanvas>
58
+ );
59
+ }
@@ -0,0 +1,85 @@
1
+ import React from "react";
2
+ import type { SlideComponentProps } from "../../../core/types.ts";
3
+ import { CANVAS, SlideCanvas, vis } from "../../../core/presets.ts";
4
+ import { HEATMAP_ALGOS as ALGOS, HEATMAP_GROUPS as GROUPS } from "../../../data/algorithms.ts";
5
+
6
+ const SVG_W = 1400;
7
+ const SVG_H = 540;
8
+ const LABEL_W = 200;
9
+ const GROUP_W = 50;
10
+ const COL_GAP_TOP = 56;
11
+ const GRID_TOP = 50;
12
+ const GRID_LEFT = LABEL_W;
13
+ const ROW_H = 17;
14
+ const MAX_R = 7;
15
+
16
+ function colColor(v: number) {
17
+ if (v <= 0) return "#C9C9C9";
18
+ if (v >= 0.65) return "#76B82A";
19
+ if (v >= 0.35) return "#E8912D";
20
+ return "#C00000";
21
+ }
22
+
23
+ export default function FaultHeatmap({ Reveal }: SlideComponentProps) {
24
+ const colW = (SVG_W - GRID_LEFT - 20) / ALGOS.length;
25
+ function colX(i: number) { return GRID_LEFT + colW * (i + 0.5); }
26
+
27
+ const rowY: any[] = [];
28
+ const groupSpans: any[] = [];
29
+ let y = GRID_TOP + 6;
30
+ GROUPS.forEach(function (g) {
31
+ const startY = y;
32
+ g.rows.forEach(function (r) {
33
+ rowY.push({ y: y, group: g, row: r });
34
+ y += ROW_H;
35
+ });
36
+ groupSpans.push({ group: g, y0: startY, y1: y });
37
+ y += 24;
38
+ });
39
+
40
+ return (
41
+ <SlideCanvas Reveal={Reveal} W={SVG_W} H={y + 50}>{(step, instant) => <>
42
+
43
+ {ALGOS.map(function (a, i) {
44
+ return (
45
+ <text key={a} x={colX(i)} y={GRID_TOP - 10} textAnchor="middle" fontSize="14" fontWeight="800" fill="#313131" fontFamily={CANVAS.fontFamily}>{a}</text>
46
+ );
47
+ })}
48
+
49
+ {groupSpans.map(function (gs, gi) {
50
+ const g = gs.group;
51
+ return (
52
+ <g key={gi} style={vis(step, g.step, instant)}>
53
+ <rect x={GRID_LEFT - 4} y={gs.y0} width={SVG_W - GRID_LEFT - 14} height={gs.y1 - gs.y0 + 4} rx="6" fill={g.color} fillOpacity="0.06" />
54
+ <rect x="14" y={gs.y0} width="6" height={gs.y1 - gs.y0 + 4} rx="3" fill={g.color} />
55
+ <text x="14" y={gs.y0 - 6} fontSize="14" fontWeight="900" fill={g.color} fontFamily={CANVAS.fontFamily}>{g.name}</text>
56
+ </g>
57
+ );
58
+ })}
59
+
60
+ {rowY.map(function (rc, ri) {
61
+ const g = rc.group, r = rc.row, ry = rc.y;
62
+ return (
63
+ <g key={ri} style={vis(step, g.step, instant)}>
64
+ <text x={GRID_LEFT - 14} y={ry + 17} textAnchor="end" fontSize="14" fontWeight="700" fill="#313131" fontFamily={CANVAS.fontFamily}>{r.fault}</text>
65
+ {r.mrr.map(function (v: number, ci: number) {
66
+ const rad = v <= 0 ? 3 : 4 + v * (MAX_R - 4);
67
+ return (
68
+ <g key={ci}>
69
+ <circle cx={colX(ci)} cy={ry + 13} r={rad} fill={colColor(v)} fillOpacity={v <= 0 ? 0.5 : 0.9} />
70
+ </g>
71
+ );
72
+ })}
73
+ </g>
74
+ );
75
+ })}
76
+
77
+ <g style={vis(step, 6, instant)}>
78
+ <text x={SVG_W / 2} y={y + 34} textAnchor="middle" fontSize="20" fontWeight="900" fill="#313131" fontFamily={CANVAS.fontFamily}>
79
+ <tspan fill="#C00000">No universal winner</tspan>
80
+ <tspan fill="#767676" fontWeight="800"> — performance depends on fault type</tspan>
81
+ </text>
82
+ </g>
83
+ </>}</SlideCanvas>
84
+ );
85
+ }
@@ -0,0 +1,93 @@
1
+ import React from "react";
2
+ import type { SlideComponentProps } from "../../../core/types.ts";
3
+ import { hierarchy, tree as d3tree } from "d3-hierarchy";
4
+ import { CANVAS, SlideCanvas, vis } from "../../../core/presets.ts";
5
+
6
+ const TREE_DATA = {
7
+ n: "ts-order-service", level: "Service", step: 0, color: "#1B556B",
8
+ children: [
9
+ { n: "ts-order-pod-1", level: "Pod", step: 1, color: "#76B82A",
10
+ children: [
11
+ { n: "order-container", level: "Container", step: 2, color: "#00A6D6",
12
+ children: [
13
+ { n: "cpu_usage: 98%", level: "Metric", step: 3, color: "#C00000" },
14
+ { n: "POST /api/order", level: "Span", step: 3, color: "#E8912D" },
15
+ { n: "createOrder()", level: "Function", step: 3, color: "#7B61FF" },
16
+ ]},
17
+ ]},
18
+ { n: "ts-order-pod-2", level: "Pod", step: 1, color: "#76B82A",
19
+ children: [
20
+ { n: "order-container", level: "Container", step: 2, color: "#00A6D6" },
21
+ ]},
22
+ ],
23
+ };
24
+
25
+ const W = 900, H = 360;
26
+ const root = hierarchy(TREE_DATA as any);
27
+ d3tree().size([H - 80, W - 220]).separation(function(a, b) {
28
+ return a.parent === b.parent ? 1.3 : 2.0;
29
+ })(root);
30
+
31
+ const allNodes = root.descendants();
32
+ const allLinks = root.links();
33
+
34
+ const LEVEL_COLORS = {
35
+ Service: "#1B556B",
36
+ Pod: "#76B82A",
37
+ Container: "#00A6D6",
38
+ Metric: "#C00000",
39
+ Span: "#E8912D",
40
+ Function: "#7B61FF",
41
+ };
42
+
43
+ const LEVEL_LABELS = ["Service", "Pod", "Container", "Metric / Span / Function"];
44
+
45
+ export default function HierarchyTree({ Reveal }: SlideComponentProps) {
46
+ return (
47
+ <SlideCanvas Reveal={Reveal} W={W} H={H}>{(step, instant) => <>
48
+
49
+ {allLinks.map(function(link, i) {
50
+ const tStep = (link.target.data as any).step;
51
+ return (
52
+ <path key={"e" + i}
53
+ d={"M" + (link.source.y! + 70) + "," + (link.source.x! + 30) +
54
+ " C" + ((link.source.y! + link.target.y!) / 2 + 70) + "," + (link.source.x! + 30) +
55
+ " " + ((link.source.y! + link.target.y!) / 2 + 70) + "," + (link.target.x! + 30) +
56
+ " " + (link.target.y! + 70) + "," + (link.target.x! + 30)}
57
+ fill="none" stroke="#ddd" strokeWidth="1.5"
58
+ style={vis(step, tStep, instant)} />
59
+ );
60
+ })}
61
+
62
+ {allNodes.map(function(nd, i) {
63
+ const d = nd.data as any;
64
+ const x = nd.y! + 70;
65
+ const y = nd.x! + 30;
66
+ const color = (LEVEL_COLORS as any)[d.level] || "#999";
67
+ const isService = d.level === "Service";
68
+ const w = isService ? 170 : d.level === "Pod" ? 150 : d.level === "Container" ? 150 : 150;
69
+ const h = 34;
70
+ const highlight = step === d.step;
71
+
72
+ return (
73
+ <g key={"n" + i} style={vis(step, d.step, instant)}>
74
+ <rect x={x - 4} y={y - h/2} width={w} height={h} rx="6"
75
+ fill="white" stroke={color}
76
+ strokeWidth={highlight ? 3 : 2}
77
+ strokeDasharray={d.level === "Metric" || d.level === "Span" || d.level === "Function" ? "5 3" : "none"} />
78
+ <text x={x + w/2 - 4} y={y + 1} textAnchor="middle" dominantBaseline="middle"
79
+ fontSize="15" fontWeight="800" fill={color} fontFamily={CANVAS.fontFamily}>{d.n}</text>
80
+ <text x={x - 16} y={y + 1} textAnchor="end" dominantBaseline="middle"
81
+ fontSize="14" fontWeight="700" fill="#bbb" fontFamily={CANVAS.fontFamily}>{d.level}</text>
82
+ </g>
83
+ );
84
+ })}
85
+
86
+ <g style={vis(step, 4, instant)}>
87
+ <text x={W / 2} y={H - 10} textAnchor="middle" fontSize="16" fontWeight="800" fill="#313131" fontFamily={CANVAS.fontFamily}>
88
+ Service-level comparison for fair cross-method evaluation
89
+ </text>
90
+ </g>
91
+ </>}</SlideCanvas>
92
+ );
93
+ }
@@ -0,0 +1,72 @@
1
+ import React from "react";
2
+ import type { SlideComponentProps } from "../../../core/types.ts";
3
+ import { CANVAS, MIN_FONT, SlideCanvas, vis } from "../../../core/presets.ts";
4
+
5
+ const W = 1200, H = 560;
6
+ const R = 42;
7
+
8
+ const C = { red: "#C00000", teal: "#00A6D6", label: "#313131", sub: "#767676" };
9
+
10
+ // Icon paths use a 24x24 viewBox, scaled and centered inside the circle.
11
+ function IconNode({ cx, cy, color, label, sub, children }: { cx: number; cy: number; color: string; label: string; sub: string; children: React.ReactNode }) {
12
+ const iconScale = (R * 1.45) / 24;
13
+ const tx = cx - 12 * iconScale;
14
+ const ty = cy - 12 * iconScale;
15
+ return (
16
+ <g>
17
+ <circle cx={cx} cy={cy} r={R} fill={color} fillOpacity={0.08} stroke={color} strokeWidth={4} />
18
+ <g transform={"translate(" + tx + "," + ty + ") scale(" + iconScale + ")"} stroke={color} color={color}>
19
+ {children}
20
+ </g>
21
+ <text x={cx} y={cy + R + 36} textAnchor="middle" fontSize={24} fontWeight={900} fill={C.label} fontFamily={CANVAS.fontFamily}>
22
+ {label}
23
+ </text>
24
+ <text x={cx} y={cy + R + 62} textAnchor="middle" fontSize={MIN_FONT} fontWeight={600} fill={C.sub} fontFamily={CANVAS.fontFamily}>
25
+ {sub}
26
+ </text>
27
+ </g>
28
+ );
29
+ }
30
+
31
+ export default function IncidentHard({ Reveal }: SlideComponentProps) {
32
+ return (
33
+ <SlideCanvas Reveal={Reveal} W={W} H={H}>{(step, instant) => <>
34
+
35
+ {/* Fault propagation node */}
36
+ <g style={vis(step, 0, instant)}>
37
+ <IconNode cx={W * 0.32} cy={150} color={C.red} label="Fault propagation" sub="cascades across service layers">
38
+ <circle cx="6" cy="19" r="2" fill="none" strokeWidth="2" />
39
+ <circle cx="18" cy="5" r="2" fill="none" strokeWidth="2" />
40
+ <path d="M6 17V7a5 5 0 0 1 5-5h1a5 5 0 0 1 5 5v10a5 5 0 0 0 5 5h1" fill="none" strokeWidth="2" strokeLinecap="round" />
41
+ </IconNode>
42
+ </g>
43
+
44
+ {/* Symptom misdirection node */}
45
+ <g style={vis(step, 1, instant)}>
46
+ <IconNode cx={W * 0.68} cy={150} color={C.teal} label="Symptom misdirection" sub="loudest signal ≠ root cause">
47
+ <path d="M2 2h5v5M22 2h-5v5M2 22h5v-5M22 22h-5v-5" fill="none" strokeWidth="2" strokeLinecap="round" />
48
+ <circle cx="12" cy="12" r="4" fill="none" strokeWidth="2" />
49
+ <line x1="15" y1="15" x2="20" y2="20" strokeWidth="2" strokeLinecap="round" />
50
+ </IconNode>
51
+ </g>
52
+
53
+ {/* Question */}
54
+ <g style={vis(step, 2, instant)}>
55
+ <text x={W / 2} y={370} textAnchor="middle" fontSize={34} fontWeight={900} fill={C.label} fontFamily={CANVAS.fontFamily}>
56
+ Do existing benchmarks
57
+ </text>
58
+ <text x={W / 2} y={414} textAnchor="middle" fontSize={34} fontWeight={900} fill={C.label} fontFamily={CANVAS.fontFamily}>
59
+ preserve these properties?
60
+ </text>
61
+ </g>
62
+
63
+ {/* Footer claim */}
64
+ <g style={vis(step, 3, instant)}>
65
+ <text x={W / 2} y={490} textAnchor="middle" fontSize={22} fontWeight={700} fill={C.sub} fontFamily={CANVAS.fontFamily}>
66
+ To find out, we designed a deliberately{" "}
67
+ <tspan fontWeight={900} fill={C.red}>simple probe</tspan>
68
+ </text>
69
+ </g>
70
+ </>}</SlideCanvas>
71
+ );
72
+ }