Make a powerpoint presentation from this COMMUNICATION STATIONS • Communication stations in OSCEs are designed to test how well a candidate interacts with patients, relatives, or colleagues, rather than just their factual knowledge. Their purpose is to ensure future clinicians can combine medical expertise with human connection. • Good communication skills are central to OSCEs and are likely to be tested in the majority of stations. • The candidate would be observed interacting with a patient, a patient's relative, or a fellow health professional (who will always be played by an actor). • Although communication skills are the main skill being tested in some stations, a candidate will be marked on his communication skills in almost all stations involving a patient. KEY TIPS • Start strong: Greet the patient, introduce yourself, and explain the purpose of the encounter. • Build rapport quickly: Use open body language, eye contact, and a warm tone. • Listen actively: Allow the patient to speak without interruption; use nods, short verbal cues, and reflective statements. • Check understanding: Use the Ask–Tell–Ask method to ensure the patient follows your explanation. • Be clear and simple: Avoid jargon; break information into small, digestible chunks. • Show empathy: Acknowledge feelings, validate concerns, and respond sensitively. • Stay patient-centered: Explore the patient’s perspective, values, and preferences before offering solutions. • Handle emotions calmly: If the patient is upset, pause, acknowledge, and give space before continuing. • Structure your talk: Organize information logically (problem → options → plan → reassurance). • Summarize and safety-net: Recap key points, confirm understanding, and advise what to do if problems arise. • Professionalism matters: Respect confidentiality, avoid judgment, and maintain composure under pressure. • Time management: Be concise but thorough avoid rambling or overloading with details TEMPLATE • Introduction: Establish rapport (eye contact, open body language)  Greet the patient respectfully.  Confirm identity (name, age, role if relevant).  Explain purpose of the session and gain consent • Assessment of Understanding  Ask what the patient already knows about the issue.  Explore concerns, expectations, and emotional state.  Identify misconceptions or gaps in knowledge. • Information Sharing  Use clear, jargon-free language.  Provide structured explanation: o Nature of the condition/problem o Available options/management strategies o Risks and benefits o Likely outcomes/prognosis  Use visual aids, analogies, or mnemonics if appropriate. • Patient-Centered Approach  Check understanding frequently (“Does this make sense so far?”).  Encourage questions.  Explore patient’s values, preferences, and cultural context.  Address emotional reactions empathetically. • Decision-Making & Planning  Summarize key points.  Present choices clearly.  Support shared decision-making.  Agree on next steps (treatment, lifestyle changes, follow-up). • Closing the Session  Reassure and motivate.  Offer written information or resources if appropriate.  Confirm patient’s understanding of the plan.  Thank the patient and close respectfully. • Examiner’s Checklist (Scoring Anchors)  Communication skills: clarity, empathy, body language.  Structure: logical flow, completeness.  Patient engagement: checking understanding, shared decision-making.  Accuracy: correct information, balanced risks/benefits.  Professionalism: respect, confidentiality, non-judgmental tone. STATION 6: NEWLY DIAGNOSED HYPERTENSIVE PATIENT Mrs. Jenny Banda a 45-year-old woman has been found with hypertension. Counsel the patient on her condition. MARKING RUBRIC • Introduction  Greet and establish rapport: “Hello Mrs. Banda, my name is Dr. [Name] I’d like to talk with you about the results we found today regarding your blood pressure. Is this a good time?”  Ensure privacy and comfort.  Check baseline knowledge: “Before I explain further, could you share what you already know about high blood pressure?” • Explanation of the Condition  Use simple terms: “Hypertension means your blood pressure is consistently higher than normal. Blood pressure is the force of blood pushing against your arteries. When it stays high, it puts strain on your heart, brain, kidneys, and blood vessels.”  Clarify: “It often doesn’t cause symptoms, which is why it’s sometimes called a ‘silent killer.’ But over time, it can lead to serious problems like stroke, heart attack, kidney disease, or vision loss.” • Importance of Treatment  Emphasize control, not cure: “Hypertension can’t usually be cured, but it can be controlled. With proper treatment and lifestyle changes, you can live a healthy, full life.”  Benefits: reduces risk of complications.  Risks if untreated: stroke, heart failure, kidney damage. • Lifestyle and Self-Care  Diet: reduce salt intake, eat more fruits and vegetables, avoid excessive fats and processed foods.  Exercise: aim for at least 30 minutes of moderate activity most days.  Weight: maintain a healthy weight.  Alcohol & smoking: limit alcohol, avoid smoking.  Stress: practice relaxation techniques. • Medication adherence: “If prescribed tablets, it’s important to take them daily as directed, even if you feel well.” • Monitoring  Regular blood pressure checks.  Keep a record of readings.  Attend follow-up appointments. • Psychosocial Support  Acknowledge feelings: “I understand this may be worrying, but many people manage hypertension successfully with support.”  Encourage family involvement.  Offer referral to nutritionist, support groups, or counseling if needed. • Safety Netting  Red flag symptoms: chest pain, severe headache, blurred vision, weakness on one side → seek urgent care.  Stress importance of follow-up: “We’ll need to monitor your blood pressure regularly and check your heart, kidneys, and eyes over time.” • Closing  Summarize: “So Mrs. Banda, hypertension means your blood pressure is high, but with lifestyle changes, regular monitoring, and possibly medication, we can control it and prevent complications.”  Invite questions: “Do you have any concerns or questions at this stage?”  End positively: “With good management, you can live a long and healthy life. We’ll support you throughout this journey.”  Thank the patient for their time

Reading File
Reading File
Running Command

ls -la /home/daytona/workspace/

Running Command

mkdir -p /home/daytona/workspace/communication-stations-pptx

Writing File

~/communication-stations-pptx/build.js

const pptxgen = require("pptxgenjs");

const pres = new pptxgen();
pres.layout = "LAYOUT_16x9";
pres.title = "Communication Stations – OSCE";
pres.author = "OSCE Prep";

// ── COLOUR PALETTE ────────────────────────────────────────────────────────────
const C = {
  navy:    "0D2B55",   // dominant dark bg
  teal:    "1A7A8A",   // header bar / accent
  tealMid: "1F9FAF",   // lighter teal for sub-bars
  gold:    "F5A623",   // accent / highlight
  white:   "FFFFFF",
  offWhite:"F0F4F8",
  slate:   "344D6E",   // secondary bg
  text:    "1C2B3A",   // body text on light bg
  muted:   "6B8299",
};

// ── HELPERS ───────────────────────────────────────────────────────────────────
function addSlide(bg) {
  const sl = pres.addSlide();
  sl.background = { color: bg || C.navy };
  return sl;
}

function sectionBar(sl, label, yPos) {
  sl.addShape(pres.ShapeType.rect, {
    x: 0, y: yPos, w: 10, h: 0.45,
    fill: { color: C.teal }, line: { color: C.teal },
  });
  sl.addText(label.toUpperCase(), {
    x: 0.2, y: yPos + 0.04, w: 9.6, h: 0.37,
    fontSize: 11, bold: true, color: C.white, charSpacing: 2, valign: "middle", margin: 0,
  });
}

function accentLine(sl, yPos) {
  sl.addShape(pres.ShapeType.rect, {
    x: 0.5, y: yPos, w: 1.0, h: 0.07,
    fill: { color: C.gold }, line: { color: C.gold },
  });
}

function titleBlock(sl, title, subtitle) {
  sl.addShape(pres.ShapeType.rect, {
    x: 0, y: 0, w: 10, h: 5.625,
    fill: { color: C.navy }, line: { color: C.navy },
  });
  // Left accent stripe
  sl.addShape(pres.ShapeType.rect, {
    x: 0, y: 0, w: 0.22, h: 5.625,
    fill: { color: C.gold }, line: { color: C.gold },
  });
  sl.addText(title, {
    x: 0.55, y: 1.6, w: 8.9, h: 1.2,
    fontSize: 40, bold: true, color: C.white, valign: "middle",
  });
  accentLine(sl, 2.9);
  if (subtitle) {
    sl.addText(subtitle, {
      x: 0.55, y: 3.1, w: 8.9, h: 0.7,
      fontSize: 18, color: C.tealMid, italic: true,
    });
  }
}

function bulletSlide(sl, heading, items, opts = {}) {
  const yStart = opts.yStart || 1.05;
  const colCount = opts.cols || 1;
  const colW = (9.2 / colCount);

  // heading bar
  sl.addShape(pres.ShapeType.rect, {
    x: 0, y: 0, w: 10, h: 0.82,
    fill: { color: C.teal }, line: { color: C.teal },
  });
  sl.addText(heading, {
    x: 0.3, y: 0, w: 9.4, h: 0.82,
    fontSize: 22, bold: true, color: C.white, valign: "middle", margin: 0,
  });

  if (colCount === 1) {
    const textArr = items.map((item, i) => ({
      text: item.text,
      options: {
        bullet: item.sub ? { indent: 20 } : true,
        color: item.sub ? C.muted : C.offWhite,
        fontSize: item.sub ? 13 : 15,
        bold: item.bold || false,
        breakLine: i < items.length - 1,
        indentLevel: item.sub ? 1 : 0,
      },
    }));
    sl.addText(textArr, {
      x: 0.4, y: yStart, w: 9.2, h: 5.625 - yStart - 0.2,
      valign: "top",
    });
  } else {
    // Split items across columns
    const half = Math.ceil(items.length / colCount);
    for (let c = 0; c < colCount; c++) {
      const chunk = items.slice(c * half, (c + 1) * half);
      const textArr = chunk.map((item, i) => ({
        text: item.text,
        options: {
          bullet: item.sub ? { indent: 20 } : true,
          color: item.sub ? C.muted : C.offWhite,
          fontSize: item.sub ? 13 : 15,
          bold: item.bold || false,
          breakLine: i < chunk.length - 1,
          indentLevel: item.sub ? 1 : 0,
        },
      }));
      sl.addText(textArr, {
        x: 0.4 + c * (colW + 0.1), y: yStart, w: colW - 0.1, h: 5.625 - yStart - 0.2,
        valign: "top",
      });
    }
  }
}

function cardSlide(sl, heading, cards) {
  // heading bar
  sl.addShape(pres.ShapeType.rect, {
    x: 0, y: 0, w: 10, h: 0.82,
    fill: { color: C.teal }, line: { color: C.teal },
  });
  sl.addText(heading, {
    x: 0.3, y: 0, w: 9.4, h: 0.82,
    fontSize: 22, bold: true, color: C.white, valign: "middle", margin: 0,
  });

  const numCards = cards.length;
  const cardW = (9.4 / numCards) - 0.15;
  cards.forEach((card, i) => {
    const cx = 0.3 + i * (cardW + 0.15);
    const cy = 1.0;
    const ch = 4.4;
    sl.addShape(pres.ShapeType.rect, {
      x: cx, y: cy, w: cardW, h: ch,
      fill: { color: C.slate }, line: { color: C.tealMid, pt: 1.5 },
      rectRadius: 0.12,
    });
    // Card header
    sl.addShape(pres.ShapeType.rect, {
      x: cx, y: cy, w: cardW, h: 0.55,
      fill: { color: C.tealMid }, line: { color: C.tealMid },
      rectRadius: 0.12,
    });
    sl.addText(card.title, {
      x: cx + 0.1, y: cy + 0.04, w: cardW - 0.2, h: 0.47,
      fontSize: 13, bold: true, color: C.white, valign: "middle", align: "center", margin: 0,
    });
    const bodyArr = card.items.map((item, idx) => ({
      text: item,
      options: {
        bullet: true,
        color: C.offWhite,
        fontSize: 12,
        breakLine: idx < card.items.length - 1,
      },
    }));
    sl.addText(bodyArr, {
      x: cx + 0.1, y: cy + 0.65, w: cardW - 0.2, h: ch - 0.75,
      valign: "top",
    });
  });
}

// ══════════════════════════════════════════════════════════════════════════════
// SLIDE 1 — TITLE
// ══════════════════════════════════════════════════════════════════════════════
{
  const sl = addSlide(C.navy);
  titleBlock(sl, "Communication Stations", "OSCE Preparation Guide");
  sl.addText("Combining Medical Expertise with Human Connection", {
    x: 0.55, y: 3.9, w: 8.9, h: 0.5,
    fontSize: 14, color: C.muted,
  });
  // Bottom bar
  sl.addShape(pres.ShapeType.rect, {
    x: 0, y: 5.25, w: 10, h: 0.375,
    fill: { color: C.teal }, line: { color: C.teal },
  });
}

// ══════════════════════════════════════════════════════════════════════════════
// SLIDE 2 — WHAT ARE COMMUNICATION STATIONS?
// ══════════════════════════════════════════════════════════════════════════════
{
  const sl = addSlide(C.navy);
  bulletSlide(sl, "What Are Communication Stations?", [
    { text: "Designed to test how well a candidate interacts with patients, relatives, or colleagues — beyond factual knowledge." },
    { text: "Purpose: ensure future clinicians combine medical expertise with human connection." },
    { text: "Communication skills are tested in the majority of OSCE stations." },
    { text: "The candidate interacts with an actor playing a patient, relative, or health professional." },
    { text: "Even in non-communication stations, candidates are marked on communication with any patient." },
  ]);
}

// ══════════════════════════════════════════════════════════════════════════════
// SLIDE 3 — KEY TIPS (Part 1)
// ══════════════════════════════════════════════════════════════════════════════
{
  const sl = addSlide(C.navy);
  bulletSlide(sl, "Key Tips (1 of 2)", [
    { text: "Start strong", bold: true },
    { text: "Greet the patient, introduce yourself, explain the purpose of the encounter.", sub: true },
    { text: "Build rapport quickly", bold: true },
    { text: "Use open body language, eye contact, and a warm tone.", sub: true },
    { text: "Listen actively", bold: true },
    { text: "Allow the patient to speak without interruption; use nods, verbal cues, and reflective statements.", sub: true },
    { text: "Check understanding", bold: true },
    { text: "Use the Ask–Tell–Ask method to ensure the patient follows your explanation.", sub: true },
    { text: "Be clear and simple", bold: true },
    { text: "Avoid jargon; break information into small, digestible chunks.", sub: true },
    { text: "Show empathy", bold: true },
    { text: "Acknowledge feelings, validate concerns, and respond sensitively.", sub: true },
  ]);
}

// ══════════════════════════════════════════════════════════════════════════════
// SLIDE 4 — KEY TIPS (Part 2)
// ══════════════════════════════════════════════════════════════════════════════
{
  const sl = addSlide(C.navy);
  bulletSlide(sl, "Key Tips (2 of 2)", [
    { text: "Stay patient-centered", bold: true },
    { text: "Explore the patient's perspective, values, and preferences before offering solutions.", sub: true },
    { text: "Handle emotions calmly", bold: true },
    { text: "If the patient is upset, pause, acknowledge, and give space before continuing.", sub: true },
    { text: "Structure your talk", bold: true },
    { text: "Organise information logically: problem → options → plan → reassurance.", sub: true },
    { text: "Summarise and safety-net", bold: true },
    { text: "Recap key points, confirm understanding, advise what to do if problems arise.", sub: true },
    { text: "Professionalism matters", bold: true },
    { text: "Respect confidentiality, avoid judgment, and maintain composure under pressure.", sub: true },
    { text: "Time management", bold: true },
    { text: "Be concise but thorough — avoid rambling or overloading with details.", sub: true },
  ]);
}

// ══════════════════════════════════════════════════════════════════════════════
// SLIDE 5 — TEMPLATE OVERVIEW (cards)
// ══════════════════════════════════════════════════════════════════════════════
{
  const sl = addSlide(C.navy);
  cardSlide(sl, "Consultation Template — Overview", [
    {
      title: "1. Introduction",
      items: [
        "Greet respectfully",
        "Confirm identity",
        "State purpose & gain consent",
        "Establish rapport",
      ],
    },
    {
      title: "2. Assessment",
      items: [
        "Ask what patient knows",
        "Explore concerns & expectations",
        "Identify misconceptions",
      ],
    },
    {
      title: "3. Information",
      items: [
        "Jargon-free language",
        "Condition / options / risks / prognosis",
        "Use aids or analogies",
      ],
    },
    {
      title: "4. Patient-Centred",
      items: [
        "Check understanding often",
        "Encourage questions",
        "Explore values & culture",
        "Address emotions",
      ],
    },
  ]);
}

// ══════════════════════════════════════════════════════════════════════════════
// SLIDE 6 — TEMPLATE: DECISION-MAKING & CLOSING
// ══════════════════════════════════════════════════════════════════════════════
{
  const sl = addSlide(C.navy);
  cardSlide(sl, "Consultation Template — Decision-Making & Closing", [
    {
      title: "5. Decision-Making",
      items: [
        "Summarise key points",
        "Present choices clearly",
        "Support shared decisions",
        "Agree on next steps",
      ],
    },
    {
      title: "6. Closing",
      items: [
        "Reassure & motivate",
        "Offer written resources",
        "Confirm patient understands",
        "Thank & close respectfully",
      ],
    },
    {
      title: "Examiner Checklist",
      items: [
        "Clarity, empathy, body language",
        "Structure & completeness",
        "Patient engagement",
        "Accurate information",
        "Professionalism",
      ],
    },
  ]);
}

// ══════════════════════════════════════════════════════════════════════════════
// SLIDE 7 — STATION 6 TITLE CARD
// ══════════════════════════════════════════════════════════════════════════════
{
  const sl = addSlide(C.navy);
  // decorative stripe
  sl.addShape(pres.ShapeType.rect, {
    x: 0, y: 0, w: 0.22, h: 5.625,
    fill: { color: C.gold }, line: { color: C.gold },
  });
  sl.addShape(pres.ShapeType.rect, {
    x: 0, y: 4.9, w: 10, h: 0.725,
    fill: { color: C.teal }, line: { color: C.teal },
  });
  sl.addText("STATION 6", {
    x: 0.55, y: 0.8, w: 9, h: 0.7,
    fontSize: 16, color: C.gold, bold: true, charSpacing: 4,
  });
  sl.addText("Newly Diagnosed\nHypertensive Patient", {
    x: 0.55, y: 1.5, w: 9, h: 1.8,
    fontSize: 36, bold: true, color: C.white,
  });
  sl.addText("Counsel Mrs. Jenny Banda, 45-year-old woman, recently diagnosed with hypertension.", {
    x: 0.55, y: 3.4, w: 9, h: 0.8,
    fontSize: 17, color: C.offWhite, italic: true,
  });
}

// ══════════════════════════════════════════════════════════════════════════════
// SLIDE 8 — RUBRIC: INTRODUCTION & EXPLANATION
// ══════════════════════════════════════════════════════════════════════════════
{
  const sl = addSlide(C.navy);
  bulletSlide(sl, "Marking Rubric — Introduction & Explanation", [
    { text: "Introduction", bold: true },
    { text: "Greet & establish rapport: "Hello Mrs. Banda, my name is Dr. [Name]…"", sub: true },
    { text: "Ensure privacy and comfort.", sub: true },
    { text: "Check baseline knowledge: "What do you already know about high blood pressure?"", sub: true },
    { text: "Explanation of the Condition", bold: true },
    { text: "Use simple terms: "Hypertension means your blood pressure is consistently higher than normal."", sub: true },
    { text: ""The force of blood pushes against your arteries — when too high, it strains your heart, brain, kidneys, and blood vessels."", sub: true },
    { text: "Clarify: "Often symptomless — the 'silent killer.' Can lead to stroke, heart attack, kidney disease, or vision loss."", sub: true },
    { text: "Importance of Treatment", bold: true },
    { text: "Emphasise control, not cure: "Hypertension can't usually be cured, but it can be controlled."", sub: true },
    { text: "Benefits: reduces risk of complications. Risks if untreated: stroke, heart failure, kidney damage.", sub: true },
  ]);
}

// ══════════════════════════════════════════════════════════════════════════════
// SLIDE 9 — RUBRIC: LIFESTYLE & MONITORING
// ══════════════════════════════════════════════════════════════════════════════
{
  const sl = addSlide(C.navy);
  bulletSlide(sl, "Marking Rubric — Lifestyle & Monitoring", [
    { text: "Diet", bold: true },
    { text: "Reduce salt; eat more fruits & vegetables; avoid excessive fats and processed foods.", sub: true },
    { text: "Exercise", bold: true },
    { text: "At least 30 minutes of moderate activity most days.", sub: true },
    { text: "Weight, Alcohol & Smoking", bold: true },
    { text: "Maintain healthy weight. Limit alcohol. Avoid smoking.", sub: true },
    { text: "Stress management", bold: true },
    { text: "Practise relaxation techniques.", sub: true },
    { text: "Medication Adherence", bold: true },
    { text: ""Take tablets daily as directed, even if you feel well."", sub: true },
    { text: "Monitoring", bold: true },
    { text: "Regular BP checks; keep a record; attend follow-up appointments.", sub: true },
  ]);
}

// ══════════════════════════════════════════════════════════════════════════════
// SLIDE 10 — RUBRIC: PSYCHOSOCIAL & SAFETY-NETTING
// ══════════════════════════════════════════════════════════════════════════════
{
  const sl = addSlide(C.navy);
  bulletSlide(sl, "Marking Rubric — Psychosocial Support & Safety-Netting", [
    { text: "Psychosocial Support", bold: true },
    { text: "Acknowledge feelings: "I understand this may be worrying, but many people manage hypertension successfully."", sub: true },
    { text: "Encourage family involvement.", sub: true },
    { text: "Offer referral to nutritionist, support groups, or counselling if needed.", sub: true },
    { text: "Safety-Netting — Red Flag Symptoms", bold: true },
    { text: "Chest pain, severe headache, blurred vision, or one-sided weakness → seek urgent care.", sub: true },
    { text: "Stress follow-up: "We'll monitor BP regularly and check your heart, kidneys, and eyes over time."", sub: true },
    { text: "Closing", bold: true },
    { text: "Summarise: "Hypertension means your BP is high, but with lifestyle changes, monitoring, and medication we can control it."", sub: true },
    { text: "Invite questions: "Do you have any concerns or questions at this stage?"", sub: true },
    { text: "End positively: "With good management, you can live a long and healthy life. We'll support you throughout."", sub: true },
    { text: "Thank the patient for their time.", sub: true },
  ]);
}

// ══════════════════════════════════════════════════════════════════════════════
// SLIDE 11 — SUMMARY / KEY TAKEAWAYS
// ══════════════════════════════════════════════════════════════════════════════
{
  const sl = addSlide(C.navy);
  sl.addShape(pres.ShapeType.rect, {
    x: 0, y: 0, w: 10, h: 0.82,
    fill: { color: C.gold }, line: { color: C.gold },
  });
  sl.addText("Key Takeaways", {
    x: 0.3, y: 0, w: 9.4, h: 0.82,
    fontSize: 22, bold: true, color: C.navy, valign: "middle", margin: 0,
  });

  const takeaways = [
    { icon: "★", text: "Good communication = medical expertise + human connection." },
    { icon: "★", text: "Follow the 6-step template: Introduce → Assess → Inform → Patient-centre → Decide → Close." },
    { icon: "★", text: "Use Ask–Tell–Ask to check understanding at every stage." },
    { icon: "★", text: "Show empathy; acknowledge emotions before continuing." },
    { icon: "★", text: "Safety-net every consultation — red flags and follow-up." },
    { icon: "★", text: "Professionalism: confidentiality, non-judgmental, composed." },
  ];

  const textArr = takeaways.map((t, i) => [
    { text: t.icon + "  ", options: { color: C.gold, bold: true, fontSize: 15 } },
    { text: t.text, options: { color: C.offWhite, fontSize: 15, breakLine: i < takeaways.length - 1 } },
  ]).flat();

  sl.addText(textArr, {
    x: 0.5, y: 1.05, w: 9, h: 4.3, valign: "top",
  });
}

// ── WRITE FILE ────────────────────────────────────────────────────────────────
pres.writeFile({ fileName: "/home/daytona/workspace/communication-stations-pptx/Communication_Stations_OSCE.pptx" })
  .then(() => console.log("✅  Saved!"))
  .catch(err => { console.error(err); process.exit(1); });
Running Command

cd /home/daytona/workspace/communication-stations-pptx && node build.js 2>&1

Running Command

cd /home/daytona/workspace/communication-stations-pptx && sed -i "s/\u201c/'/g; s/\u201d/'/g; s/\u2018/'/g; s/\u2019/'/g; s/\u2026/.../g" build.js && node build.js 2>&1

Running Command

python3 -c " import re with open('/home/daytona/workspace/communication-stations-pptx/build.js', 'r', encoding='utf-8') as f: content = f.read() # Replace curly quotes and ellipsis with plain ASCII content = content.replace('\u201c', \"'\").replace('\u201d', \"'\") content = content.replace('\u2018', \"'\").replace('\u2019', \"'\") content = content.replace('\u2026', '...') with open('/home/daytona/workspace/communication-stations-pptx/build.js', 'w', encoding='utf-8') as f: f.write(content) print('Done') "

Running Command

cd /home/daytona/workspace/communication-stations-pptx && node build.js 2>&1

Running Command

python3 -c " with open('/home/daytona/workspace/communication-stations-pptx/build.js', 'r', encoding='utf-8') as f: content = f.read() # The problem: curly quotes were replaced with plain double-quotes # We need to replace the inner double-quote characters that came from curly quotes # with escaped double quotes. # The pattern is: inside a JS string (delimited by double quotes), we have embedded double quotes # Easiest fix: replace any remaining ' that are quote chars with backtick-style or just remove quotes # Actually the simplest fix is to replace all remaining problematic lines manually. # Let's just replace the inner double-quote pairs with single quotes in text strings. # Strategy: replace ': \"...' pattern inside text fields with single quotes import re # Replace double-quote wrapped speech inside text: fields with single-quote versions # Pattern: text: \"...<inner stuff with double quotes>...\" # We'll use a simple replacement: convert all double-quote chars that appear after a space # inside a text field to be escaped # Simpler: just replace all double-quote characters that are immediately preceded/followed # by word chars (not a JS string boundary) with escaped double-quotes # Actually easiest: just use backtick template literals for ALL text strings # Even simpler: replace the offending ' chars (which are now \" from curly-to-plain conversion) # The inner quotes now appear as \" in the text values. Let's escape them. # Find all double-quote pairs that are INSIDE a string value (after 'text: ') # Replace with escaped versions # Method: replace \" occurrences inside text: \"...\" strings fixed = [] for line in content.split('\n'): if '{ text: ' in line or \"{ text: \" in line: # Find the string value between the outer quotes # Replace inner double-quotes with escaped ones # The line looks like: { text: \"word 'hello' word\", ...} # We need to escape any \" that appears after the first \" opener pass fixed.append(line) # Simpler approach: just replace all double-quote-space and space-double-quote # patterns that look like speech marks with single quotes content = content.replace('\"Hello Mrs. Banda', \"'Hello Mrs. Banda\") content = content.replace('[Name]...\"\"', \"[Name]...'\") content = content.replace('[Name]...\"', \"[Name]...'\") print(repr(content[content.find('Greet & establish'):content.find('Greet & establish')+200])) "

Running Command

python3 << 'PYEOF' import re with open('/home/daytona/workspace/communication-stations-pptx/build.js', 'r', encoding='utf-8') as f: content = f.read() # The problem: some text: "..." strings contain embedded " characters (from converted curly quotes) # Solution: for every text: "..." value, if the value contains a raw ", replace with escaped \" def fix_text_strings(content): # Find all text property values: text: "..." # We need to carefully handle strings that contain inner double-quotes result = [] i = 0 while i < len(content): # Look for text: " pattern match = re.search(r'{ text: "(.*?)"(?=,|\s*})', content[i:], re.DOTALL) if match: start = i + match.start() # The matched string content inner = match.group(1) if '"' in inner: # Need to escape inner double-quotes fixed_inner = inner.replace('"', '\\"') old = '{ text: "' + inner + '"' new = '{ text: "' + fixed_inner + '"' content = content[:start] + new + content[start + len(old):] i = start + len(new) else: i = start + match.end() else: break return content # Actually simpler: just replace the specific problematic patterns globally replacements = [ # Slide 8 rubric lines with inner quotes ('"Greet & establish rapport: "Hello Mrs. Banda, my name is Dr. [Name]...""', '"Greet & establish rapport: Hello Mrs. Banda, my name is Dr. [Name]..."'), ('"Check baseline knowledge: "What do you already know about high blood pressure?""', '"Check baseline knowledge: What do you already know about high blood pressure?"'), ('"Use simple terms: "Hypertension means your blood pressure is consistently higher than normal.""', '"Use simple terms: Hypertension means your blood pressure is consistently higher than normal."'), ('"The force of blood pushes against your arteries', '"Blood pushes against your arteries'), ('"Clarify: "Often symptomless', '"Clarify: Often symptomless'), ('"Often doesn\'t cause symptoms', '"Often no symptoms'), ('"Emphasise control, not cure: "Hypertension can\'t usually be cured, but it can be controlled.""', '"Emphasise control, not cure: Hypertension cannot usually be cured, but it can be controlled."'), ('"Medication Adherence: "Take tablets daily as directed, even if you feel well.""', '"Medication Adherence: Take tablets daily as directed, even if you feel well."'), ('""Take tablets daily as directed, even if you feel well.""', '"Take tablets daily as directed, even if you feel well."'), ('""I understand this may be worrying, but many people manage hypertension successfully.""', '"Acknowledge feelings: I understand this may be worrying - many people manage hypertension successfully."'), ('""Hypertension means your BP is high, but with lifestyle changes, monitoring, and medication we can control it.""', '"Summarise: Hypertension means your BP is high - with lifestyle changes, monitoring, and medication we can control it."'), ('""Do you have any concerns or questions at this stage?""', '"Invite questions: Do you have any concerns or questions?"'), ('""With good management, you can live a long and healthy life. We\'ll support you throughout.""', '"End positively: With good management, you can live a long and healthy life."'), ] for old, new in replacements: content = content.replace(old, new) # Now use regex to catch any remaining embedded double-quotes inside text: "..." strings # Pattern: text: "something "quoted" something" # Replace inner quotes with nothing or escaped lines = content.split('\n') fixed_lines = [] for line in lines: m = re.match(r'^(\s*\{ text: )"(.*)"(,\s*.*)?$', line) if m: prefix = m.group(1) inner = m.group(2) suffix = m.group(3) or '' if '"' in inner: inner = inner.replace('"', '') fixed_lines.append(prefix + '"' + inner + '"' + suffix) else: fixed_lines.append(line) content = '\n'.join(fixed_lines) with open('/home/daytona/workspace/communication-stations-pptx/build.js', 'w', encoding='utf-8') as f: f.write(content) print("Done. Checking for syntax issues...") # Quick check import subprocess result = subprocess.run(['node', '--check', '/home/daytona/workspace/communication-stations-pptx/build.js'], capture_output=True, text=True) print("STDOUT:", result.stdout) print("STDERR:", result.stderr) print("RC:", result.returncode) PYEOF

Running Command

cd /home/daytona/workspace/communication-stations-pptx && node build.js 2>&1

The file was built successfully. Here's your presentation:

Communication Stations OSCE

Presentation · PPTX


What's inside — 11 slides:
#Slide
1Title — Communication Stations: OSCE Preparation Guide
2What Are Communication Stations?
3Key Tips (1 of 2)
4Key Tips (2 of 2)
5Consultation Template — Overview (4 cards)
6Consultation Template — Decision-Making & Closing (3 cards)
7Station 6 title card — Newly Diagnosed Hypertensive Patient
8Marking Rubric — Introduction & Explanation
9Marking Rubric — Lifestyle & Monitoring
10Marking Rubric — Psychosocial Support & Safety-Netting
11Key Takeaways
Design choices: Navy blue dominant background, teal header bars, gold accent stripe and highlights, off-white body text, card-layout slides for the template sections to avoid wall-of-bullets fatigue.
This is a shared conversation. Sign in to Orris to start your own chat.