make ppt on acid base balance in pictorial way
mkdir -p /home/daytona/workspace/acid-base-ppt && ls /home/daytona/workspace/acid-base-ppt/
~/acid-base-ppt/create_ppt.js
const pptxgen = require("pptxgenjs");
const pres = new pptxgen();
pres.layout = "LAYOUT_16x9";
pres.author = "Orris Medical";
pres.title = "Acid-Base Balance";
// ─────────────────────────────────────────────
// COLOR PALETTE
// Deep navy dominates, teal accent, amber highlight, white text
const C = {
navy: "0D2B45",
navyMid: "133A5E",
teal: "1A8A8C",
tealLight:"26B5B8",
amber: "F4A31A",
red: "E84040",
green: "2DBE6C",
blue: "2D7FBE",
purple: "7B5EA7",
white: "FFFFFF",
offWhite: "EDF2F7",
lightGray:"C8D6E5",
darkGray: "1C2E40",
acidRed: "D63031",
alkBlue: "0984E3",
neutralG: "00B894",
};
// ─────────────────────────────────────────────
// HELPER FUNCTIONS
function bgFill(slide, color) {
slide.background = { fill: color };
}
function addHeader(slide, title, subtitle) {
// Decorative top bar
slide.addShape(pres.ShapeType.rect, {
x: 0, y: 0, w: "100%", h: 0.08,
fill: { color: C.amber }, line: { width: 0 }
});
slide.addText(title, {
x: 0.4, y: 0.15, w: 9.2, h: 0.65,
fontSize: 28, bold: true, color: C.white, fontFace: "Calibri",
align: "left", margin: 0
});
if (subtitle) {
slide.addText(subtitle, {
x: 0.4, y: 0.8, w: 9.2, h: 0.35,
fontSize: 14, color: C.lightGray, fontFace: "Calibri",
align: "left", italic: true, margin: 0
});
}
// Divider line
slide.addShape(pres.ShapeType.rect, {
x: 0.4, y: 1.15, w: 9.2, h: 0.03,
fill: { color: C.teal }, line: { width: 0 }
});
}
function pill(slide, txt, x, y, w, h, bgColor, txtColor) {
slide.addShape(pres.ShapeType.roundRect, {
x, y, w, h,
fill: { color: bgColor },
line: { color: C.white, width: 1 },
rectRadius: 0.12
});
slide.addText(txt, {
x, y, w, h,
fontSize: 11, bold: true, color: txtColor || C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
}
function iconCircle(slide, letter, x, y, r, color) {
slide.addShape(pres.ShapeType.ellipse, {
x, y, w: r, h: r,
fill: { color: color }, line: { color: C.white, width: 1.5 }
});
slide.addText(letter, {
x, y, w: r, h: r,
fontSize: 18, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
}
function arrowRight(slide, x, y, w, color) {
slide.addShape(pres.ShapeType.rightArrow, {
x, y, w, h: 0.35,
fill: { color: color }, line: { color: color, width: 0 }
});
}
// ─────────────────────────────────────────────
// SLIDE 1 — TITLE
// ─────────────────────────────────────────────
{
const s = pres.addSlide();
bgFill(s, C.navy);
// Left color block
s.addShape(pres.ShapeType.rect, {
x: 0, y: 0, w: 0.35, h: "100%",
fill: { color: C.teal }, line: { width: 0 }
});
// Bottom band
s.addShape(pres.ShapeType.rect, {
x: 0, y: 4.8, w: "100%", h: 0.82,
fill: { color: C.navyMid }, line: { width: 0 }
});
// Big pH scale bar
const barX = 1.2, barY = 1.05, barW = 7.6, barH = 0.55;
// gradient simulation with multiple rects
const segments = [
[C.acidRed, "1"],
["C0392B", "2"],
["E67E22", "3"],
["F39C12", "4"],
["F1C40F", "5"],
["D4E009", "6"],
[C.neutralG, "7"],
["27AE60", "8"],
["2ECC71", "9"],
[C.alkBlue, "10"],
["1565C0", "11"],
["0D47A1", "12"],
["4A148C", "13"],
["311B92", "14"],
];
const sw = barW / segments.length;
segments.forEach(([col, lbl], i) => {
s.addShape(pres.ShapeType.rect, {
x: barX + i * sw, y: barY, w: sw, h: barH,
fill: { color: col }, line: { width: 0 }
});
s.addText(lbl, {
x: barX + i * sw, y: barY + barH + 0.05, w: sw, h: 0.25,
fontSize: 9, color: C.lightGray, align: "center", fontFace: "Calibri", margin: 0
});
});
// Arrow pointing to blood pH zone
s.addShape(pres.ShapeType.downArrow, {
x: barX + 6 * sw - 0.05, y: barY - 0.55, w: 0.45, h: 0.5,
fill: { color: C.amber }, line: { width: 0 }
});
s.addText("Blood pH\n7.35-7.45", {
x: barX + 5.6 * sw, y: barY - 1.0, w: 1.2, h: 0.45,
fontSize: 10, bold: true, color: C.amber,
align: "center", fontFace: "Calibri", margin: 0
});
// Labels
s.addText("ACID", {
x: barX - 0.05, y: barY + barH + 0.35, w: 1.2, h: 0.28,
fontSize: 11, bold: true, color: C.acidRed, fontFace: "Calibri", margin: 0
});
s.addText("NEUTRAL", {
x: barX + 2.9, y: barY + barH + 0.35, w: 1.6, h: 0.28,
fontSize: 11, bold: true, color: C.neutralG, align: "center", fontFace: "Calibri", margin: 0
});
s.addText("ALKALI", {
x: barX + 6.2, y: barY + barH + 0.35, w: 1.2, h: 0.28,
fontSize: 11, bold: true, color: C.alkBlue, align: "right", fontFace: "Calibri", margin: 0
});
// Main title
s.addText("ACID–BASE BALANCE", {
x: 0.55, y: 2.55, w: 8.9, h: 0.85,
fontSize: 46, bold: true, color: C.white,
align: "center", fontFace: "Calibri", charSpacing: 3, margin: 0
});
s.addText("Physiology · Disorders · Compensation · Clinical Approach", {
x: 0.55, y: 3.45, w: 8.9, h: 0.38,
fontSize: 16, color: C.lightGray, italic: true,
align: "center", fontFace: "Calibri", margin: 0
});
// Footer
s.addText("Source: Guyton & Hall • Lippincott Biochemistry • Roberts & Hedges Emergency Medicine", {
x: 0.4, y: 5.0, w: 9.2, h: 0.28,
fontSize: 9, color: C.lightGray, align: "center", fontFace: "Calibri", margin: 0
});
}
// ─────────────────────────────────────────────
// SLIDE 2 — NORMAL BLOOD pH & HENDERSON-HASSELBALCH
// ─────────────────────────────────────────────
{
const s = pres.addSlide();
bgFill(s, C.navy);
addHeader(s, "Normal Blood pH & Henderson–Hasselbalch Equation", "The foundation of acid-base physiology");
// Central equation box
s.addShape(pres.ShapeType.roundRect, {
x: 1.2, y: 1.35, w: 7.6, h: 1.1,
fill: { color: C.navyMid }, line: { color: C.amber, width: 2 },
rectRadius: 0.15
});
s.addText("pH = pKa + log ( [HCO₃⁻] / [CO₂] )", {
x: 1.2, y: 1.35, w: 7.6, h: 1.1,
fontSize: 26, bold: true, color: C.amber,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// Three column icons
const cols = [
{ label: "[HCO₃⁻]", val: "24 mEq/L", sub: "Regulated by\nKidneys", color: C.blue, x: 1.0 },
{ label: "pH", val: "7.35–7.45", sub: "Normal\nBlood pH", color: C.neutralG, x: 3.9 },
{ label: "PCO₂", val: "35–45 mmHg", sub: "Regulated by\nLungs", color: C.teal, x: 6.8 },
];
cols.forEach(col => {
// Circle
s.addShape(pres.ShapeType.ellipse, {
x: col.x, y: 2.7, w: 1.5, h: 1.5,
fill: { color: col.color }, line: { color: C.white, width: 2 }
});
s.addText(col.label + "\n" + col.val, {
x: col.x, y: 2.7, w: 1.5, h: 1.5,
fontSize: 11, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// Subtitle
s.addText(col.sub, {
x: col.x, y: 4.28, w: 1.5, h: 0.65,
fontSize: 11, color: C.lightGray,
align: "center", fontFace: "Calibri", margin: 0
});
});
// Ratio label
s.addText("20 : 1 = Normal HCO₃⁻ : CO₂ ratio → pH 7.40", {
x: 1.2, y: 5.05, w: 7.6, h: 0.38,
fontSize: 13, color: C.lightGray, align: "center", italic: true,
fontFace: "Calibri", margin: 0
});
}
// ─────────────────────────────────────────────
// SLIDE 3 — BODY BUFFER SYSTEMS (PICTORIAL)
// ─────────────────────────────────────────────
{
const s = pres.addSlide();
bgFill(s, C.navy);
addHeader(s, "Three Lines of Defense: Buffer Systems", "The body corrects pH in seconds → minutes → hours → days");
// Three large columns as shields / banners
const defenses = [
{
num: "1st", time: "Seconds", icon: "⚗",
title: "Chemical Buffers",
items: ["Bicarbonate (HCO₃⁻/H₂CO₃)", "Phosphate (HPO₄²⁻/H₂PO₄⁻)", "Proteins & Hemoglobin"],
color: C.teal, x: 0.3
},
{
num: "2nd", time: "3–12 min", icon: "🫁",
title: "Respiratory System",
items: ["↑ H⁺ → ↑ ventilation", "↑ CO₂ exhaled → ↓ H⁺", "50–75% correction"],
color: C.blue, x: 3.5
},
{
num: "3rd", time: "Hours–Days", icon: "🫘",
title: "Renal System",
items: ["Excretes H⁺ in distal tubule", "Reabsorbs HCO₃⁻ proximally", "Complete correction possible"],
color: C.purple, x: 6.7
},
];
defenses.forEach(d => {
// Card background
s.addShape(pres.ShapeType.roundRect, {
x: d.x, y: 1.3, w: 2.9, h: 3.85,
fill: { color: C.navyMid }, line: { color: d.color, width: 2 },
rectRadius: 0.18
});
// Color header band
s.addShape(pres.ShapeType.roundRect, {
x: d.x, y: 1.3, w: 2.9, h: 0.75,
fill: { color: d.color }, line: { width: 0 },
rectRadius: 0.18
});
// fix bottom corners of color header
s.addShape(pres.ShapeType.rect, {
x: d.x, y: 1.7, w: 2.9, h: 0.35,
fill: { color: d.color }, line: { width: 0 }
});
// Number badge
s.addShape(pres.ShapeType.ellipse, {
x: d.x + 0.05, y: 1.33, w: 0.55, h: 0.55,
fill: { color: C.amber }, line: { color: C.white, width: 1 }
});
s.addText(d.num, {
x: d.x + 0.05, y: 1.33, w: 0.55, h: 0.55,
fontSize: 11, bold: true, color: C.navy,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// Title
s.addText(d.title, {
x: d.x + 0.1, y: 1.35, w: 2.7, h: 0.7,
fontSize: 13, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// Time pill
pill(s, "⏱ " + d.time, d.x + 0.55, 2.12, 1.8, 0.3, C.darkGray, C.amber);
// Bullet items
d.items.forEach((item, i) => {
s.addShape(pres.ShapeType.ellipse, {
x: d.x + 0.18, y: 2.58 + i * 0.6, w: 0.22, h: 0.22,
fill: { color: d.color }, line: { width: 0 }
});
s.addText(item, {
x: d.x + 0.48, y: 2.55 + i * 0.6, w: 2.3, h: 0.3,
fontSize: 11, color: C.offWhite, fontFace: "Calibri", valign: "middle", margin: 0
});
});
});
// Bottom note
s.addText("Chemical buffers act instantly but incompletely. Respiratory response is fast but partial. Only kidneys restore full pH.", {
x: 0.3, y: 5.1, w: 9.4, h: 0.35,
fontSize: 10, color: C.lightGray, italic: true, align: "center",
fontFace: "Calibri", margin: 0
});
}
// ─────────────────────────────────────────────
// SLIDE 4 — THE 4 ACID-BASE DISORDERS (QUADRANT)
// ─────────────────────────────────────────────
{
const s = pres.addSlide();
bgFill(s, C.navy);
addHeader(s, "The 4 Primary Acid-Base Disorders", "Classified by origin (metabolic vs respiratory) and pH direction");
// Center cross
s.addShape(pres.ShapeType.rect, {
x: 4.85, y: 1.3, w: 0.06, h: 4.0,
fill: { color: C.lightGray }, line: { width: 0 }
});
s.addShape(pres.ShapeType.rect, {
x: 0.3, y: 3.3, w: 9.4, h: 0.06,
fill: { color: C.lightGray }, line: { width: 0 }
});
// Axis labels
s.addText("↓ pH (Acidosis)", {
x: 0.3, y: 3.4, w: 2.5, h: 0.3,
fontSize: 11, bold: true, color: C.acidRed, fontFace: "Calibri", margin: 0
});
s.addText("↑ pH (Alkalosis) →", {
x: 7.2, y: 3.4, w: 2.5, h: 0.3,
fontSize: 11, bold: true, color: C.alkBlue, fontFace: "Calibri", align: "right", margin: 0
});
s.addText("METABOLIC", {
x: 0.3, y: 1.3, w: 2.5, h: 0.3,
fontSize: 11, bold: true, color: C.lightGray, fontFace: "Calibri", margin: 0
});
s.addText("RESPIRATORY", {
x: 0.3, y: 4.8, w: 2.5, h: 0.3,
fontSize: 11, bold: true, color: C.lightGray, fontFace: "Calibri", margin: 0
});
// Quadrant data
const quads = [
{
title: "Metabolic\nACIDOSIS",
abbr: "↓ HCO₃⁻",
causes: ["Diarrhea", "DKA / AKA", "Lactic acidosis", "Renal failure", "Salicylate OD"],
comp: "↑ Ventilation\n(Kussmaul breathing)",
color: C.acidRed, x: 0.35, y: 1.35
},
{
title: "Metabolic\nALKALOSIS",
abbr: "↑ HCO₃⁻",
causes: ["Vomiting", "Diuretics", "Hyperaldosteronism", "Antacid excess"],
comp: "↓ Ventilation\n(hypoventilation)",
color: C.alkBlue, x: 5.0, y: 1.35
},
{
title: "Respiratory\nACIDOSIS",
abbr: "↑ PCO₂",
causes: ["COPD", "Opioids/sedation", "Neuromuscular dx", "Pneumonia"],
comp: "↑ Renal HCO₃⁻ retention",
color: "#C0392B", x: 0.35, y: 3.45
},
{
title: "Respiratory\nALKALOSIS",
abbr: "↓ PCO₂",
causes: ["Anxiety / pain", "High altitude", "PE", "Mechanical ventilation"],
comp: "↓ Renal HCO₃⁻ retention",
color: C.tealLight, x: 5.0, y: 3.45
},
];
quads.forEach(q => {
// Card
s.addShape(pres.ShapeType.roundRect, {
x: q.x, y: q.y, w: 4.35, h: 1.8,
fill: { color: C.navyMid }, line: { color: q.color, width: 2 },
rectRadius: 0.14
});
// Top color bar
s.addShape(pres.ShapeType.roundRect, {
x: q.x, y: q.y, w: 4.35, h: 0.45,
fill: { color: q.color }, line: { width: 0 }, rectRadius: 0.14
});
s.addShape(pres.ShapeType.rect, {
x: q.x, y: q.y + 0.2, w: 4.35, h: 0.25,
fill: { color: q.color }, line: { width: 0 }
});
s.addText(q.title + " " + q.abbr, {
x: q.x + 0.1, y: q.y, w: 4.1, h: 0.45,
fontSize: 12, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// Causes
const causeTxt = q.causes.map(c => "• " + c).join(" ");
s.addText(causeTxt, {
x: q.x + 0.1, y: q.y + 0.5, w: 4.1, h: 0.6,
fontSize: 9.5, color: C.offWhite, fontFace: "Calibri",
wrap: true, margin: 2
});
// Compensation
s.addText("Compensation: " + q.comp, {
x: q.x + 0.1, y: q.y + 1.15, w: 4.1, h: 0.55,
fontSize: 9.5, color: C.amber, fontFace: "Calibri", italic: true,
wrap: true, margin: 2
});
});
}
// ─────────────────────────────────────────────
// SLIDE 5 — RESPIRATORY REGULATION (VISUAL)
// ─────────────────────────────────────────────
{
const s = pres.addSlide();
bgFill(s, C.navy);
addHeader(s, "Respiratory Regulation of pH", "Lungs respond within 3–12 minutes via chemoreceptors");
// Big lung silhouette via shapes
const lx = 1.0, ly = 1.4;
// Left "lung" shape
s.addShape(pres.ShapeType.ellipse, {
x: lx, y: ly, w: 1.5, h: 2.8,
fill: { color: C.blue }, line: { color: C.tealLight, width: 2 }
});
// Right "lung" shape
s.addShape(pres.ShapeType.ellipse, {
x: lx + 1.7, y: ly, w: 1.6, h: 2.8,
fill: { color: C.blue }, line: { color: C.tealLight, width: 2 }
});
// Trachea
s.addShape(pres.ShapeType.rect, {
x: lx + 1.35, y: ly - 0.6, w: 0.3, h: 0.65,
fill: { color: C.tealLight }, line: { width: 0 }
});
s.addText("LUNGS", {
x: lx, y: ly + 1.1, w: 3.3, h: 0.5,
fontSize: 14, bold: true, color: C.white,
align: "center", fontFace: "Calibri", margin: 0
});
s.addText("CO₂ + H₂O ⇌ H₂CO₃ ⇌ H⁺ + HCO₃⁻", {
x: lx, y: ly + 1.65, w: 3.3, h: 0.5,
fontSize: 9, color: C.lightGray,
align: "center", fontFace: "Calibri", margin: 0
});
// Flow diagram: two feedback loops
// ACIDOSIS path (top)
s.addShape(pres.ShapeType.rect, {
x: 4.5, y: 1.4, w: 2.3, h: 0.55,
fill: { color: C.acidRed }, line: { color: C.white, width: 1 }
});
s.addText("↑ H⁺ / ↓ pH", {
x: 4.5, y: 1.4, w: 2.3, h: 0.55,
fontSize: 12, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
arrowRight(s, 6.88, 1.55, 0.45, C.white);
s.addShape(pres.ShapeType.rect, {
x: 7.4, y: 1.4, w: 2.2, h: 0.55,
fill: { color: C.navyMid }, line: { color: C.acidRed, width: 1.5 }
});
s.addText("Stimulates\nchemoreceptors", {
x: 7.4, y: 1.4, w: 2.2, h: 0.55,
fontSize: 10, color: C.lightGray,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// Arrow down
s.addShape(pres.ShapeType.downArrow, {
x: 8.3, y: 2.03, w: 0.4, h: 0.35,
fill: { color: C.amber }, line: { width: 0 }
});
s.addShape(pres.ShapeType.rect, {
x: 7.4, y: 2.38, w: 2.2, h: 0.55,
fill: { color: C.navyMid }, line: { color: C.amber, width: 1.5 }
});
s.addText("↑ Ventilation rate\n(Kussmaul breathing)", {
x: 7.4, y: 2.38, w: 2.2, h: 0.55,
fontSize: 10, color: C.amber,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
s.addShape(pres.ShapeType.downArrow, {
x: 8.3, y: 3.0, w: 0.4, h: 0.35,
fill: { color: C.neutralG }, line: { width: 0 }
});
s.addShape(pres.ShapeType.rect, {
x: 7.4, y: 3.38, w: 2.2, h: 0.55,
fill: { color: C.neutralG }, line: { width: 0 }
});
s.addText("↑ CO₂ exhaled\n→ ↓ H⁺ → ↑ pH", {
x: 7.4, y: 3.38, w: 2.2, h: 0.55,
fontSize: 10, bold: true, color: C.navy,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// ALKALOSIS path (bottom)
s.addShape(pres.ShapeType.rect, {
x: 4.5, y: 4.15, w: 2.3, h: 0.55,
fill: { color: C.alkBlue }, line: { color: C.white, width: 1 }
});
s.addText("↓ H⁺ / ↑ pH", {
x: 4.5, y: 4.15, w: 2.3, h: 0.55,
fontSize: 12, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
arrowRight(s, 6.88, 4.3, 0.45, C.white);
s.addShape(pres.ShapeType.rect, {
x: 7.4, y: 4.15, w: 2.2, h: 0.55,
fill: { color: C.navyMid }, line: { color: C.alkBlue, width: 1.5 }
});
s.addText("↓ Ventilation\n(Hypoventilation)", {
x: 7.4, y: 4.15, w: 2.2, h: 0.55,
fontSize: 10, color: C.lightGray,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// Efficiency note
s.addShape(pres.ShapeType.roundRect, {
x: 4.5, y: 2.85, w: 2.5, h: 0.85,
fill: { color: C.navyMid }, line: { color: C.teal, width: 1.5 },
rectRadius: 0.12
});
s.addText("Efficiency: 50–75%\nTime: 3–12 minutes", {
x: 4.5, y: 2.85, w: 2.5, h: 0.85,
fontSize: 11, color: C.tealLight, bold: true,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
}
// ─────────────────────────────────────────────
// SLIDE 6 — RENAL REGULATION
// ─────────────────────────────────────────────
{
const s = pres.addSlide();
bgFill(s, C.navy);
addHeader(s, "Renal Regulation of pH", "Kidneys provide the slowest but most complete correction");
// Nephron schematic (simplified shapes)
const nx = 0.5, ny = 1.35;
// Glomerulus
s.addShape(pres.ShapeType.ellipse, {
x: nx, y: ny, w: 0.8, h: 0.8,
fill: { color: C.teal }, line: { color: C.white, width: 1.5 }
});
s.addText("GFR", {
x: nx, y: ny, w: 0.8, h: 0.8,
fontSize: 9, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// PCT tube
s.addShape(pres.ShapeType.rect, {
x: nx + 0.95, y: ny + 0.25, w: 1.6, h: 0.35,
fill: { color: C.blue }, line: { color: C.white, width: 1 }
});
s.addText("Proximal Tubule", {
x: nx + 0.95, y: ny + 0.25, w: 1.6, h: 0.35,
fontSize: 8.5, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// DCT tube
s.addShape(pres.ShapeType.rect, {
x: nx + 0.95, y: ny + 1.2, w: 1.6, h: 0.35,
fill: { color: C.purple }, line: { color: C.white, width: 1 }
});
s.addText("Distal Tubule", {
x: nx + 0.95, y: ny + 1.2, w: 1.6, h: 0.35,
fontSize: 8.5, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// Collecting duct
s.addShape(pres.ShapeType.rect, {
x: nx + 0.95, y: ny + 2.1, w: 1.6, h: 0.35,
fill: { color: C.tealLight }, line: { color: C.white, width: 1 }
});
s.addText("Collecting Duct", {
x: nx + 0.95, y: ny + 2.1, w: 1.6, h: 0.35,
fontSize: 8.5, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// Vertical connector
s.addShape(pres.ShapeType.rect, {
x: nx + 1.65, y: ny + 0.6, w: 0.06, h: 2.0,
fill: { color: C.lightGray }, line: { width: 0 }
});
// Function labels
const funcs = [
{ txt: "Reabsorbs 80-90% HCO₃⁻\nvia Na⁺/H⁺ exchanger", x: 3.0, y: ny + 0.2, color: C.blue },
{ txt: "Secretes H⁺ (titratable acids)\nReabsorbs remaining HCO₃⁻", x: 3.0, y: ny + 1.1, color: C.purple },
{ txt: "Secretes NH₄⁺\nFinal H⁺ excretion", x: 3.0, y: ny + 2.0, color: C.tealLight },
];
funcs.forEach(f => {
s.addShape(pres.ShapeType.roundRect, {
x: f.x, y: f.y, w: 3.3, h: 0.6,
fill: { color: C.navyMid }, line: { color: f.color, width: 1.5 },
rectRadius: 0.1
});
s.addText(f.txt, {
x: f.x, y: f.y, w: 3.3, h: 0.6,
fontSize: 10, color: C.offWhite, fontFace: "Calibri",
align: "center", valign: "middle", margin: 0
});
});
// Summary boxes right side
const boxes = [
{ title: "Acidosis Response", items: ["↑ H⁺ secretion", "↑ HCO₃⁻ reabsorption", "↑ NH₄⁺ excretion", "More acidic urine (pH < 5.5)"], color: C.acidRed, x: 6.5, y: 1.35 },
{ title: "Alkalosis Response", items: ["↓ H⁺ secretion", "↓ HCO₃⁻ reabsorption", "HCO₃⁻ excreted in urine", "More alkaline urine (pH > 7.0)"], color: C.alkBlue, x: 6.5, y: 3.3 },
];
boxes.forEach(b => {
s.addShape(pres.ShapeType.roundRect, {
x: b.x, y: b.y, w: 3.1, h: 1.75,
fill: { color: C.navyMid }, line: { color: b.color, width: 2 },
rectRadius: 0.15
});
s.addShape(pres.ShapeType.roundRect, {
x: b.x, y: b.y, w: 3.1, h: 0.4,
fill: { color: b.color }, line: { width: 0 }, rectRadius: 0.15
});
s.addShape(pres.ShapeType.rect, {
x: b.x, y: b.y + 0.2, w: 3.1, h: 0.2,
fill: { color: b.color }, line: { width: 0 }
});
s.addText(b.title, {
x: b.x, y: b.y, w: 3.1, h: 0.4,
fontSize: 12, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
b.items.forEach((item, i) => {
s.addShape(pres.ShapeType.ellipse, {
x: b.x + 0.15, y: b.y + 0.52 + i * 0.32, w: 0.18, h: 0.18,
fill: { color: b.color }, line: { width: 0 }
});
s.addText(item, {
x: b.x + 0.42, y: b.y + 0.49 + i * 0.32, w: 2.6, h: 0.28,
fontSize: 10, color: C.offWhite, fontFace: "Calibri", valign: "middle", margin: 0
});
});
});
}
// ─────────────────────────────────────────────
// SLIDE 7 — ABG INTERPRETATION ALGORITHM
// ─────────────────────────────────────────────
{
const s = pres.addSlide();
bgFill(s, C.navy);
addHeader(s, "Step-by-Step ABG Interpretation", "Systematic 5-step approach to any blood gas");
const steps = [
{ n: "1", q: "Check pH", lo: "< 7.35 → Acidosis", hi: "> 7.45 → Alkalosis", color: C.acidRed },
{ n: "2", q: "Check PCO₂", lo: "> 45 → Resp Acidosis", hi: "< 35 → Resp Alkalosis", color: C.teal },
{ n: "3", q: "Check HCO₃⁻", lo: "< 22 → Met Acidosis", hi: "> 26 → Met Alkalosis", color: C.blue },
{ n: "4", q: "Primary disorder?", lo: "Match pH with PCO₂ or HCO₃⁻ change", hi: "", color: C.purple },
{ n: "5", q: "Compensation?", lo: "Calculate expected compensation", hi: "Compare with measured value", color: C.amber },
];
steps.forEach((st, i) => {
const x = 0.3, y = 1.3 + i * 0.82, w = 9.4, h = 0.72;
s.addShape(pres.ShapeType.roundRect, {
x, y, w, h,
fill: { color: C.navyMid }, line: { color: st.color, width: 1.5 },
rectRadius: 0.12
});
// Step badge
s.addShape(pres.ShapeType.ellipse, {
x: x + 0.1, y: y + 0.1, w: 0.52, h: 0.52,
fill: { color: st.color }, line: { width: 0 }
});
s.addText(st.n, {
x: x + 0.1, y: y + 0.1, w: 0.52, h: 0.52,
fontSize: 14, bold: true, color: C.navy,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// Question
s.addText(st.q, {
x: x + 0.75, y, w: 2.5, h,
fontSize: 13, bold: true, color: C.white,
fontFace: "Calibri", valign: "middle", margin: 0
});
// Low
pill(s, st.lo, x + 3.4, y + 0.18, 2.9, 0.38, C.darkGray, C.lightGray);
// High
if (st.hi) pill(s, st.hi, x + 6.4, y + 0.18, 2.9, 0.38, C.darkGray, C.lightGray);
});
// Normal reference box
s.addShape(pres.ShapeType.roundRect, {
x: 0.3, y: 5.2, w: 9.4, h: 0.27,
fill: { color: C.teal }, line: { width: 0 }, rectRadius: 0.08
});
s.addText("Normal: pH 7.35–7.45 | PCO₂ 35–45 mmHg | HCO₃⁻ 22–26 mEq/L | PO₂ 75–100 mmHg | SaO₂ ≥95%", {
x: 0.3, y: 5.2, w: 9.4, h: 0.27,
fontSize: 10, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
}
// ─────────────────────────────────────────────
// SLIDE 8 — ANION GAP
// ─────────────────────────────────────────────
{
const s = pres.addSlide();
bgFill(s, C.navy);
addHeader(s, "Anion Gap — Classifying Metabolic Acidosis", "AG = Na⁺ − (Cl⁻ + HCO₃⁻) Normal: 8–12 mEq/L");
// Two large columns
// HIGH AG column
s.addShape(pres.ShapeType.roundRect, {
x: 0.3, y: 1.35, w: 4.4, h: 3.9,
fill: { color: C.navyMid }, line: { color: C.acidRed, width: 2.5 },
rectRadius: 0.18
});
s.addShape(pres.ShapeType.roundRect, {
x: 0.3, y: 1.35, w: 4.4, h: 0.5,
fill: { color: C.acidRed }, line: { width: 0 }, rectRadius: 0.18
});
s.addShape(pres.ShapeType.rect, {
x: 0.3, y: 1.6, w: 4.4, h: 0.25,
fill: { color: C.acidRed }, line: { width: 0 }
});
s.addText("HIGH Anion Gap (> 12)", {
x: 0.3, y: 1.35, w: 4.4, h: 0.5,
fontSize: 13, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
// MUDPILES
pill(s, "MUDPILES Mnemonic", 0.6, 1.95, 3.8, 0.32, C.darkGray, C.amber);
const mudpiles = [
["M", "Methanol"],
["U", "Uremia"],
["D", "DKA"],
["P", "Propylene glycol"],
["I", "INH / Iron"],
["L", "Lactic acidosis"],
["E", "Ethylene glycol"],
["S", "Salicylates"],
];
mudpiles.forEach(([letter, name], i) => {
const col = i < 4 ? 0 : 1;
const row = i % 4;
s.addShape(pres.ShapeType.ellipse, {
x: 0.5 + col * 2.1, y: 2.38 + row * 0.56, w: 0.35, h: 0.35,
fill: { color: C.acidRed }, line: { width: 0 }
});
s.addText(letter, {
x: 0.5 + col * 2.1, y: 2.38 + row * 0.56, w: 0.35, h: 0.35,
fontSize: 11, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
s.addText(name, {
x: 0.95 + col * 2.1, y: 2.4 + row * 0.56, w: 1.6, h: 0.3,
fontSize: 11, color: C.offWhite, fontFace: "Calibri", valign: "middle", margin: 0
});
});
// NORMAL AG column
s.addShape(pres.ShapeType.roundRect, {
x: 5.0, y: 1.35, w: 4.4, h: 3.9,
fill: { color: C.navyMid }, line: { color: C.blue, width: 2.5 },
rectRadius: 0.18
});
s.addShape(pres.ShapeType.roundRect, {
x: 5.0, y: 1.35, w: 4.4, h: 0.5,
fill: { color: C.blue }, line: { width: 0 }, rectRadius: 0.18
});
s.addShape(pres.ShapeType.rect, {
x: 5.0, y: 1.6, w: 4.4, h: 0.25,
fill: { color: C.blue }, line: { width: 0 }
});
s.addText("NORMAL Anion Gap (8–12)", {
x: 5.0, y: 1.35, w: 4.4, h: 0.5,
fontSize: 13, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
pill(s, "HARDUP Mnemonic", 5.3, 1.95, 3.8, 0.32, C.darkGray, C.amber);
const hardup = [
["H", "Hyperalimentation"],
["A", "Addison's disease"],
["R", "Renal tubular acidosis"],
["D", "Diarrhea"],
["U", "Ureterosigmoid / ureteral diversion"],
["P", "Pancreatic fistula"],
];
hardup.forEach(([letter, name], i) => {
s.addShape(pres.ShapeType.ellipse, {
x: 5.2, y: 2.38 + i * 0.52, w: 0.35, h: 0.35,
fill: { color: C.blue }, line: { width: 0 }
});
s.addText(letter, {
x: 5.2, y: 2.38 + i * 0.52, w: 0.35, h: 0.35,
fontSize: 11, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
s.addText(name, {
x: 5.65, y: 2.4 + i * 0.52, w: 3.5, h: 0.3,
fontSize: 10.5, color: C.offWhite, fontFace: "Calibri", valign: "middle", margin: 0
});
});
// Hyperchloremic note
s.addText("Normal AG acidosis = Hyperchloremic acidosis (Cl⁻ replaces lost HCO₃⁻)", {
x: 0.3, y: 5.2, w: 9.4, h: 0.28,
fontSize: 10, color: C.lightGray, italic: true, align: "center",
fontFace: "Calibri", margin: 0
});
}
// ─────────────────────────────────────────────
// SLIDE 9 — COMPENSATION FORMULAS
// ─────────────────────────────────────────────
{
const s = pres.addSlide();
bgFill(s, C.navy);
addHeader(s, "Compensation Formulas — Quick Reference", "Expected compensatory response for each primary disorder");
const rows = [
{ disorder: "Metabolic Acidosis", primary: "↓ HCO₃⁻", comp: "↓ PCO₂", formula: "Expected PCO₂ = 1.5 × HCO₃⁻ + 8 ± 2\n(Winters formula)", color: C.acidRed },
{ disorder: "Metabolic Alkalosis", primary: "↑ HCO₃⁻", comp: "↑ PCO₂", formula: "Expected PCO₂ = 0.6 × ΔHCO₃⁻ + 40", color: C.alkBlue },
{ disorder: "Respiratory Acidosis (Acute)", primary: "↑ PCO₂", comp: "↑ HCO₃⁻", formula: "ΔHCO₃⁻ = +1 per 10 mmHg ↑ PCO₂", color: C.acidRed },
{ disorder: "Respiratory Acidosis (Chronic)", primary: "↑ PCO₂", comp: "↑ HCO₃⁻", formula: "ΔHCO₃⁻ = +4 per 10 mmHg ↑ PCO₂", color: "#C0392B" },
{ disorder: "Respiratory Alkalosis (Acute)", primary: "↓ PCO₂", comp: "↓ HCO₃⁻", formula: "ΔHCO₃⁻ = −2 per 10 mmHg ↓ PCO₂", color: C.alkBlue },
{ disorder: "Respiratory Alkalosis (Chronic)", primary: "↓ PCO₂", comp: "↓ HCO₃⁻", formula: "ΔHCO₃⁻ = −5 per 10 mmHg ↓ PCO₂", color: C.tealLight },
];
rows.forEach((r, i) => {
const y = 1.3 + i * 0.68;
s.addShape(pres.ShapeType.roundRect, {
x: 0.3, y, w: 9.4, h: 0.6,
fill: { color: C.navyMid }, line: { color: r.color, width: 1 },
rectRadius: 0.1
});
// Color left accent
s.addShape(pres.ShapeType.roundRect, {
x: 0.3, y, w: 0.18, h: 0.6,
fill: { color: r.color }, line: { width: 0 }, rectRadius: 0.08
});
s.addText(r.disorder, {
x: 0.6, y, w: 2.7, h: 0.6,
fontSize: 11, bold: true, color: C.white, fontFace: "Calibri",
valign: "middle", margin: 0
});
pill(s, r.primary, 3.45, y + 0.13, 0.85, 0.33, r.color, C.white);
s.addShape(pres.ShapeType.rightArrow, {
x: 4.38, y: y + 0.18, w: 0.35, h: 0.25,
fill: { color: C.lightGray }, line: { width: 0 }
});
pill(s, r.comp, 4.8, y + 0.13, 0.85, 0.33, C.darkGray, C.amber);
s.addText(r.formula, {
x: 5.8, y, w: 3.8, h: 0.6,
fontSize: 9.5, color: C.lightGray, fontFace: "Calibri",
valign: "middle", margin: 0
});
});
s.addText("If measured compensation ≠ expected → Mixed acid-base disorder", {
x: 0.3, y: 5.32, w: 9.4, h: 0.26,
fontSize: 10, color: C.amber, bold: true, align: "center",
fontFace: "Calibri", margin: 0
});
}
// ─────────────────────────────────────────────
// SLIDE 10 — METABOLIC ALKALOSIS CAUSES & TREATMENT
// ─────────────────────────────────────────────
{
const s = pres.addSlide();
bgFill(s, C.navy);
addHeader(s, "Metabolic Alkalosis — Causes & Management", "↑ HCO₃⁻ → pH > 7.45 | Compensatory hypoventilation");
// Two halves
const causes = [
{ cat: "H⁺ Loss", items: ["Vomiting / NG suction", "H. pylori", "Congenital Cl⁻ diarrhea"] },
{ cat: "↑ HCO₃⁻ load", items: ["Bicarbonate infusion", "Milk-alkali syndrome", "Massive transfusion (citrate)"] },
{ cat: "Volume / Cl⁻ Depletion", items: ["Loop / thiazide diuretics", "Hypomagnesemia"] },
{ cat: "Mineralocorticoid excess", items: ["Primary hyperaldosteronism", "Cushing's syndrome"] },
];
const treatment = [
{ label: "Chloride-responsive\n(Cl⁻ < 20 mEq/L)", items: ["IV Normal Saline 0.9%", "Correct hypokalemia", "Stop diuretics / NG losses"], color: C.teal },
{ label: "Chloride-resistant\n(Cl⁻ > 20 mEq/L)", items: ["Treat underlying cause", "Aldosterone antagonists", "Surgical for adenoma"], color: C.purple },
];
causes.forEach((c, i) => {
const col = i % 2, row = Math.floor(i / 2);
const x = 0.3 + col * 2.55, y = 1.35 + row * 1.35;
s.addShape(pres.ShapeType.roundRect, {
x, y, w: 2.35, h: 1.25,
fill: { color: C.navyMid }, line: { color: C.alkBlue, width: 1.5 },
rectRadius: 0.12
});
s.addText(c.cat, {
x, y: y + 0.06, w: 2.35, h: 0.35,
fontSize: 11, bold: true, color: C.alkBlue,
align: "center", fontFace: "Calibri", margin: 0
});
c.items.forEach((item, j) => {
s.addText("• " + item, {
x: x + 0.1, y: y + 0.42 + j * 0.27, w: 2.15, h: 0.25,
fontSize: 9.5, color: C.offWhite, fontFace: "Calibri", margin: 0
});
});
});
// Treatment cards
treatment.forEach((t, i) => {
const x = 5.4 + i * 2.2, y = 1.35;
s.addShape(pres.ShapeType.roundRect, {
x, y, w: 2.0, h: 3.4,
fill: { color: C.navyMid }, line: { color: t.color, width: 2 },
rectRadius: 0.15
});
s.addShape(pres.ShapeType.roundRect, {
x, y, w: 2.0, h: 0.55,
fill: { color: t.color }, line: { width: 0 }, rectRadius: 0.15
});
s.addShape(pres.ShapeType.rect, {
x, y: y + 0.3, w: 2.0, h: 0.25,
fill: { color: t.color }, line: { width: 0 }
});
s.addText(t.label, {
x, y, w: 2.0, h: 0.55,
fontSize: 9, bold: true, color: C.white,
align: "center", valign: "middle", fontFace: "Calibri", margin: 0
});
t.items.forEach((item, j) => {
s.addShape(pres.ShapeType.ellipse, {
x: x + 0.15, y: y + 0.68 + j * 0.55, w: 0.2, h: 0.2,
fill: { color: t.color }, line: { width: 0 }
});
s.addText(item, {
x: x + 0.43, y: y + 0.65 + j * 0.55, w: 1.5, h: 0.3,
fontSize: 9.5, color: C.offWhite, fontFace: "Calibri", valign: "middle", margin: 0
});
});
});
// Key lab finding
s.addShape(pres.ShapeType.roundRect, {
x: 0.3, y: 4.8, w: 5.0, h: 0.55,
fill: { color: C.navyMid }, line: { color: C.amber, width: 1.5 },
rectRadius: 0.12
});
s.addText("Key labs: ↑ HCO₃⁻, ↑ pH, ↑ PCO₂ (compensatory), ↓ K⁺, ↓ Cl⁻", {
x: 0.3, y: 4.8, w: 5.0, h: 0.55,
fontSize: 10, color: C.amber, fontFace: "Calibri",
align: "center", valign: "middle", margin: 0
});
}
// ─────────────────────────────────────────────
// SLIDE 11 — SUMMARY / KEY TAKEAWAYS
// ─────────────────────────────────────────────
{
const s = pres.addSlide();
bgFill(s, C.navy);
// Left accent bar
s.addShape(pres.ShapeType.rect, {
x: 0, y: 0, w: 0.35, h: "100%",
fill: { color: C.teal }, line: { width: 0 }
});
s.addShape(pres.ShapeType.rect, {
x: 0, y: 0, w: "100%", h: 0.08,
fill: { color: C.amber }, line: { width: 0 }
});
s.addText("Key Takeaways", {
x: 0.6, y: 0.15, w: 8.8, h: 0.6,
fontSize: 30, bold: true, color: C.white, fontFace: "Calibri",
align: "left", margin: 0
});
const points = [
{ icon: "🔬", text: "Normal blood pH is 7.35–7.45, maintained by the 20:1 HCO₃⁻:CO₂ ratio." },
{ icon: "⚗", text: "Chemical buffers (bicarbonate, phosphate, proteins) act in seconds." },
{ icon: "🫁", text: "Lungs compensate in 3–12 min; 50–75% correction via CO₂ exhalation." },
{ icon: "🫘", text: "Kidneys provide complete correction over hours–days via H⁺ / HCO₃⁻ handling." },
{ icon: "↓", text: "Metabolic acidosis → ↓ HCO₃⁻; classified as High or Normal Anion Gap." },
{ icon: "↑", text: "Metabolic alkalosis → ↑ HCO₃⁻; often chloride-responsive (vomiting, diuretics)." },
{ icon: "♻", text: "Compensation is never complete (except sometimes respiratory alkalosis)." },
{ icon: "📊", text: "Unequal compensation = Mixed disorder. Always apply expected compensation formulas." },
];
points.forEach((p, i) => {
const col = i % 2, row = Math.floor(i / 2);
const x = 0.5 + col * 4.8, y = 0.95 + row * 1.12;
s.addShape(pres.ShapeType.roundRect, {
x, y, w: 4.5, h: 1.0,
fill: { color: C.navyMid }, line: { color: C.teal, width: 1 },
rectRadius: 0.12
});
s.addText(p.icon, {
x: x + 0.1, y, w: 0.55, h: 1.0,
fontSize: 20, align: "center", valign: "middle", fontFace: "Segoe UI Emoji", margin: 0
});
s.addText(p.text, {
x: x + 0.75, y: y + 0.1, w: 3.6, h: 0.8,
fontSize: 11, color: C.offWhite, fontFace: "Calibri",
valign: "middle", wrap: true, margin: 2
});
});
}
// ─────────────────────────────────────────────
// WRITE FILE
// ─────────────────────────────────────────────
pres.writeFile({ fileName: "/home/daytona/workspace/acid-base-ppt/Acid_Base_Balance.pptx" })
.then(() => console.log("SUCCESS: Acid_Base_Balance.pptx created"))
.catch(err => { console.error("ERROR:", err); process.exit(1); });
cd /home/daytona/workspace/acid-base-ppt && node create_ppt.js 2>&1
ls -lh /home/daytona/workspace/acid-base-ppt/Acid_Base_Balance.pptx