Create a presentation on principle of haemodynamic based on guyton,gk pal look like a mbbs 1st year student made this

Reading File
Reading File
Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Finding Sources
I have the structure. Now let me read the key sections from Guyton (Medical Physiology) to get all the content needed for the slides.
Reading File
Finding Sources
I have enough content from the textbook. Now let me build the full presentation using pptxgenjs with a student-made aesthetic.
Running Command

mkdir -p /home/daytona/workspace/haemodynamics-ppt && ls /home/daytona/workspace/haemodynamics-ppt/

Writing File

~/haemodynamics-ppt/build.js

const pptxgen = require("pptxgenjs");

const pres = new pptxgen();
pres.layout = "LAYOUT_16x9";
pres.title = "Principles of Haemodynamics";
pres.author = "MBBS 1st Year Student";

// ─── COLOR PALETTE ───────────────────────────────────────────────────────────
// Deep navy bg, white text, yellow accent — classic "student notepad" but digital
const BG      = "0D1B2A";   // deep navy
const BG2     = "1A2E44";   // slightly lighter navy
const WHITE   = "FFFFFF";
const YELLOW  = "FFD166";   // warm yellow accent (highlighter)
const RED     = "EF476F";   // important points
const GREEN   = "06D6A0";   // formula green
const LGRAY   = "B0C4DE";   // light steel blue for subtitles
const ORANGE  = "FF9F1C";   // secondary accent
const BOX_BG  = "162032";   // card background

// ─── HELPERS ─────────────────────────────────────────────────────────────────
function addSlide() {
  const s = pres.addSlide();
  s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.625, fill: { color: BG } });
  return s;
}

function titleBanner(s, text) {
  // Coloured left bar
  s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 0.18, h: 5.625, fill: { color: YELLOW } });
  s.addText(text, {
    x: 0.3, y: 0.12, w: 9.5, h: 0.55,
    fontSize: 22, bold: true, color: YELLOW, fontFace: "Calibri", align: "left"
  });
  // Thin separator line
  s.addShape(pres.ShapeType.line, {
    x: 0.3, y: 0.72, w: 9.4, h: 0,
    line: { color: YELLOW, width: 1.2, dashType: "dash" }
  });
}

function bullet(s, items, x, y, w, h, opts = {}) {
  const richText = items.map((it, i) => {
    const isLast = i === items.length - 1;
    if (typeof it === "string") {
      return { text: it, options: { bullet: { type: "bullet", code: "2022" }, breakLine: !isLast, color: WHITE, fontSize: opts.fontSize || 14, fontFace: "Calibri" } };
    }
    return { text: it.text, options: { bullet: { type: "bullet", code: "2022" }, breakLine: !isLast, color: it.color || WHITE, fontSize: it.sz || opts.fontSize || 14, bold: it.bold || false, fontFace: "Calibri" } };
  });
  s.addText(richText, { x, y, w, h, valign: "top", lineSpacingMultiple: 1.3 });
}

function formulaBox(s, formula, label, x, y, w = 4.2) {
  s.addShape(pres.ShapeType.rect, { x, y, w, h: 0.9, fill: { color: BOX_BG }, line: { color: GREEN, width: 1.5 } });
  s.addText(formula, { x: x + 0.1, y: y + 0.07, w: w - 0.2, h: 0.45, fontSize: 17, bold: true, color: GREEN, fontFace: "Courier New", align: "center" });
  if (label) {
    s.addText(label, { x: x + 0.1, y: y + 0.5, w: w - 0.2, h: 0.32, fontSize: 10, color: LGRAY, fontFace: "Calibri", align: "center" });
  }
}

function sectionTag(s, tag, color = ORANGE) {
  s.addShape(pres.ShapeType.rect, { x: 0.3, y: 5.2, w: tag.length * 0.12 + 0.6, h: 0.25, fill: { color: color }, rounding: "0.05" });
  s.addText(tag, { x: 0.32, y: 5.2, w: tag.length * 0.12 + 0.56, h: 0.25, fontSize: 9, bold: true, color: BG, fontFace: "Calibri", align: "center", valign: "middle" });
}

function handNote(s, note) {
  s.addShape(pres.ShapeType.rect, { x: 0.3, y: 4.92, w: 9.4, h: 0.55, fill: { color: "1E3A5F" }, line: { color: YELLOW, width: 0.7, dashType: "dash" } });
  s.addText("✏  " + note, { x: 0.38, y: 4.95, w: 9.2, h: 0.48, fontSize: 10, italic: true, color: YELLOW, fontFace: "Calibri", valign: "middle" });
}


// ═══════════════════════════════════════════════════════════════════════════════
// SLIDE 1 — TITLE SLIDE
// ═══════════════════════════════════════════════════════════════════════════════
{
  const s = addSlide();
  // Big red accent strip across top
  s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 1.1, fill: { color: "112233" } });
  s.addShape(pres.ShapeType.rect, { x: 0, y: 1.0, w: 10, h: 0.08, fill: { color: YELLOW } });

  s.addText("PRINCIPLES OF", { x: 0.6, y: 0.1, w: 9, h: 0.5, fontSize: 18, color: LGRAY, bold: false, fontFace: "Calibri", charSpacing: 6 });
  s.addText("HAEMODYNAMICS", { x: 0.6, y: 0.52, w: 9, h: 0.55, fontSize: 32, color: YELLOW, bold: true, fontFace: "Calibri", charSpacing: 2 });

  s.addText([
    { text: "Based on: ", options: { color: LGRAY, fontSize: 13, italic: false } },
    { text: "Guyton & Hall – Medical Physiology", options: { color: WHITE, fontSize: 13, bold: true } },
    { text: "  |  ", options: { color: LGRAY, fontSize: 13 } },
    { text: "G.K. Pal – Textbook of Medical Physiology", options: { color: WHITE, fontSize: 13, bold: true } }
  ], { x: 0.6, y: 1.25, w: 8.8, h: 0.45 });

  // Topics overview boxes
  const topics = [
    { t: "Ohm's Law\nAnalogy",      c: RED },
    { t: "Poiseuille's\nEquation",   c: ORANGE },
    { t: "Blood\nViscosity",         c: GREEN },
    { t: "Laminar &\nTurbulent",     c: "5E81F4" },
    { t: "Cardiac\nOutput",          c: YELLOW },
    { t: "Vascular\nCompliance",     c: "B07FFF" },
    { t: "Starling\nForces",         c: RED },
    { t: "Haemostasis\nOverview",    c: ORANGE }
  ];
  topics.forEach((tp, i) => {
    const col = i % 4;
    const row = Math.floor(i / 4);
    const x = 0.35 + col * 2.35;
    const y = 1.9 + row * 1.25;
    s.addShape(pres.ShapeType.rect, { x, y, w: 2.15, h: 1.0, fill: { color: BOX_BG }, line: { color: tp.c, width: 1.8 } });
    s.addShape(pres.ShapeType.rect, { x, y, w: 2.15, h: 0.12, fill: { color: tp.c } });
    s.addText(tp.t, { x: x + 0.1, y: y + 0.18, w: 1.95, h: 0.72, fontSize: 13, bold: true, color: WHITE, fontFace: "Calibri", align: "center", valign: "middle" });
  });

  s.addText("MBBS 1st Year · Medical Physiology", { x: 0.6, y: 5.25, w: 8.8, h: 0.3, fontSize: 10, color: LGRAY, fontFace: "Calibri", align: "right", italic: true });
}


// ═══════════════════════════════════════════════════════════════════════════════
// SLIDE 2 — WHAT IS HAEMODYNAMICS?
// ═══════════════════════════════════════════════════════════════════════════════
{
  const s = addSlide();
  titleBanner(s, "WHAT IS HAEMODYNAMICS?");

  s.addText("The study of blood flow and the forces that govern it", {
    x: 0.3, y: 0.85, w: 9.4, h: 0.4, fontSize: 16, bold: false, italic: true, color: LGRAY, fontFace: "Calibri"
  });

  // Three pillars
  const pillars = [
    { icon: "❤️", title: "HEART", desc: "Acts as a\npressure generator", color: RED },
    { icon: "🩸", title: "BLOOD", desc: "Liquid organ;\nviscous fluid", color: ORANGE },
    { icon: "🔵", title: "VESSELS", desc: "Distribution system;\nresistance elements", color: "5E81F4" }
  ];
  pillars.forEach((p, i) => {
    const x = 0.4 + i * 3.2;
    s.addShape(pres.ShapeType.rect, { x, y: 1.4, w: 2.85, h: 2.8, fill: { color: BOX_BG }, line: { color: p.color, width: 1.5 } });
    s.addText(p.icon, { x, y: 1.5, w: 2.85, h: 0.7, fontSize: 30, align: "center" });
    s.addShape(pres.ShapeType.rect, { x, y: 2.15, w: 2.85, h: 0.3, fill: { color: p.color } });
    s.addText(p.title, { x, y: 2.18, w: 2.85, h: 0.26, fontSize: 12, bold: true, color: BG, fontFace: "Calibri", align: "center" });
    s.addText(p.desc, { x: x + 0.1, y: 2.55, w: 2.65, h: 0.8, fontSize: 13, color: WHITE, fontFace: "Calibri", align: "center", valign: "top" });
  });

  bullet(s, [
    { text: "Failure of heart → Heart failure", color: RED },
    { text: "Failure of blood → Thrombosis, embolism", color: RED },
    { text: "Failure of vessels → Haemorrhage, atherosclerosis", color: RED }
  ], 0.35, 4.3, 9.2, 0.6, { fontSize: 12 });

  handNote(s, "Guyton: 'Some of the most important life-threatening diseases arise from failure of ONE of these three systems'");
}


// ═══════════════════════════════════════════════════════════════════════════════
// SLIDE 3 — OHM'S LAW ANALOGY
// ═══════════════════════════════════════════════════════════════════════════════
{
  const s = addSlide();
  titleBanner(s, "OHM'S LAW OF HYDRODYNAMICS");
  sectionTag(s, "MOST IMPORTANT LAW ★", RED);

  // Electricity vs Blood side by side
  s.addText("⚡ ELECTRICITY", { x: 0.35, y: 0.85, w: 4.3, h: 0.35, fontSize: 14, bold: true, color: "FFD166", fontFace: "Calibri" });
  s.addText("🩸 BLOOD FLOW", { x: 5.35, y: 0.85, w: 4.3, h: 0.35, fontSize: 14, bold: true, color: GREEN, fontFace: "Calibri" });

  formulaBox(s, "ΔV = I × R", "Voltage = Current × Resistance", 0.35, 1.25, 4.3);
  formulaBox(s, "ΔP = F × R", "Pressure = Flow × Resistance", 5.35, 1.25, 4.3);

  // Vertical separator
  s.addShape(pres.ShapeType.line, { x: 5.0, y: 0.82, w: 0, h: 3.6, line: { color: LGRAY, width: 0.8, dashType: "sysDash" } });
  s.addText("VS", { x: 4.7, y: 2.1, w: 0.6, h: 0.4, fontSize: 13, bold: true, color: LGRAY, fontFace: "Calibri", align: "center" });

  // Mapping table
  const map = [
    ["ELECTRICAL", "HAEMODYNAMIC"],
    ["Voltage (ΔV)", "Pressure diff. (ΔP)"],
    ["Current (I)",  "Blood flow (F)"],
    ["Resistance (R)", "Vascular resistance (R)"]
  ];
  map.forEach((row, ri) => {
    const isHead = ri === 0;
    const bgC = isHead ? "1E3A5F" : (ri % 2 === 0 ? "162032" : BOX_BG);
    s.addShape(pres.ShapeType.rect, { x: 0.35, y: 2.3 + ri * 0.38, w: 4.3, h: 0.36, fill: { color: bgC } });
    s.addText(row[0], { x: 0.4, y: 2.33 + ri * 0.38, w: 4.2, h: 0.3, fontSize: isHead ? 11 : 12, bold: isHead, color: isHead ? YELLOW : WHITE, fontFace: "Calibri" });

    s.addShape(pres.ShapeType.rect, { x: 5.35, y: 2.3 + ri * 0.38, w: 4.3, h: 0.36, fill: { color: bgC } });
    s.addText(row[1], { x: 5.4, y: 2.33 + ri * 0.38, w: 4.2, h: 0.3, fontSize: isHead ? 11 : 12, bold: isHead, color: isHead ? YELLOW : GREEN, fontFace: "Calibri" });
  });

  handNote(s, "Guyton: 'ΔP = F × R holds at any instant in time regardless of how simple or complicated the circuit'");
}


// ═══════════════════════════════════════════════════════════════════════════════
// SLIDE 4 — SERIES & PARALLEL CIRCUITS
// ═══════════════════════════════════════════════════════════════════════════════
{
  const s = addSlide();
  titleBanner(s, "SERIES & PARALLEL VASCULAR RESISTANCE");

  // Series
  s.addShape(pres.ShapeType.rect, { x: 0.3, y: 0.85, w: 4.35, h: 3.9, fill: { color: BOX_BG }, line: { color: YELLOW, width: 1 } });
  s.addText("📏 SERIES", { x: 0.4, y: 0.9, w: 4.15, h: 0.38, fontSize: 14, bold: true, color: YELLOW, fontFace: "Calibri" });
  formulaBox(s, "R_total = R₁ + R₂ + R₃ ...", "", 0.38, 1.32, 4.15);
  bullet(s, [
    "Same flow passes through each segment",
    "Ex: Arteriole → Capillary → Venule",
    "Kidney: Glomerular + Peritubular in series",
    { text: "R_total > any single R", bold: true, color: ORANGE }
  ], 0.42, 2.3, 4.1, 2.3, { fontSize: 12 });

  // Parallel
  s.addShape(pres.ShapeType.rect, { x: 5.35, y: 0.85, w: 4.3, h: 3.9, fill: { color: BOX_BG }, line: { color: GREEN, width: 1 } });
  s.addText("⫶ PARALLEL", { x: 5.45, y: 0.9, w: 4.1, h: 0.38, fontSize: 14, bold: true, color: GREEN, fontFace: "Calibri" });
  formulaBox(s, "1/R_t = 1/R₁ + 1/R₂ ...", "", 5.43, 1.32, 4.1);
  bullet(s, [
    "Blood flow divides among branches",
    "Most systemic organs are in parallel",
    "Adding vessels DECREASES total R",
    { text: "R_total < smallest individual R", bold: true, color: GREEN }
  ], 5.47, 2.3, 4.1, 2.3, { fontSize: 12 });

  handNote(s, "Remember: Parallel arrangement gives each organ INDEPENDENT blood supply — critical for organ autoregulation! 🙏");
}


// ═══════════════════════════════════════════════════════════════════════════════
// SLIDE 5 — POISEUILLE'S EQUATION
// ═══════════════════════════════════════════════════════════════════════════════
{
  const s = addSlide();
  titleBanner(s, "POISEUILLE–HAGEN EQUATION");
  sectionTag(s, "RADIUS IS KING 👑", RED);

  // Big formula
  s.addShape(pres.ShapeType.rect, { x: 1.5, y: 0.85, w: 7, h: 1.05, fill: { color: BOX_BG }, line: { color: GREEN, width: 2 } });
  s.addText("F = (ΔP × π × r⁴) / (8 × η × L)", {
    x: 1.55, y: 0.88, w: 6.9, h: 0.6, fontSize: 20, bold: true, color: GREEN, fontFace: "Courier New", align: "center"
  });
  s.addText("Flow ∝ r⁴  —  Hagen-Poiseuille Law  (for laminar, steady, Newtonian flow)", {
    x: 1.55, y: 1.46, w: 6.9, h: 0.3, fontSize: 10, color: LGRAY, fontFace: "Calibri", align: "center"
  });

  // Variable legend
  const vars = [
    { sym: "F", def: "Blood flow (mL/min)", color: WHITE },
    { sym: "ΔP", def: "Pressure difference", color: WHITE },
    { sym: "r", def: "Vessel radius", color: YELLOW },
    { sym: "η (eta)", def: "Blood viscosity", color: ORANGE },
    { sym: "L", def: "Length of vessel", color: WHITE }
  ];
  vars.forEach((v, i) => {
    const x = 0.35 + (i % 3) * 3.2;
    const y = 2.1 + Math.floor(i / 3) * 0.55;
    s.addShape(pres.ShapeType.rect, { x, y, w: 3.0, h: 0.45, fill: { color: BOX_BG }, line: { color: "2A4060", width: 0.5 } });
    s.addText(v.sym, { x: x + 0.05, y, w: 0.8, h: 0.45, fontSize: 13, bold: true, color: v.color, fontFace: "Courier New", valign: "middle" });
    s.addText(v.def, { x: x + 0.8, y, w: 2.15, h: 0.45, fontSize: 12, color: LGRAY, fontFace: "Calibri", valign: "middle" });
  });

  // Key takeaway box
  s.addShape(pres.ShapeType.rect, { x: 0.35, y: 3.4, w: 9.3, h: 1.0, fill: { color: "1E3A5F" }, line: { color: RED, width: 1.5 } });
  s.addText("⚠  WHY r⁴ MATTERS", { x: 0.5, y: 3.42, w: 4, h: 0.32, fontSize: 12, bold: true, color: RED, fontFace: "Calibri" });
  bullet(s, [
    "If radius doubles → Flow increases 16× (2⁴ = 16)",
    "Arterioles are the MAJOR site of resistance control (smallest radius!)",
    "Even tiny change in arteriole radius → HUGE change in blood flow"
  ], 0.5, 3.75, 9.0, 0.62, { fontSize: 12 });

  handNote(s, "GK Pal: Resistance R = 8ηL / πr⁴  →  Resistance is INVERSELY proportional to 4th power of radius");
}


// ═══════════════════════════════════════════════════════════════════════════════
// SLIDE 6 — BLOOD PRESSURE
// ═══════════════════════════════════════════════════════════════════════════════
{
  const s = addSlide();
  titleBanner(s, "BLOOD PRESSURE");

  // Definitions column
  s.addShape(pres.ShapeType.rect, { x: 0.3, y: 0.85, w: 4.35, h: 4.05, fill: { color: BOX_BG }, line: { color: ORANGE, width: 1 } });
  s.addText("KEY DEFINITIONS", { x: 0.4, y: 0.9, w: 4.15, h: 0.32, fontSize: 13, bold: true, color: ORANGE, fontFace: "Calibri" });

  const defs = [
    { term: "Systolic BP", val: "~120 mmHg", note: "Peak pressure during systole" },
    { term: "Diastolic BP", val: "~80 mmHg", note: "Lowest pressure during diastole" },
    { term: "Pulse Pressure", val: "SBP − DBP = 40", note: "Reflects stroke volume & compliance" },
    { term: "MAP", val: "DBP + PP/3 ≈ 93", note: "Mean Arterial Pressure (driving pressure)" }
  ];
  defs.forEach((d, i) => {
    const y = 1.32 + i * 0.85;
    s.addShape(pres.ShapeType.rect, { x: 0.38, y, w: 4.18, h: 0.78, fill: { color: "0F1E30" } });
    s.addText(d.term, { x: 0.44, y: y + 0.04, w: 2.2, h: 0.28, fontSize: 12, bold: true, color: YELLOW, fontFace: "Calibri" });
    s.addText(d.val, { x: 2.62, y: y + 0.04, w: 1.85, h: 0.28, fontSize: 12, bold: true, color: GREEN, fontFace: "Calibri", align: "right" });
    s.addText(d.note, { x: 0.44, y: y + 0.35, w: 4.0, h: 0.3, fontSize: 10, color: LGRAY, fontFace: "Calibri", italic: true });
  });

  // MAP formula highlighted
  formulaBox(s, "MAP = DBP + (PP/3)", "or  MAP ≈ (SBP + 2×DBP) / 3", 5.35, 0.85, 4.3);

  // Important concepts right side
  bullet(s, [
    { text: "Pressure is ALWAYS measured as a DIFFERENCE between two points", bold: true, color: WHITE },
    "Reference point: atmospheric pressure (760 mmHg absolute)",
    "Mean pressures: Aorta 100 → Arteries 90 → Arterioles 60 → Capillaries 25 → Veins 10 → Vena cava ~0",
    { text: "Largest pressure drop: across arterioles (major resistance vessels)", color: ORANGE }
  ], 5.35, 1.88, 4.3, 2.9, { fontSize: 11.5 });

  handNote(s, "Guyton: 'It is the MEAN pressure that drives blood flow; pulsatile pressure adds little net flow in most vessels'");
}


// ═══════════════════════════════════════════════════════════════════════════════
// SLIDE 7 — CARDIAC OUTPUT
// ═══════════════════════════════════════════════════════════════════════════════
{
  const s = addSlide();
  titleBanner(s, "CARDIAC OUTPUT");

  formulaBox(s, "CO = HR × SV", "Cardiac Output = Heart Rate × Stroke Volume", 0.35, 0.88, 4.3);

  // Normal values
  const vals = [
    { label: "Cardiac Output", val: "5 L/min", color: YELLOW },
    { label: "Heart Rate", val: "72 bpm", color: GREEN },
    { label: "Stroke Volume", val: "~70 mL", color: ORANGE },
    { label: "Cardiac Index", val: "3.2 L/min/m²", color: "5E81F4" }
  ];
  vals.forEach((v, i) => {
    const x = 0.35 + (i % 2) * 2.25;
    const y = 1.95 + Math.floor(i / 2) * 0.65;
    s.addShape(pres.ShapeType.rect, { x, y, w: 2.1, h: 0.58, fill: { color: BOX_BG }, line: { color: v.color, width: 1 } });
    s.addText(v.val, { x, y: y + 0.02, w: 2.1, h: 0.28, fontSize: 14, bold: true, color: v.color, fontFace: "Calibri", align: "center" });
    s.addText(v.label, { x, y: y + 0.3, w: 2.1, h: 0.24, fontSize: 9.5, color: LGRAY, fontFace: "Calibri", align: "center" });
  });

  // Right side - determinants
  s.addShape(pres.ShapeType.rect, { x: 5.0, y: 0.85, w: 4.65, h: 4.6, fill: { color: BOX_BG }, line: { color: "5E81F4", width: 1 } });
  s.addText("DETERMINANTS OF STROKE VOLUME", { x: 5.1, y: 0.9, w: 4.45, h: 0.32, fontSize: 11, bold: true, color: "5E81F4", fontFace: "Calibri" });

  const det = [
    { name: "PRELOAD", def: "End-diastolic volume (EDV)\nVentricular stretch before contraction", color: GREEN },
    { name: "AFTERLOAD", def: "Resistance the ventricle\nmust overcome to eject blood", color: ORANGE },
    { name: "CONTRACTILITY", def: "Intrinsic force of contraction\n(independent of preload/afterload)", color: RED }
  ];
  det.forEach((d, i) => {
    const y = 1.32 + i * 1.15;
    s.addShape(pres.ShapeType.rect, { x: 5.08, y, w: 0.85, h: 0.9, fill: { color: d.color } });
    s.addText(d.name, { x: 5.08, y: y + 0.05, w: 0.85, h: 0.8, fontSize: 9, bold: true, color: BG, fontFace: "Calibri", align: "center", valign: "middle" });
    s.addText(d.def, { x: 6.0, y: y + 0.05, w: 3.55, h: 0.8, fontSize: 11.5, color: WHITE, fontFace: "Calibri", valign: "middle" });
  });

  s.addText("Fick Method:  CO = VO₂ / (CaO₂ − CvO₂)", { x: 5.08, y: 4.65, w: 4.45, h: 0.35, fontSize: 11, color: GREEN, fontFace: "Courier New", italic: false });

  handNote(s, "Guyton: 'CO averages 5 L/min. Can rise to 25 L/min during heavy exercise in trained athletes'");
}


// ═══════════════════════════════════════════════════════════════════════════════
// SLIDE 8 — BLOOD VISCOSITY
// ═══════════════════════════════════════════════════════════════════════════════
{
  const s = addSlide();
  titleBanner(s, "BLOOD VISCOSITY");

  // Left: definition + values
  s.addShape(pres.ShapeType.rect, { x: 0.3, y: 0.85, w: 4.35, h: 4.05, fill: { color: BOX_BG }, line: { color: ORANGE, width: 1 } });
  s.addText("NORMAL VALUES", { x: 0.4, y: 0.9, w: 4.15, h: 0.32, fontSize: 13, bold: true, color: ORANGE, fontFace: "Calibri" });

  const viscVals = [
    { item: "Whole blood viscosity", val: "3–4 × water" },
    { item: "Plasma viscosity", val: "1.5–2 × water" },
    { item: "Water viscosity", val: "1.0 (reference)" },
    { item: "Normal Haematocrit", val: "42–45%" }
  ];
  viscVals.forEach((v, i) => {
    const y = 1.32 + i * 0.75;
    s.addShape(pres.ShapeType.rect, { x: 0.38, y, w: 4.18, h: 0.65, fill: { color: "0F1E30" } });
    s.addText(v.item, { x: 0.44, y: y + 0.06, w: 2.5, h: 0.5, fontSize: 12, color: WHITE, fontFace: "Calibri", valign: "middle" });
    s.addText(v.val, { x: 2.95, y: y + 0.06, w: 1.5, h: 0.5, fontSize: 12, bold: true, color: YELLOW, fontFace: "Calibri", align: "right", valign: "middle" });
  });

  // Right side
  s.addShape(pres.ShapeType.rect, { x: 5.0, y: 0.85, w: 4.65, h: 4.05, fill: { color: BOX_BG }, line: { color: "5E81F4", width: 1 } });
  s.addText("FACTORS AFFECTING VISCOSITY", { x: 5.1, y: 0.9, w: 4.45, h: 0.32, fontSize: 11, bold: true, color: "5E81F4", fontFace: "Calibri" });

  bullet(s, [
    { text: "Haematocrit (Hct)", bold: true, color: YELLOW },
    "  ↑ Hct → ↑ Viscosity (most important factor!)",
    { text: "Fibrinogen & plasma proteins", bold: true, color: YELLOW },
    "  ↑ Fibrinogen → ↑ RBC aggregation → ↑ viscosity",
    { text: "Temperature", bold: true, color: YELLOW },
    "  ↓ Temp → ↑ Viscosity",
    { text: "Anomalous viscosity (Fahraeus-Lindqvist)", bold: true, color: ORANGE },
    "  In small vessels (d<300μm) viscosity DECREASES\n  (axial streaming of RBCs)"
  ], 5.1, 1.28, 4.4, 3.55, { fontSize: 11 });

  handNote(s, "Guyton: 'Blood behaves as a non-Newtonian fluid — its viscosity changes with flow velocity (anomalous viscosity)'");
}


// ═══════════════════════════════════════════════════════════════════════════════
// SLIDE 9 — LAMINAR VS TURBULENT FLOW
// ═══════════════════════════════════════════════════════════════════════════════
{
  const s = addSlide();
  titleBanner(s, "LAMINAR vs TURBULENT FLOW");

  // Laminar
  s.addShape(pres.ShapeType.rect, { x: 0.3, y: 0.85, w: 4.35, h: 3.7, fill: { color: BOX_BG }, line: { color: GREEN, width: 1.5 } });
  s.addText("🌊 LAMINAR FLOW", { x: 0.4, y: 0.9, w: 4.15, h: 0.35, fontSize: 13, bold: true, color: GREEN, fontFace: "Calibri" });
  bullet(s, [
    "Streamlined, smooth, concentric layers",
    "Velocity HIGHEST at centre, zero at wall",
    "Parabolic velocity profile",
    { text: "Normal in most blood vessels", color: GREEN },
    "Silent — no sounds produced",
    "Obeys Poiseuille's law"
  ], 0.4, 1.32, 4.1, 3.1, { fontSize: 12 });

  // Turbulent
  s.addShape(pres.ShapeType.rect, { x: 5.35, y: 0.85, w: 4.3, h: 3.7, fill: { color: BOX_BG }, line: { color: RED, width: 1.5 } });
  s.addText("🌀 TURBULENT FLOW", { x: 5.45, y: 0.9, w: 4.1, h: 0.35, fontSize: 13, bold: true, color: RED, fontFace: "Calibri" });
  bullet(s, [
    "Chaotic, eddy currents form",
    "INCREASES resistance to flow",
    { text: "Produces SOUNDS (bruits/murmurs)", color: RED, bold: true },
    "Occurs at high velocities",
    "Increases energy requirement"
  ], 5.45, 1.32, 4.1, 3.1, { fontSize: 12 });

  // Reynolds number
  s.addShape(pres.ShapeType.rect, { x: 0.3, y: 4.58, w: 9.35, h: 0.62, fill: { color: "1E3A5F" }, line: { color: YELLOW, width: 1 } });
  s.addText("Reynolds Number:  Re = (ρ × v × d) / η     |     Re < 2000 → Laminar   |   Re > 3000 → Turbulent", {
    x: 0.4, y: 4.61, w: 9.15, h: 0.56,
    fontSize: 12, bold: true, color: YELLOW, fontFace: "Courier New", align: "center", valign: "middle"
  });

  // Separator
  s.addShape(pres.ShapeType.line, { x: 5.0, y: 0.88, w: 0, h: 3.65, line: { color: LGRAY, width: 0.6, dashType: "sysDash" } });
}


// ═══════════════════════════════════════════════════════════════════════════════
// SLIDE 10 — VASCULAR COMPLIANCE
// ═══════════════════════════════════════════════════════════════════════════════
{
  const s = addSlide();
  titleBanner(s, "VASCULAR COMPLIANCE & DISTENSIBILITY");

  formulaBox(s, "C = ΔV / ΔP", "Compliance = Change in Volume / Change in Pressure", 0.35, 0.85, 4.3);
  formulaBox(s, "D = ΔV / (V₀ × ΔP)", "Distensibility = Fractional change in volume per mmHg", 5.35, 0.85, 4.3);

  // Table of comparisons
  s.addText("ARTERIES vs VEINS — COMPLIANCE COMPARISON", {
    x: 0.35, y: 2.0, w: 9.3, h: 0.32, fontSize: 12, bold: true, color: LGRAY, fontFace: "Calibri"
  });

  const rows = [
    ["Property", "ARTERIES", "VEINS"],
    ["Wall thickness", "Thick", "Thin"],
    ["Elastic content", "High", "Low"],
    ["Compliance", "Low", "~8× more than arteries"],
    ["Function", "Windkessel (pressure reservoir)", "Capacitance vessels (blood reservoir)"],
    ["Blood volume", "~15%", "~65%"]
  ];
  rows.forEach((row, ri) => {
    const isHead = ri === 0;
    const bgC = isHead ? "1E3A5F" : (ri % 2 === 0 ? "162032" : BOX_BG);
    const cols = [0.35, 3.05, 6.75];
    const ws   = [2.65, 3.65, 3.2];
    row.forEach((cell, ci) => {
      s.addShape(pres.ShapeType.rect, { x: cols[ci], y: 2.38 + ri * 0.38, w: ws[ci], h: 0.36, fill: { color: bgC } });
      s.addText(cell, {
        x: cols[ci] + 0.05, y: 2.4 + ri * 0.38, w: ws[ci] - 0.1, h: 0.32,
        fontSize: isHead ? 11 : 11.5, bold: isHead,
        color: isHead ? YELLOW : (ci === 1 ? ORANGE : ci === 2 ? GREEN : WHITE),
        fontFace: "Calibri", valign: "middle"
      });
    });
  });

  handNote(s, "Guyton: 'Veins serve as a BLOOD RESERVOIR — 65% of total blood volume. Venous tone controls venous return to heart'");
}


// ═══════════════════════════════════════════════════════════════════════════════
// SLIDE 11 — STARLING FORCES (CAPILLARY)
// ═══════════════════════════════════════════════════════════════════════════════
{
  const s = addSlide();
  titleBanner(s, "STARLING FORCES — CAPILLARY FLUID EXCHANGE");
  sectionTag(s, "IMPORTANT FOR EXAM ★★", RED);

  formulaBox(s, "NFP = [(Pc + πi) − (Pi + πp)]", "Net Filtration Pressure = Filtration forces − Absorption forces", 0.35, 0.85, 9.3);

  const forces = [
    { name: "Pc",  full: "Capillary hydrostatic pressure",   fav: "Filtration →", val: "Art. end: 32  Venous end: 15  mmHg", color: RED },
    { name: "πi",  full: "Interstitial oncotic pressure",    fav: "Filtration →", val: "~8 mmHg",  color: RED },
    { name: "Pi",  full: "Interstitial hydrostatic pressure",fav: "← Absorption", val: "−3 mmHg (slight suction)", color: GREEN },
    { name: "πp",  full: "Plasma oncotic pressure",          fav: "← Absorption", val: "~28 mmHg (albumin++)",  color: GREEN }
  ];

  s.addShape(pres.ShapeType.rect, { x: 0.35, y: 2.0, w: 4.3, h: 0.28, fill: { color: RED }, rounding: "0.02" });
  s.addText("FILTRATION FORCES (outward)", { x: 0.35, y: 2.0, w: 4.3, h: 0.28, fontSize: 11, bold: true, color: WHITE, fontFace: "Calibri", align: "center", valign: "middle" });

  s.addShape(pres.ShapeType.rect, { x: 5.35, y: 2.0, w: 4.3, h: 0.28, fill: { color: GREEN }, rounding: "0.02" });
  s.addText("ABSORPTION FORCES (inward)", { x: 5.35, y: 2.0, w: 4.3, h: 0.28, fontSize: 11, bold: true, color: BG, fontFace: "Calibri", align: "center", valign: "middle" });

  forces.forEach((f, i) => {
    const isFilter = i < 2;
    const x = isFilter ? 0.35 : 5.35;
    const y = 2.35 + (isFilter ? i : i - 2) * 0.88;
    s.addShape(pres.ShapeType.rect, { x, y, w: 4.3, h: 0.8, fill: { color: BOX_BG }, line: { color: f.color, width: 1 } });
    s.addText(f.name, { x: x + 0.05, y: y + 0.04, w: 0.5, h: 0.35, fontSize: 15, bold: true, color: f.color, fontFace: "Courier New" });
    s.addText(f.full, { x: x + 0.55, y: y + 0.04, w: 3.65, h: 0.32, fontSize: 11, color: WHITE, fontFace: "Calibri" });
    s.addText(f.val, { x: x + 0.1, y: y + 0.44, w: 4.1, h: 0.3, fontSize: 11, color: LGRAY, fontFace: "Calibri", italic: true });
  });

  s.addShape(pres.ShapeType.rect, { x: 0.35, y: 4.1, w: 9.3, h: 0.72, fill: { color: "1E3A5F" }, line: { color: YELLOW, width: 1 } });
  s.addText("ARTERIOLAR END: NFP = +13 mmHg → Net FILTRATION (fluid leaves)", { x: 0.5, y: 4.12, w: 8.9, h: 0.3, fontSize: 11.5, color: RED, fontFace: "Calibri", bold: true });
  s.addText("VENOUS END: NFP = −8 mmHg  → Net ABSORPTION (fluid enters capillary)", { x: 0.5, y: 4.42, w: 8.9, h: 0.3, fontSize: 11.5, color: GREEN, fontFace: "Calibri", bold: true });
}


// ═══════════════════════════════════════════════════════════════════════════════
// SLIDE 12 — SUMMARY TABLE
// ═══════════════════════════════════════════════════════════════════════════════
{
  const s = addSlide();
  titleBanner(s, "QUICK SUMMARY — KEY FORMULAE & VALUES");

  const rows = [
    ["Principle / Law", "Formula / Key Fact", "Clinical Importance"],
    ["Ohm's Hydrodynamic Law", "ΔP = F × R", "Flow ∝ Pressure, Flow ∝ 1/Resistance"],
    ["Poiseuille's Equation",  "F ∝ r⁴ / (η × L)", "Arteriole radius = biggest control point"],
    ["Reynolds Number",       "Re = ρvd/η  (<2000 laminar)", "Turbulence → bruits, murmurs"],
    ["Cardiac Output",        "CO = HR × SV  (5 L/min)", "Preload, afterload, contractility"],
    ["Mean Arterial Pressure","MAP = DBP + PP/3  (~93 mmHg)", "Organ perfusion pressure"],
    ["Vascular Compliance",   "C = ΔV/ΔP  (veins > arteries)", "Veins hold 65% blood volume"],
    ["Starling Forces",       "NFP = Pc + πi − Pi − πp", "Oedema when filtration > absorption"]
  ];

  rows.forEach((row, ri) => {
    const isHead = ri === 0;
    const bgC = isHead ? "1E3A5F" : (ri % 2 === 0 ? "162032" : BOX_BG);
    const cols = [0.2, 3.2, 6.5];
    const ws   = [2.95, 3.25, 3.25];
    const fcs  = [YELLOW, GREEN, ORANGE];
    row.forEach((cell, ci) => {
      s.addShape(pres.ShapeType.rect, { x: cols[ci], y: 0.78 + ri * 0.54, w: ws[ci], h: 0.52, fill: { color: bgC } });
      s.addText(cell, {
        x: cols[ci] + 0.05, y: 0.8 + ri * 0.54, w: ws[ci] - 0.1, h: 0.48,
        fontSize: isHead ? 11 : 10.5, bold: isHead,
        color: isHead ? fcs[ci] : (ci === 1 ? GREEN : WHITE),
        fontFace: isHead ? "Calibri" : (ci === 1 ? "Courier New" : "Calibri"),
        valign: "middle"
      });
    });
  });

  handNote(s, "Prepared from: Guyton & Hall — Medical Physiology (14th Ed.)  |  G.K. Pal — Textbook of Medical Physiology  ✏️ MBBS 1st Year");
}


// ═══════════════════════════════════════════════════════════════════════════════
// WRITE FILE
// ═══════════════════════════════════════════════════════════════════════════════
pres.writeFile({ fileName: "/home/daytona/workspace/haemodynamics-ppt/Principles_of_Haemodynamics.pptx" })
  .then(() => console.log("✅ PPTX saved successfully!"))
  .catch(err => { console.error("❌ Error:", err); process.exit(1); });
Running Command

cd /home/daytona/workspace/haemodynamics-ppt && node build.js 2>&1

Running Command

ls -lh /home/daytona/workspace/haemodynamics-ppt/Principles_of_Haemodynamics.pptx

You've run out of free credits. Sign up for a free account to continue using Orris.
This is a shared conversation. Sign in to Orris to start your own chat.