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.
- package/dist/index.js +119 -0
- package/package.json +36 -0
- package/template-full/README.md +99 -0
- package/template-full/package.json +47 -0
- package/template-full/src/reveal/components/auto-layout.ts +229 -0
- package/template-full/src/reveal/components/charts.tsx +213 -0
- package/template-full/src/reveal/core/blocks.ts +172 -0
- package/template-full/src/reveal/core/deck-init.ts +60 -0
- package/template-full/src/reveal/core/design.ts +46 -0
- package/template-full/src/reveal/core/layout.ts +187 -0
- package/template-full/src/reveal/core/mount-registry.ts +41 -0
- package/template-full/src/reveal/core/presets.ts +189 -0
- package/template-full/src/reveal/core/runtime.ts +141 -0
- package/template-full/src/reveal/core/types.ts +114 -0
- package/template-full/src/reveal/data/algorithms.ts +78 -0
- package/template-full/src/reveal/data/benchmark.ts +79 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-arc-progress.tsx +153 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-before-after.tsx +164 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-bigtext.tsx +70 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-card-flip.tsx +118 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-chat-bubbles.tsx +257 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-code.tsx +136 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-concept-map.tsx +336 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-counter.tsx +194 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-cover.tsx +188 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-dark-dashboard.tsx +166 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-eval-matrix.tsx +191 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-force-graph.tsx +169 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-fullbleed-bars.tsx +109 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-fullbleed-flow.tsx +177 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-heatmap.tsx +135 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-icon-wall.tsx +143 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-math.tsx +103 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-number-morph.tsx +126 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-path.tsx +185 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-radar.tsx +124 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-rough.tsx +169 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-sankey.tsx +144 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-screenshot-annotate.tsx +181 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-stacked-cards.tsx +159 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-tabs.tsx +206 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-timeline.tsx +162 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-treemap.tsx +161 -0
- package/template-full/src/reveal/decks/demo-showcase/components/demo-zoom-focus.tsx +223 -0
- package/template-full/src/reveal/decks/demo-showcase/components/registry.ts +63 -0
- package/template-full/src/reveal/decks/demo-showcase/demo.css +237 -0
- package/template-full/src/reveal/decks/demo-showcase/index.html +24 -0
- package/template-full/src/reveal/decks/demo-showcase/main.ts +7 -0
- package/template-full/src/reveal/decks/demo-showcase/slides.ts +271 -0
- package/template-full/src/reveal/decks/fse26-rca/components/aws-cascade.tsx +295 -0
- package/template-full/src/reveal/decks/fse26-rca/components/bench-compare.tsx +64 -0
- package/template-full/src/reveal/decks/fse26-rca/components/bench-deficiency.tsx +104 -0
- package/template-full/src/reveal/decks/fse26-rca/components/bench-loop.tsx +402 -0
- package/template-full/src/reveal/decks/fse26-rca/components/bench-needs.tsx +78 -0
- package/template-full/src/reveal/decks/fse26-rca/components/closing-takeaway.tsx +165 -0
- package/template-full/src/reveal/decks/fse26-rca/components/cloud-incidents.tsx +88 -0
- package/template-full/src/reveal/decks/fse26-rca/components/failure-modes.tsx +59 -0
- package/template-full/src/reveal/decks/fse26-rca/components/fault-heatmap.tsx +85 -0
- package/template-full/src/reveal/decks/fse26-rca/components/hierarchy-tree.tsx +93 -0
- package/template-full/src/reveal/decks/fse26-rca/components/incident-hard.tsx +72 -0
- package/template-full/src/reveal/decks/fse26-rca/components/rca-pipeline.tsx +193 -0
- package/template-full/src/reveal/decks/fse26-rca/components/registry.ts +37 -0
- package/template-full/src/reveal/decks/fse26-rca/components/simple-rca.tsx +216 -0
- package/template-full/src/reveal/decks/fse26-rca/components/sota-collapse.tsx +63 -0
- package/template-full/src/reveal/decks/fse26-rca/components/srca-results.tsx +115 -0
- package/template-full/src/reveal/decks/fse26-rca/images/aws-outage-2025-deployflow.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/aws-post-event-summary.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/bbc-crowdstrike.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/cnn-meta-outage-2021.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/cover.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/nyt-facebook-2021.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/qr-repo.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/verge-crowdstrike-2024.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/images/wiki-meta-outage-2021.png +0 -0
- package/template-full/src/reveal/decks/fse26-rca/index.html +30 -0
- package/template-full/src/reveal/decks/fse26-rca/main.ts +8 -0
- package/template-full/src/reveal/decks/fse26-rca/slides.ts +175 -0
- package/template-full/src/reveal/env.d.ts +38 -0
- package/template-full/src/reveal/theme.css +762 -0
- package/template-full/src/reveal/tools/dev.mjs +120 -0
- package/template-full/src/reveal/tools/export-pdf.mjs +86 -0
- package/template-full/src/reveal/tools/preview.mjs +132 -0
- package/template-full/tsconfig.json +19 -0
- package/template-full/vite.config.ts +95 -0
- package/template-minimal/package.json +42 -0
- package/template-minimal/src/reveal/components/auto-layout.ts +229 -0
- package/template-minimal/src/reveal/components/charts.tsx +213 -0
- package/template-minimal/src/reveal/core/blocks.ts +172 -0
- package/template-minimal/src/reveal/core/deck-init.ts +60 -0
- package/template-minimal/src/reveal/core/design.ts +46 -0
- package/template-minimal/src/reveal/core/layout.ts +187 -0
- package/template-minimal/src/reveal/core/mount-registry.ts +41 -0
- package/template-minimal/src/reveal/core/presets.ts +189 -0
- package/template-minimal/src/reveal/core/runtime.ts +141 -0
- package/template-minimal/src/reveal/core/types.ts +114 -0
- package/template-minimal/src/reveal/data/.gitkeep +0 -0
- package/template-minimal/src/reveal/decks/my-deck/components/example-component.tsx +28 -0
- package/template-minimal/src/reveal/decks/my-deck/components/registry.ts +9 -0
- package/template-minimal/src/reveal/decks/my-deck/index.html +14 -0
- package/template-minimal/src/reveal/decks/my-deck/main.ts +5 -0
- package/template-minimal/src/reveal/decks/my-deck/slides.ts +34 -0
- package/template-minimal/src/reveal/env.d.ts +38 -0
- package/template-minimal/src/reveal/theme.css +762 -0
- package/template-minimal/tsconfig.json +19 -0
- 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
|
+
}
|