So, Aris, how can you help me?
Can you make a PPT on the topic Colinger carcinoma that will be presented in the classroom by a second-year MBBS student in a proper way so that a teacher will get remarks as very good?
Cholangiocarcinoma bile duct cancer classification pathology clinical features treatment MBBS
mkdir -p /home/daytona/workspace/cholangiocarcinoma-ppt && ls /home/daytona/workspace/
~/cholangiocarcinoma-ppt/build.js
const pptxgen = require("pptxgenjs");
const React = require("react");
const ReactDOMServer = require("react-dom/server");
const sharp = require("sharp");
const { execSync } = require("child_process");
// ─── Color Palette ───────────────────────────────────────────────────────────
const DARK_BG = "0D1B2A"; // deep navy (dominant - title/section slides)
const MID_NAVY = "1B3A5C"; // mid navy accent
const TEAL = "1A7E8F"; // teal accent
const GOLD = "D4A017"; // warm gold highlight
const WHITE = "FFFFFF";
const LIGHT_BG = "F0F4F8"; // light slides background
const TEXT_DARK = "1A1A2E"; // headings on light slides
const TEXT_MED = "2C3E50"; // body text
const SUBTEXT = "5A6A7A"; // subtitles
// ─── Font faces ──────────────────────────────────────────────────────────────
const FONT_TITLE = "Calibri";
const FONT_BODY = "Calibri";
// ─── Helper: draw top bar stripe on content slides ───────────────────────────
function addTopBar(slide, color) {
slide.addShape("rect", { x: 0, y: 0, w: 10, h: 0.12, fill: { color: color || TEAL }, line: { type: "none" } });
}
// ─── Helper: slide number ────────────────────────────────────────────────────
function addSlideNum(slide, num, total) {
slide.addText(`${num} / ${total}`, {
x: 8.8, y: 5.35, w: 1, h: 0.2,
fontSize: 9, color: SUBTEXT, align: "right", fontFace: FONT_BODY
});
}
// ─── Helper: section divider slide ───────────────────────────────────────────
function addSectionDivider(pres, title, subtitle) {
const slide = pres.addSlide();
slide.addShape("rect", { x: 0, y: 0, w: 10, h: 5.625, fill: { color: DARK_BG }, line: { type: "none" } });
slide.addShape("rect", { x: 0, y: 2.6, w: 10, h: 0.06, fill: { color: TEAL }, line: { type: "none" } });
slide.addShape("rect", { x: 3.5, y: 1.2, w: 0.06, h: 2.0, fill: { color: GOLD }, line: { type: "none" } });
slide.addText(title, {
x: 4.0, y: 1.5, w: 5.5, h: 1.2,
fontSize: 36, bold: true, color: WHITE, fontFace: FONT_TITLE, valign: "middle"
});
if (subtitle) {
slide.addText(subtitle, {
x: 4.0, y: 2.8, w: 5.5, h: 0.7,
fontSize: 16, color: TEAL, fontFace: FONT_BODY, italic: true
});
}
return slide;
}
// ─── Helper: content slide template ──────────────────────────────────────────
function addContentSlide(pres, heading, num, total, accentColor) {
const slide = pres.addSlide();
// Light background
slide.addShape("rect", { x: 0, y: 0, w: 10, h: 5.625, fill: { color: LIGHT_BG }, line: { type: "none" } });
// Top colored bar
addTopBar(slide, accentColor || TEAL);
// Heading band
slide.addShape("rect", { x: 0, y: 0.12, w: 10, h: 0.75, fill: { color: MID_NAVY }, line: { type: "none" } });
slide.addText(heading, {
x: 0.3, y: 0.12, w: 9.4, h: 0.75,
fontSize: 20, bold: true, color: WHITE, fontFace: FONT_TITLE, valign: "middle", margin: 0
});
addSlideNum(slide, num, total);
return slide;
}
// ─── Helper: bullet items ────────────────────────────────────────────────────
function bullets(items, opts) {
return items.map((item, i) => ({
text: item,
options: {
bullet: { type: "bullet", characterCode: "2022" },
fontSize: opts.fontSize || 15,
color: opts.color || TEXT_DARK,
fontFace: FONT_BODY,
paraSpaceBefore: opts.paraSpace || 4,
breakLine: i < items.length - 1
}
}));
}
// ─── Helper: sub-bullets ─────────────────────────────────────────────────────
function subbullets(items, opts) {
return items.map((item, i) => ({
text: item,
options: {
bullet: { type: "bullet", characterCode: "25B8", indent: 20 },
fontSize: opts.fontSize || 13,
color: opts.color || TEXT_MED,
fontFace: FONT_BODY,
indentLevel: 1,
paraSpaceBefore: 2,
breakLine: i < items.length - 1
}
}));
}
// ─── Helper: two-column layout ────────────────────────────────────────────────
function addTwoCols(slide, leftItems, rightItems, topY, colH, fontSize) {
const leftTexts = bullets(leftItems, { fontSize: fontSize || 13, paraSpace: 5 });
const rightTexts = bullets(rightItems, { fontSize: fontSize || 13, paraSpace: 5 });
slide.addText(leftTexts, { x: 0.3, y: topY, w: 4.5, h: colH, valign: "top" });
slide.addShape("rect", { x: 5.05, y: topY + 0.1, w: 0.04, h: colH - 0.2, fill: { color: TEAL }, line: { type: "none" } });
slide.addText(rightTexts, { x: 5.2, y: topY, w: 4.5, h: colH, valign: "top" });
}
// ─── Fetch textbook images ────────────────────────────────────────────────────
function fetchImages(urls) {
try {
const result = execSync(
`node /home/daytona/skills/shared/scripts/fetch_images.js ${urls.map(u => `"${u}"`).join(" ")}`
).toString();
return JSON.parse(result);
} catch (e) {
return urls.map(() => ({ base64: null, error: e.message }));
}
}
// ═════════════════════════════════════════════════════════════════════════════
async function buildPresentation() {
const pres = new pptxgen();
pres.layout = "LAYOUT_16x9";
pres.title = "Cholangiocarcinoma";
pres.author = "Second-Year MBBS Student";
const TOTAL = 18;
// ── Fetch the histopathology image from Robbins ─────────────────────────
const imgUrls = [
"https://cdn.orris.care/cdss_images/3e92f1397cc3ba1c353762cd045b612780c70a8dba8b8e2806f736bccbabe016.png"
];
const imgs = fetchImages(imgUrls);
const histoImg = imgs[0];
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 1 – Title Slide
// ─────────────────────────────────────────────────────────────────────────
{
const slide = pres.addSlide();
// Full dark background
slide.addShape("rect", { x: 0, y: 0, w: 10, h: 5.625, fill: { color: DARK_BG }, line: { type: "none" } });
// Decorative diagonal accent
slide.addShape("rect", { x: 0, y: 3.8, w: 10, h: 0.1, fill: { color: TEAL }, line: { type: "none" } });
slide.addShape("rect", { x: 0, y: 3.95, w: 6, h: 0.05, fill: { color: GOLD }, line: { type: "none" } });
// Title
slide.addText("CHOLANGIOCARCINOMA", {
x: 0.5, y: 0.8, w: 9, h: 1.4,
fontSize: 44, bold: true, color: WHITE,
fontFace: FONT_TITLE, align: "center", valign: "middle",
charSpacing: 2
});
// Subtitle
slide.addText("Bile Duct Cancer: A Comprehensive Overview", {
x: 0.5, y: 2.4, w: 9, h: 0.6,
fontSize: 18, color: TEAL, fontFace: FONT_BODY, align: "center", italic: true
});
// Presenter line
slide.addText("Presented by: Second-Year MBBS Student", {
x: 0.5, y: 4.2, w: 9, h: 0.4,
fontSize: 14, color: GOLD, fontFace: FONT_BODY, align: "center"
});
slide.addText("Department of Pathology | MBBS 2nd Year | 2026", {
x: 0.5, y: 4.7, w: 9, h: 0.35,
fontSize: 12, color: WHITE, fontFace: FONT_BODY, align: "center"
});
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 2 – Table of Contents
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Table of Contents", 2, TOTAL);
const topics = [
["1. Introduction & Definition", "2. Epidemiology"],
["3. Etiology & Risk Factors", "4. Classification"],
["5. Pathogenesis", "6. Morphology & Histopathology"],
["7. Clinical Features", "8. Diagnosis & Investigations"],
["9. Staging (TNM)", "10. Treatment"],
["11. Prognosis", "12. Summary & Key Points"],
];
topics.forEach((row, i) => {
const y = 1.1 + i * 0.65;
slide.addShape("rect", { x: 0.3, y: y, w: 4.3, h: 0.55, fill: { color: MID_NAVY }, line: { type: "none" } });
slide.addShape("rect", { x: 5.1, y: y, w: 4.3, h: 0.55, fill: { color: MID_NAVY }, line: { type: "none" } });
slide.addText(row[0], { x: 0.5, y: y, w: 4.1, h: 0.55, fontSize: 13, color: WHITE, fontFace: FONT_BODY, valign: "middle" });
slide.addText(row[1], { x: 5.3, y: y, w: 4.1, h: 0.55, fontSize: 13, color: WHITE, fontFace: FONT_BODY, valign: "middle" });
});
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 3 – Introduction & Definition
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Introduction & Definition", 3, TOTAL);
slide.addText([
{ text: "What is Cholangiocarcinoma?", options: { bold: true, fontSize: 17, color: MID_NAVY, fontFace: FONT_TITLE, breakLine: true } },
], { x: 0.3, y: 1.1, w: 9.4, h: 0.45 });
const defItems = bullets([
"Malignant tumor arising from the epithelium of the bile ducts (cholangiocytes)",
"Second most common primary malignant tumor of the liver, after Hepatocellular Carcinoma (HCC)",
"Accounts for ~3% of all gastrointestinal cancers",
"Often abbreviated as CCA",
"Produces mucin — histologically a mucin-secreting adenocarcinoma",
"Notorious for late presentation, dense desmoplasia, and poor prognosis"
], { fontSize: 14, paraSpace: 5 });
slide.addText(defItems, { x: 0.3, y: 1.6, w: 9.2, h: 3.7, valign: "top" });
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 4 – Epidemiology
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Epidemiology", 4, TOTAL, GOLD);
// Left column: global stats
slide.addText("Global Statistics", { x: 0.3, y: 1.0, w: 4.5, h: 0.4, fontSize: 14, bold: true, color: MID_NAVY, fontFace: FONT_TITLE });
slide.addText(bullets([
"~2,000–3,000 new cases/year in the US",
"15% of primary liver malignancies worldwide",
"More common in East Asia (SE Asia, Korea, Japan)",
"Incidence rising globally over past 3 decades",
"Peak age: 55–75 years",
"Male > Female",
], { fontSize: 13, paraSpace: 4 }), { x: 0.3, y: 1.45, w: 4.5, h: 3.5, valign: "top" });
slide.addShape("rect", { x: 5.05, y: 1.0, w: 0.04, h: 4.0, fill: { color: TEAL }, line: { type: "none" } });
// Right column: geographic
slide.addText("High-Risk Regions", { x: 5.2, y: 1.0, w: 4.5, h: 0.4, fontSize: 14, bold: true, color: MID_NAVY, fontFace: FONT_TITLE });
slide.addText(bullets([
"NE Thailand, Laos, Cambodia — 30-40x higher rates",
"Driven by endemic liver fluke (Opisthorchis viverrini)",
"South Korea — Clonorchis sinensis infestation",
"Increasing incidence in Western countries linked to NASH/NAFLD",
"ICD-10: C22.1 (intrahepatic), C24 (extrahepatic)"
], { fontSize: 13, paraSpace: 4 }), { x: 5.2, y: 1.45, w: 4.5, h: 3.5, valign: "top" });
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 5 – Etiology & Risk Factors
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Etiology & Risk Factors", 5, TOTAL);
// Three card boxes
const cards = [
{ title: "Parasitic / Infectious", color: TEAL, items: ["Liver flukes: Opisthorchis viverrini, Clonorchis sinensis", "Hepatitis B virus (HBV)", "Hepatitis C virus (HCV)", "HIV infection"] },
{ title: "Biliary Tract Disease", color: MID_NAVY, items: ["Primary Sclerosing Cholangitis (PSC) — lifetime risk 5–20%", "Choledochal cysts", "Hepatolithiasis (intrahepatic stones)", "Caroli disease"] },
{ title: "Metabolic / Other", color: GOLD, items: ["NAFLD / NASH", "Diabetes mellitus", "Obesity", "Inflammatory bowel disease (UC)", "Thorotrast exposure (historical)"] },
];
cards.forEach((card, i) => {
const x = 0.2 + i * 3.3;
slide.addShape("rect", { x, y: 1.0, w: 3.1, h: 0.45, fill: { color: card.color }, line: { type: "none" } });
slide.addText(card.title, { x, y: 1.0, w: 3.1, h: 0.45, fontSize: 13, bold: true, color: WHITE, fontFace: FONT_TITLE, align: "center", valign: "middle" });
slide.addShape("rect", { x, y: 1.45, w: 3.1, h: 3.85, fill: { color: WHITE }, line: { color: card.color, pt: 1.5 } });
const bItems = card.items.map((item, j) => ({
text: item,
options: { bullet: { type: "bullet", characterCode: "25BA" }, fontSize: 12, color: TEXT_DARK, fontFace: FONT_BODY, paraSpaceBefore: 5, breakLine: j < card.items.length - 1 }
}));
slide.addText(bItems, { x: x + 0.12, y: 1.5, w: 2.88, h: 3.75, valign: "top" });
});
// Bottom note
slide.addText("Mnemonic: 'CHIPS' — Cholangitis, Hepatolithiasis, IBD, Parasites, Sclerosing cholangitis", {
x: 0.3, y: 5.2, w: 9.4, h: 0.3, fontSize: 11, color: TEAL, italic: true, fontFace: FONT_BODY
});
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 6 – Classification
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Classification of Cholangiocarcinoma", 6, TOTAL, GOLD);
slide.addText("By Anatomical Location (Most Clinically Used):", {
x: 0.3, y: 1.0, w: 9.4, h: 0.4, fontSize: 15, bold: true, color: MID_NAVY, fontFace: FONT_TITLE
});
const typeCards = [
{ type: "Intrahepatic (iCCA)", pct: "~10%", desc: "Peripheral, within liver parenchyma. Often presents as a large mass. Shares risk factors with HCC. Difficult to detect early.", color: TEAL },
{ type: "Perihilar (pCCA)", pct: "50–60%", desc: "Also called Klatskin tumor. Located at the biliary confluence. Most common type. Causes early biliary obstruction.", color: MID_NAVY },
{ type: "Distal (dCCA)", pct: "20–30%", desc: "Arises from common bile duct posterior to duodenum. Earliest obstructive symptoms. Best surgical outcomes.", color: GOLD },
];
typeCards.forEach((tc, i) => {
const x = 0.2 + i * 3.27;
slide.addShape("rect", { x, y: 1.5, w: 3.1, h: 3.8, fill: { color: WHITE }, line: { color: tc.color, pt: 2 } });
slide.addShape("rect", { x, y: 1.5, w: 3.1, h: 0.6, fill: { color: tc.color }, line: { type: "none" } });
slide.addText(tc.type, { x, y: 1.5, w: 3.1, h: 0.4, fontSize: 13, bold: true, color: WHITE, fontFace: FONT_TITLE, align: "center", valign: "middle" });
slide.addText(tc.pct, { x, y: 1.9, w: 3.1, h: 0.25, fontSize: 16, bold: true, color: tc.color, fontFace: FONT_TITLE, align: "center" });
slide.addText(tc.desc, { x: x + 0.1, y: 2.2, w: 2.9, h: 3.0, fontSize: 12, color: TEXT_DARK, fontFace: FONT_BODY, valign: "top", wrap: true });
});
slide.addText("Bismuth-Corlette Classification further subdivides perihilar CCA (Type I–IV) based on ductal involvement", {
x: 0.3, y: 5.2, w: 9.4, h: 0.3, fontSize: 11, color: SUBTEXT, italic: true, fontFace: FONT_BODY
});
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 7 – Pathogenesis
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Pathogenesis", 7, TOTAL);
slide.addText("Core Mechanism: Chronic Inflammation → Genetic Damage → Malignant Transformation", {
x: 0.3, y: 1.0, w: 9.4, h: 0.45,
fontSize: 13, color: TEAL, italic: true, fontFace: FONT_BODY, bold: true
});
// Flow boxes
const steps = [
{ label: "Chronic\nInflammation", desc: "PSC, flukes, stones" },
{ label: "Cholestasis\n& Bile Stasis", desc: "Toxic bile acids accumulate" },
{ label: "Oxidative DNA\nDamage", desc: "ROS, cytokines (IL-6, TNF-α)" },
{ label: "Somatic\nMutations", desc: "KRAS, IDH1/2, FGFR2, TP53, SMAD4" },
{ label: "Malignant\nTransformation", desc: "Adenocarcinoma" },
];
const arrowW = 0.3;
const boxW = 1.6;
const totalW = steps.length * boxW + (steps.length - 1) * arrowW;
const startX = (10 - totalW) / 2;
steps.forEach((step, i) => {
const x = startX + i * (boxW + arrowW);
const boxColor = i === 4 ? TEAL : MID_NAVY;
slide.addShape("rect", { x, y: 1.65, w: boxW, h: 0.8, fill: { color: boxColor }, line: { type: "none" } });
slide.addText(step.label, { x, y: 1.65, w: boxW, h: 0.8, fontSize: 11, bold: true, color: WHITE, fontFace: FONT_TITLE, align: "center", valign: "middle" });
slide.addText(step.desc, { x: x - 0.05, y: 2.5, w: boxW + 0.1, h: 0.55, fontSize: 9.5, color: TEXT_MED, fontFace: FONT_BODY, align: "center", italic: true });
if (i < steps.length - 1) {
slide.addText("→", { x: x + boxW, y: 1.68, w: arrowW, h: 0.7, fontSize: 22, color: GOLD, align: "center", valign: "middle" });
}
});
slide.addText("Molecular Drivers:", {
x: 0.3, y: 3.2, w: 9.4, h: 0.4, fontSize: 14, bold: true, color: MID_NAVY, fontFace: FONT_TITLE
});
const molItems = bullets([
"IDH1 / IDH2 mutations — most common in intrahepatic CCA (~15–25%)",
"FGFR2 fusions — targetable driver in ~15% of intrahepatic CCA (new therapies available)",
"KRAS mutations — common in extrahepatic CCA",
"TP53 inactivation, SMAD4 loss, CDKN2A deletion",
"Epigenetic changes: promoter hypermethylation, histone modifications"
], { fontSize: 13, paraSpace: 4 });
slide.addText(molItems, { x: 0.3, y: 3.6, w: 9.4, h: 1.9, valign: "top" });
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 8 – Morphology & Histopathology
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Morphology & Histopathology", 8, TOTAL, GOLD);
// Left text
slide.addText("Gross Morphology:", {
x: 0.3, y: 1.0, w: 5.2, h: 0.35, fontSize: 14, bold: true, color: MID_NAVY, fontFace: FONT_TITLE
});
slide.addText(bullets([
"Extrahepatic CCA: Firm, gray nodules within bile duct wall; may be diffusely infiltrative",
"Intrahepatic CCA: Occurs in non-cirrhotic liver; may track along portal tracts or form large tumors",
"Growth patterns: Mass-forming | Periductal-infiltrating | Intraductal"
], { fontSize: 12.5, paraSpace: 5 }), { x: 0.3, y: 1.4, w: 5.0, h: 1.5, valign: "top" });
slide.addText("Histopathology (Microscopy):", {
x: 0.3, y: 3.0, w: 5.2, h: 0.35, fontSize: 14, bold: true, color: MID_NAVY, fontFace: FONT_TITLE
});
slide.addText(bullets([
"Mucin-producing adenocarcinoma (well to moderately differentiated)",
"Glandular / tubular structures lined by malignant epithelium",
"Marked desmoplastic stroma (dense fibrous reaction) — KEY FEATURE",
"Lymphovascular invasion and perineural invasion — common",
"IHC: CK7+, CK19+, MOC31+; Hepatocyte markers negative"
], { fontSize: 12.5, paraSpace: 4 }), { x: 0.3, y: 3.38, w: 5.0, h: 2.1, valign: "top" });
// Histology image from Robbins
if (histoImg && histoImg.base64 && !histoImg.error) {
slide.addImage({ data: histoImg.base64, x: 5.55, y: 1.0, w: 4.15, h: 3.2, sizing: { type: "contain", w: 4.15, h: 3.2 } });
slide.addText("Fig: Cholangiocarcinoma — invasive malignant glands in sclerotic stroma (Robbins Pathology)", {
x: 5.55, y: 4.3, w: 4.15, h: 0.5, fontSize: 9, color: SUBTEXT, italic: true, fontFace: FONT_BODY, align: "center"
});
} else {
slide.addShape("rect", { x: 5.55, y: 1.0, w: 4.15, h: 3.2, fill: { color: MID_NAVY }, line: { type: "none" } });
slide.addText("Histopathology Image\n(Invasive glands in desmoplastic stroma)", {
x: 5.55, y: 1.0, w: 4.15, h: 3.2, fontSize: 13, color: WHITE, align: "center", valign: "middle", fontFace: FONT_BODY
});
}
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 9 – Clinical Features
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Clinical Features", 9, TOTAL);
slide.addText("Clinical Presentation varies by location:", {
x: 0.3, y: 1.0, w: 9.4, h: 0.35, fontSize: 14, bold: true, color: MID_NAVY, fontFace: FONT_TITLE
});
const clCols = [
{
title: "Intrahepatic CCA",
color: TEAL,
items: ["Often SILENT until late stage", "Vague right upper quadrant pain", "Weight loss, fatigue", "Hepatomegaly", "Elevated liver enzymes", "Incidental imaging finding"]
},
{
title: "Perihilar (Klatskin)",
color: MID_NAVY,
items: ["Progressive obstructive JAUNDICE (painless)", "Pruritus (bile salt deposition)", "Dark urine, pale stools (clay-colored)", "Weight loss", "Cholangitis (fever, RUQ pain)", "Courvoisier sign may be absent"]
},
{
title: "Distal CCA",
color: GOLD,
items: ["Painless progressive jaundice", "Palpable gallbladder (Courvoisier sign +ve)", "Pale stools, dark urine", "Steatorrhea", "Earlier presentation than perihilar CCA"]
}
];
clCols.forEach((col, i) => {
const x = 0.2 + i * 3.27;
slide.addShape("rect", { x, y: 1.45, w: 3.1, h: 0.42, fill: { color: col.color }, line: { type: "none" } });
slide.addText(col.title, { x, y: 1.45, w: 3.1, h: 0.42, fontSize: 12, bold: true, color: WHITE, fontFace: FONT_TITLE, align: "center", valign: "middle" });
slide.addShape("rect", { x, y: 1.87, w: 3.1, h: 3.5, fill: { color: WHITE }, line: { color: col.color, pt: 1.5 } });
const bItems = col.items.map((it, j) => ({
text: it,
options: { bullet: { type: "bullet", characterCode: "2022" }, fontSize: 12, color: TEXT_DARK, fontFace: FONT_BODY, paraSpaceBefore: 5, breakLine: j < col.items.length - 1 }
}));
slide.addText(bItems, { x: x + 0.1, y: 1.95, w: 2.9, h: 3.35, valign: "top" });
});
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 10 – Diagnosis & Investigations
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Diagnosis & Investigations", 10, TOTAL, TEAL);
const diagCols = [
{
label: "Laboratory Tests",
color: MID_NAVY,
items: [
"LFTs: ↑Bilirubin (conjugated), ↑ALP, ↑GGT",
"CA 19-9 — most used tumor marker; sensitivity 60–70%",
"CEA — less specific",
"AFP — elevated in HCC, not CCA",
"IgG4 — rule out autoimmune cholangiopathy",
"LDH, CBC"
]
},
{
label: "Imaging",
color: TEAL,
items: [
"Ultrasound: First-line — dilated bile ducts",
"MRCP: Gold standard for biliary anatomy (non-invasive)",
"CT Abdomen (triple phase): Mass, vascular invasion, metastases",
"PET-CT: Staging and distant metastases",
"ERCP: Diagnostic + therapeutic (stenting)",
"EUS: Lymph node sampling"
]
},
{
label: "Tissue Diagnosis",
color: GOLD,
items: [
"Biliary brushings (ERCP) — sensitivity ~30–50%",
"Fluorescence in situ hybridization (FISH) improves yield",
"EUS-guided biopsy for nodes / mass",
"Percutaneous biopsy (unresectable disease)",
"Cholangoscopy + directed biopsy",
"Next-gen sequencing for IDH1/2, FGFR2 mutations"
]
}
];
diagCols.forEach((col, i) => {
const x = 0.2 + i * 3.27;
slide.addShape("rect", { x, y: 1.0, w: 3.1, h: 0.42, fill: { color: col.color }, line: { type: "none" } });
slide.addText(col.label, { x, y: 1.0, w: 3.1, h: 0.42, fontSize: 12.5, bold: true, color: WHITE, fontFace: FONT_TITLE, align: "center", valign: "middle" });
slide.addShape("rect", { x, y: 1.42, w: 3.1, h: 4.0, fill: { color: WHITE }, line: { color: col.color, pt: 1.5 } });
const bItems = col.items.map((it, j) => ({
text: it,
options: { bullet: { type: "bullet", characterCode: "25BA" }, fontSize: 11.5, color: TEXT_DARK, fontFace: FONT_BODY, paraSpaceBefore: 4, breakLine: j < col.items.length - 1 }
}));
slide.addText(bItems, { x: x + 0.1, y: 1.5, w: 2.9, h: 3.88, valign: "top" });
});
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 11 – TNM Staging
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "TNM Staging (Distal CCA — AJCC 8th Ed.)", 11, TOTAL);
slide.addText("T – Primary Tumor:", {
x: 0.3, y: 1.0, w: 4.5, h: 0.3, fontSize: 13, bold: true, color: MID_NAVY, fontFace: FONT_TITLE
});
const tRows = [
["T1", "Invades bile duct wall, depth < 5 mm"],
["T2", "Invades bile duct wall, depth 5–12 mm"],
["T3", "Invades bile duct wall, depth > 12 mm"],
["T4", "Involves celiac axis / SMA / common hepatic artery"],
];
const nRows = [
["N0", "No regional lymph node metastasis"],
["N1", "Metastasis in 1–3 regional nodes"],
["N2", "Metastasis in ≥4 regional nodes"],
];
const mRows = [
["M0", "No distant metastasis"],
["M1", "Distant metastasis"],
];
const drawTable = (rows, x, y, w, headerColor) => {
rows.forEach((row, i) => {
const rowY = y + i * 0.48;
const bg = i % 2 === 0 ? "EDF4FB" : WHITE;
slide.addShape("rect", { x, y: rowY, w: 1.0, h: 0.44, fill: { color: headerColor }, line: { type: "none" } });
slide.addShape("rect", { x: x + 1.0, y: rowY, w: w - 1.0, h: 0.44, fill: { color: bg }, line: { color: "CCCCCC", pt: 0.5 } });
slide.addText(row[0], { x, y: rowY, w: 1.0, h: 0.44, fontSize: 12, bold: true, color: WHITE, fontFace: FONT_BODY, align: "center", valign: "middle" });
slide.addText(row[1], { x: x + 1.05, y: rowY, w: w - 1.1, h: 0.44, fontSize: 11.5, color: TEXT_DARK, fontFace: FONT_BODY, valign: "middle" });
});
};
drawTable(tRows, 0.3, 1.38, 4.3, MID_NAVY);
slide.addText("N – Lymph Nodes:", {
x: 0.3, y: 3.4, w: 4.3, h: 0.3, fontSize: 13, bold: true, color: TEAL, fontFace: FONT_TITLE
});
drawTable(nRows, 0.3, 3.74, 4.3, TEAL);
slide.addText("M – Distant Metastasis:", {
x: 5.1, y: 1.0, w: 4.5, h: 0.3, fontSize: 13, bold: true, color: GOLD, fontFace: FONT_TITLE
});
drawTable(mRows, 5.1, 1.38, 4.5, GOLD);
slide.addText("Overall Staging:", { x: 5.1, y: 2.4, w: 4.5, h: 0.3, fontSize: 13, bold: true, color: MID_NAVY, fontFace: FONT_TITLE });
const stageRows = [
["Stage I", "T1–T2, N0, M0"],
["Stage II", "T3, N0, M0"],
["Stage III", "T1–T3, N1, M0 OR T4, any N, M0"],
["Stage IVA", "T4, N2, M0"],
["Stage IVB", "Any T, Any N, M1"],
];
stageRows.forEach((row, i) => {
const y = 2.75 + i * 0.47;
const bg = i % 2 === 0 ? "EDF4FB" : WHITE;
slide.addShape("rect", { x: 5.1, y, w: 1.5, h: 0.43, fill: { color: MID_NAVY }, line: { type: "none" } });
slide.addShape("rect", { x: 6.6, y, w: 3.0, h: 0.43, fill: { color: bg }, line: { color: "CCCCCC", pt: 0.5 } });
slide.addText(row[0], { x: 5.1, y, w: 1.5, h: 0.43, fontSize: 12, bold: true, color: WHITE, fontFace: FONT_BODY, align: "center", valign: "middle" });
slide.addText(row[1], { x: 6.65, y, w: 2.9, h: 0.43, fontSize: 11.5, color: TEXT_DARK, fontFace: FONT_BODY, valign: "middle" });
});
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 12 – Treatment Overview
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Treatment", 12, TOTAL, GOLD);
slide.addText("Treatment depends on location, stage, and resectability:", {
x: 0.3, y: 1.0, w: 9.4, h: 0.35, fontSize: 13, color: TEAL, italic: true, fontFace: FONT_BODY, bold: true
});
const txCols = [
{
label: "Surgical (Curative)",
color: TEAL,
items: [
"Hepatic resection with clear margins (R0) — only cure",
"Bile duct resection for extrahepatic CCA",
"Whipple procedure (pancreaticoduodenectomy) for distal CCA",
"Liver transplantation: selected perihilar CCA + Mayo Protocol",
"Only ~20–30% of patients are resectable at diagnosis"
]
},
{
label: "Palliative Interventions",
color: MID_NAVY,
items: [
"Biliary stenting (ERCP or PTC) — relieve obstruction",
"Photodynamic therapy (PDT)",
"Transarterial chemoembolization (TACE) for intrahepatic CCA",
"Radiofrequency ablation (RFA)",
"Radiation therapy (stereotactic body radiotherapy)"
]
},
{
label: "Systemic Therapy",
color: GOLD,
items: [
"First-line: Gemcitabine + Cisplatin (standard of care)",
"Added durvalumab (anti-PD-L1) — improves survival (TOPAZ-1 trial)",
"IDH1 inhibitor: Ivosidenib (approved for IDH1-mutant iCCA)",
"FGFR2 inhibitors: Pemigatinib, Infigratinib",
"Second-line: FOLFOX, FOLFIRI"
]
}
];
txCols.forEach((col, i) => {
const x = 0.2 + i * 3.27;
slide.addShape("rect", { x, y: 1.45, w: 3.1, h: 0.42, fill: { color: col.color }, line: { type: "none" } });
slide.addText(col.label, { x, y: 1.45, w: 3.1, h: 0.42, fontSize: 11.5, bold: true, color: WHITE, fontFace: FONT_TITLE, align: "center", valign: "middle" });
slide.addShape("rect", { x, y: 1.87, w: 3.1, h: 3.55, fill: { color: WHITE }, line: { color: col.color, pt: 1.5 } });
const bItems = col.items.map((it, j) => ({
text: it,
options: { bullet: { type: "bullet", characterCode: "2022" }, fontSize: 12, color: TEXT_DARK, fontFace: FONT_BODY, paraSpaceBefore: 5, breakLine: j < col.items.length - 1 }
}));
slide.addText(bItems, { x: x + 0.1, y: 1.95, w: 2.9, h: 3.42, valign: "top" });
});
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 13 – Prognosis
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Prognosis", 13, TOTAL);
slide.addText("Overall prognosis is poor — late presentation, early metastasis, desmoplastic barrier.", {
x: 0.3, y: 1.0, w: 9.4, h: 0.38, fontSize: 13, color: TEAL, italic: true, fontFace: FONT_BODY, bold: true
});
// Prognosis table
const progRows = [
["Tumor Type", "Median Survival", "5-Year Survival", "Key Factor"],
["Resected distal CCA", "24–36 months", "20–35%", "R0 resection margin"],
["Resected perihilar CCA", "18–24 months", "10–20%", "Bismuth type, margins"],
["Intrahepatic CCA (resected)","12–24 months", "15–35%", "Tumor size, vascular invasion"],
["Unresectable / Metastatic", "6–12 months", "< 5%", "Systemic chemo response"],
];
progRows.forEach((row, i) => {
const y = 1.5 + i * 0.63;
const isHeader = i === 0;
const bg = isHeader ? MID_NAVY : (i % 2 === 1 ? "EDF4FB" : WHITE);
const textColor = isHeader ? WHITE : TEXT_DARK;
const widths = [3.0, 1.9, 1.8, 2.95];
const xs = [0.25, 3.25, 5.15, 6.95];
row.forEach((cell, j) => {
slide.addShape("rect", { x: xs[j], y, w: widths[j], h: 0.58, fill: { color: bg }, line: { color: "CCCCCC", pt: 0.5 } });
slide.addText(cell, { x: xs[j] + 0.05, y, w: widths[j] - 0.1, h: 0.58, fontSize: isHeader ? 12 : 11.5, bold: isHeader, color: textColor, fontFace: FONT_BODY, valign: "middle", wrap: true });
});
});
// Poor prognostic factors
slide.addText("Poor Prognostic Factors:", { x: 0.3, y: 4.72, w: 4.5, h: 0.3, fontSize: 12, bold: true, color: MID_NAVY, fontFace: FONT_TITLE });
slide.addText("Positive margins (R1/R2) • Lymph node involvement • Vascular invasion • Perineural invasion • Advanced T stage • Intrahepatic CCA type", {
x: 0.3, y: 5.05, w: 9.4, h: 0.35, fontSize: 11, color: TEXT_MED, fontFace: FONT_BODY
});
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 14 – Differential Diagnosis
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Differential Diagnosis", 14, TOTAL, TEAL);
slide.addText("Important conditions to distinguish from Cholangiocarcinoma:", {
x: 0.3, y: 1.0, w: 9.4, h: 0.35, fontSize: 13, color: TEAL, italic: true, fontFace: FONT_BODY
});
const ddx = [
{ dx: "Hepatocellular Carcinoma (HCC)", clue: "Cirrhosis background, AFP elevated, hepatocyte markers +ve on IHC" },
{ dx: "Gallbladder Carcinoma", clue: "Arises from GB wall; may invade liver bed; often presents as thickened GB wall" },
{ dx: "Pancreatic Adenocarcinoma", clue: "Similar jaundice pattern; CA19-9 elevated; ERCP shows pancreatic duct involvement" },
{ dx: "Primary Sclerosing Cholangitis", clue: "Inflammatory, non-malignant biliary strictures; bead-and-pruned appearance on MRCP" },
{ dx: "Metastatic Adenocarcinoma", clue: "History of primary tumor (colon, breast, lung); IHC panel, clinical history key" },
{ dx: "IgG4-related Cholangiopathy", clue: "Elevated serum IgG4, responds to steroids; mimics perihilar CCA clinically" },
];
ddx.forEach((d, i) => {
const y = 1.44 + i * 0.65;
const bg = i % 2 === 0 ? "EDF4FB" : WHITE;
slide.addShape("rect", { x: 0.25, y, w: 3.5, h: 0.6, fill: { color: MID_NAVY }, line: { type: "none" } });
slide.addShape("rect", { x: 3.75, y, w: 5.9, h: 0.6, fill: { color: bg }, line: { color: "DDDDDD", pt: 0.5 } });
slide.addText(d.dx, { x: 0.3, y, w: 3.45, h: 0.6, fontSize: 12, bold: true, color: WHITE, fontFace: FONT_BODY, valign: "middle" });
slide.addText(d.clue, { x: 3.85, y, w: 5.75, h: 0.6, fontSize: 11.5, color: TEXT_DARK, fontFace: FONT_BODY, valign: "middle" });
});
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 15 – Recent Advances
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Recent Advances & Targeted Therapies", 15, TOTAL, GOLD);
slide.addText("Molecular profiling has revolutionized CCA treatment in the last decade:", {
x: 0.3, y: 1.0, w: 9.4, h: 0.35, fontSize: 13, color: MID_NAVY, italic: true, fontFace: FONT_BODY, bold: true
});
const advances = [
{ target: "FGFR2 Fusions", drug: "Pemigatinib, Infigratinib, Futibatinib", note: "~15% iCCA; FDA-approved 2nd line" },
{ target: "IDH1 Mutations", drug: "Ivosidenib", note: "~15–25% iCCA; FDA-approved 2021" },
{ target: "BRAF V600E", drug: "Dabrafenib + Trametinib", note: "Rare, ~5%; off-label use" },
{ target: "HER2 Amplification", drug: "Trastuzumab + Pertuzumab", note: "Emerging target; trials ongoing" },
{ target: "PD-L1 / PD-1", drug: "Durvalumab, Pembrolizumab", note: "TOPAZ-1 (durvalumab): improved OS; FDA-approved" },
{ target: "NTRK Fusions", drug: "Larotrectinib, Entrectinib", note: "Rare; tumor-agnostic approval" },
];
advances.forEach((a, i) => {
const y = 1.45 + i * 0.62;
const bg = i % 2 === 0 ? "EDF4FB" : WHITE;
slide.addShape("rect", { x: 0.25, y, w: 2.5, h: 0.57, fill: { color: TEAL }, line: { type: "none" } });
slide.addShape("rect", { x: 2.75, y, w: 3.5, h: 0.57, fill: { color: bg }, line: { color: "CCCCCC", pt: 0.5 } });
slide.addShape("rect", { x: 6.25, y, w: 3.4, h: 0.57, fill: { color: bg }, line: { color: "CCCCCC", pt: 0.5 } });
slide.addText(a.target, { x: 0.3, y, w: 2.4, h: 0.57, fontSize: 12, bold: true, color: WHITE, fontFace: FONT_BODY, valign: "middle" });
slide.addText(a.drug, { x: 2.8, y, w: 3.4, h: 0.57, fontSize: 11.5, color: TEXT_DARK, fontFace: FONT_BODY, valign: "middle" });
slide.addText(a.note, { x: 6.3, y, w: 3.3, h: 0.57, fontSize: 11.5, color: SUBTEXT, fontFace: FONT_BODY, valign: "middle", italic: true });
});
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 16 – Key Points / Summary
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "Key Points to Remember", 16, TOTAL);
const keyPoints = [
"CCA = malignant tumor of bile duct epithelium; 2nd most common primary liver cancer",
"Perihilar (Klatskin tumor) is the MOST COMMON type (~50–60%)",
"Hallmark histology: mucin-producing adenocarcinoma with DESMOPLASTIC stroma",
"Painless progressive jaundice is the classic presentation of extrahepatic CCA",
"MRCP is the gold standard for imaging the biliary tree",
"CA 19-9 is the most used tumor marker (but not specific)",
"ONLY surgical resection (R0) offers a curative chance",
"First-line palliative chemo: Gemcitabine + Cisplatin ± Durvalumab",
"Targetable mutations: FGFR2 fusions and IDH1 mutations are most important",
"Prognosis is poor — median survival < 1 year for unresectable disease"
];
keyPoints.forEach((kp, i) => {
const y = 1.05 + i * 0.44;
const color = i % 2 === 0 ? TEAL : MID_NAVY;
slide.addShape("rect", { x: 0.25, y, w: 0.35, h: 0.36, fill: { color }, line: { type: "none" } });
slide.addText(`${i + 1}`, { x: 0.25, y, w: 0.35, h: 0.36, fontSize: 12, bold: true, color: WHITE, fontFace: FONT_BODY, align: "center", valign: "middle" });
slide.addText(kp, { x: 0.7, y: y + 0.02, w: 9.0, h: 0.36, fontSize: 12.5, color: TEXT_DARK, fontFace: FONT_BODY, valign: "middle" });
});
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 17 – References
// ─────────────────────────────────────────────────────────────────────────
{
const slide = addContentSlide(pres, "References", 17, TOTAL, TEAL);
const refs = [
"Kumar V, Abbas A, Aster J. Robbins & Kumar Basic Pathology, 10th ed. Elsevier; 2023.",
"Feldman M, Friedman L, Brandt L. Sleisenger and Fordtran's Gastrointestinal and Liver Disease, 11th ed. Elsevier; 2021.",
"Banales JM, et al. Cholangiocarcinoma 2020: the next horizon in mechanisms and management. Nat Rev Gastroenterol Hepatol. 2020;17:557–588.",
"Oh DY, et al. Durvalumab plus Gemcitabine/Cisplatin in advanced biliary tract cancer (TOPAZ-1 trial). NEJM Evid. 2022.",
"NCI PDQ: Bile Duct Cancer (Cholangiocarcinoma) Treatment. cancer.gov. Accessed June 2026.",
"Abou-Alfa GK, et al. Ivosidenib in IDH1-mutant, chemotherapy-refractory cholangiocarcinoma. NEJM. 2020;382:2219–2227.",
"Abou-Alfa GK, et al. Pemigatinib for previously treated CCA with FGFR2 rearrangements. NEJM. 2020;383:1442–1454.",
"AJCC Cancer Staging Manual, 8th ed. Springer; 2017."
];
refs.forEach((ref, i) => {
const y = 1.05 + i * 0.53;
slide.addText(`${i + 1}. ${ref}`, {
x: 0.35, y, w: 9.3, h: 0.5, fontSize: 11, color: TEXT_DARK, fontFace: FONT_BODY, valign: "top", wrap: true
});
slide.addShape("rect", { x: 0.25, y: y + 0.46, w: 9.5, h: 0.02, fill: { color: "DDDDDD" }, line: { type: "none" } });
});
}
// ─────────────────────────────────────────────────────────────────────────
// SLIDE 18 – Thank You
// ─────────────────────────────────────────────────────────────────────────
{
const slide = pres.addSlide();
slide.addShape("rect", { x: 0, y: 0, w: 10, h: 5.625, fill: { color: DARK_BG }, line: { type: "none" } });
slide.addShape("rect", { x: 0, y: 2.5, w: 10, h: 0.08, fill: { color: TEAL }, line: { type: "none" } });
slide.addShape("rect", { x: 3.5, y: 1.0, w: 3.0, h: 0.06, fill: { color: GOLD }, line: { type: "none" } });
slide.addText("Thank You", {
x: 0.5, y: 1.2, w: 9, h: 1.0,
fontSize: 52, bold: true, color: WHITE, fontFace: FONT_TITLE, align: "center", valign: "middle"
});
slide.addText("For Your Attention", {
x: 0.5, y: 2.3, w: 9, h: 0.55,
fontSize: 20, color: TEAL, fontFace: FONT_BODY, align: "center", italic: true
});
slide.addText("Questions & Discussion Welcome", {
x: 0.5, y: 3.0, w: 9, h: 0.45,
fontSize: 16, color: GOLD, fontFace: FONT_BODY, align: "center"
});
slide.addText("Cholangiocarcinoma | 2nd Year MBBS | Department of Pathology | 2026", {
x: 0.5, y: 4.9, w: 9, h: 0.35,
fontSize: 11, color: SUBTEXT, fontFace: FONT_BODY, align: "center"
});
}
// ─── Save ────────────────────────────────────────────────────────────────
const outPath = "/home/daytona/workspace/cholangiocarcinoma-ppt/Cholangiocarcinoma_MBBS.pptx";
await pres.writeFile({ fileName: outPath });
console.log("Saved:", outPath);
}
buildPresentation().catch(err => { console.error(err); process.exit(1); });
cd /home/daytona/workspace/cholangiocarcinoma-ppt && node build.js 2>&1
~/cholangiocarcinoma-ppt/build.js
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/cholangiocarcinoma-ppt/build.js'
cd /home/daytona/workspace/cholangiocarcinoma-ppt && node build.js 2>&1
ls -lh /home/daytona/workspace/cholangiocarcinoma-ppt/Cholangiocarcinoma_MBBS.pptx
Cholangiocarcinoma MBBS
Presentation · PPTX
| # | Slide | Highlights |
|---|---|---|
| 1 | Title Slide | Deep navy background, gold accent, professional presenter block |
| 2 | Table of Contents | 12 topic cards, two-column layout |
| 3 | Introduction & Definition | What is CCA, epidemiology basics |
| 4 | Epidemiology | Two-column: US stats vs global/geographic data |
| 5 | Etiology & Risk Factors | Three card columns: Parasitic, Biliary, Metabolic + mnemonic "CHIPS" |
| 6 | Classification | Intrahepatic, Perihilar (Klatskin), Distal with % frequency; Bismuth-Corlette note |
| 7 | Pathogenesis | Visual flow-box diagram + molecular drivers (IDH1/2, FGFR2, KRAS, TP53) |
| 8 | Morphology & Histopathology | Gross + microscopic features; real Robbins pathology image embedded |
| 9 | Clinical Features | Three-column by location: intrahepatic, perihilar, distal |
| 10 | Diagnosis & Investigations | Labs, Imaging, Tissue Diagnosis — three card columns |
| 11 | TNM Staging | Full AJCC 8th edition table (T/N/M + overall stages) |
| 12 | Treatment | Surgical, Palliative, Systemic (Gem-Cis + durvalumab TOPAZ-1 trial) |
| 13 | Prognosis | Survival table by type + poor prognostic factors |
| 14 | Differential Diagnosis | 6 key differentials with distinguishing clues |
| 15 | Recent Advances | Targeted therapy table: FGFR2, IDH1, HER2, NTRK, PD-L1 |
| 16 | Key Points | 10 numbered exam-important takeaways |
| 17 | References | Robbins, Sleisenger, NEJM papers (TOPAZ-1, ivosidenib, pemigatinib) |
| 18 | Thank You | Dark elegant closing slide |
Thank u