Give me a pdf that would be enough to diagnose and ecg correctly with its treatment don't generate boring pdf make it colourful with animations and don't miss any concepts I know some what ecg please help me to be better add some more details and more detailed easy and simple explanation keep details vast and include treatment too bro and keep colour radiant and add cartoonisitc and animated images generate more attractive pdf this is best this details should be there but add more with modification I mentioned plz help me out with it and at end of every page introduce a footer of my name mihir and give page number with a boundary it should be attractive create a pdf of it
mkdir -p /tmp/workspace/ecg-pdf && ls /tmp/workspace/
Give me a pdf that would be enough to diagnose and ecg correctly with its treatment don't generate boring pdf make it colourful with animations and don't miss any concepts I know some what ecg please help me to be better add some more details and more detailed easy and simple explanation keep details vast and include treatment too bro and keep colour radiant and add cartoonisitc and animated images generate more attractive pdf this is best this details should be there but add more with modification I mentioned plz help me out with it and at end of every page introduce a footer of my name mihir and give page number with a boundary it should be attractive create a pdf of it
mkdir -p /tmp/workspace/ecg-pdf && echo "Ready"
Why so much time
cat << 'PYEOF' > /tmp/workspace/ecg-pdf/build_ecg.py from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import mm, cm from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak, HRFlowable) from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY from reportlab.platypus.flowables import Flowable from reportlab.pdfgen import canvas from reportlab.graphics.shapes import Drawing, Rect, Circle, Ellipse, Line, Polygon, String, Path from reportlab.graphics import renderPDF import math, os OUTPUT = "/tmp/workspace/ecg-pdf/ECG_MasterGuide_Mihir.pdf" W, H = A4 # 595 x 842 pts # ββ Colour palette ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ C_BG = colors.HexColor("#0D1B2A") # deep navy C_CARD1 = colors.HexColor("#1A2E4A") C_CARD2 = colors.HexColor("#112233") C_ACCENT1 = colors.HexColor("#FF6B6B") # coral red C_ACCENT2 = colors.HexColor("#FFD93D") # sunny yellow C_ACCENT3 = colors.HexColor("#6BCB77") # mint green C_ACCENT4 = colors.HexColor("#4D96FF") # electric blue C_ACCENT5 = colors.HexColor("#FF922B") # orange C_ACCENT6 = colors.HexColor("#CC5DE8") # purple C_WHITE = colors.white C_LTGRAY = colors.HexColor("#C8D6E5") C_GOLD = colors.HexColor("#FFD700") C_PINK = colors.HexColor("#FF69B4") C_CYAN = colors.HexColor("#00D4FF") C_LIME = colors.HexColor("#AAFF00") # ββ Page background + border + footer drawn on every page βββββββββββββββββββ def on_page(canv, doc): canv.saveState() # full-page gradient background simulation canv.setFillColor(C_BG) canv.rect(0, 0, W, H, fill=1, stroke=0) # decorative corner squares sz = 18 for x, y in [(0,0),(W-sz,0),(0,H-sz),(W-sz,H-sz)]: canv.setFillColor(C_ACCENT2) canv.rect(x, y, sz, sz, fill=1, stroke=0) # outer rainbow border (4 nested rectangles) border_cols = [C_ACCENT4, C_ACCENT3, C_ACCENT1, C_ACCENT2] for i, bc in enumerate(border_cols): off = 6 + i*4 canv.setStrokeColor(bc) canv.setLineWidth(2.5 - i*0.4) canv.roundRect(off, off, W-2*off, H-2*off, 12-i*2, fill=0, stroke=1) # heartbeat line across the top canv.setStrokeColor(C_ACCENT1) canv.setLineWidth(2) p = canv.beginPath() segs = [(0,H-28),(60,H-28),(70,H-8),(80,H-48),(90,H-8),(100,H-28),(W,H-28)] p.moveTo(*segs[0]) for pt in segs[1:]: p.lineTo(*pt) canv.drawPath(p) # ββ FOOTER ββ footer_y = 20 canv.setFillColor(C_ACCENT2) canv.roundRect(30, footer_y-4, W-60, 22, 6, fill=1, stroke=0) canv.setFillColor(C_BG) canv.setFont("Helvetica-Bold", 9) canv.drawCentredString(W/2, footer_y+4, f"β¦ MIHIR β¦ ECG MasterGuide β¦ Page {doc.page} β¦") canv.restoreState() # ββ Helper Flowables ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ class ColorBox(Flowable): """A coloured rounded-rect box drawn behind some text β used as section dividers.""" def __init__(self, text, bg=C_ACCENT4, fg=C_WHITE, font="Helvetica-Bold", fsize=14, radius=10, pad=8, width=None): super().__init__() self.text = text self.bg = bg self.fg = fg self.font = font self.fsize = fsize self.radius= radius self.pad = pad self._w = width or (W - 100) self.height= fsize + 2*pad + 4 def wrap(self, aW, aH): return (self._w, self.height) def draw(self): c = self.canv c.setFillColor(self.bg) c.roundRect(0, 0, self._w, self.height, self.radius, fill=1, stroke=0) c.setFillColor(self.fg) c.setFont(self.font, self.fsize) c.drawCentredString(self._w/2, self.pad+2, self.text) class ECGWave(Flowable): """Draws a realistic cartoon ECG trace with labelled waves.""" def __init__(self, width=460, height=130): super().__init__() self._w = width self._h = height def wrap(self, aW, aH): return (self._w, self._h) def draw(self): c = self.canv w, h = self._w, self._h baseline = h * 0.42 # grid c.setStrokeColor(colors.HexColor("#1A4A2A")) c.setLineWidth(0.4) for gx in range(0, int(w)+1, 20): c.line(gx, 0, gx, h*0.85) for gy in range(0, int(h*0.85)+1, 20): c.line(0, gy, w, gy) # bold grid every 100px c.setStrokeColor(colors.HexColor("#2A7A4A")) c.setLineWidth(0.8) for gx in range(0, int(w)+1, 100): c.line(gx, 0, gx, h*0.85) # ECG waveform points (two beats) def beat(ox): return [ (ox+0, baseline), # start (ox+20, baseline), # flat (ox+28, baseline+8), # P wave up (ox+36, baseline+8), (ox+40, baseline), # P down (ox+55, baseline), # PR flat (ox+58, baseline-5), # Q dip (ox+62, baseline+55), # R peak (ox+66, baseline-12), # S dip (ox+72, baseline), # back to base (ox+80, baseline), (ox+88, baseline+6), # T wave (ox+100, baseline+18), (ox+112, baseline+6), (ox+120, baseline), (ox+150, baseline), # TP flat ] pts1 = beat(10) pts2 = beat(10+150) all_pts = pts1 + pts2[1:] c.setStrokeColor(C_ACCENT3) c.setLineWidth(2.5) p = c.beginPath() p.moveTo(*all_pts[0]) for pt in all_pts[1:]: p.lineTo(*pt) c.drawPath(p) # Labels c.setFont("Helvetica-Bold", 9) labels = [ (pts1[2][0]+2, pts1[2][1]+12, "P", C_ACCENT2), (pts1[7][0]-4, pts1[7][1]+6, "R", C_ACCENT1), (pts1[10][0], pts1[10][1]-14, "Q", C_CYAN), (pts1[11][0]-2, pts1[11][1]-14, "S", C_PINK), (pts1[14][0]+2, pts1[14][1]+20, "T", C_ACCENT3), (pts1[0][0]+2, pts1[0][1]-14, "PR int",C_LTGRAY), (pts1[8][0]+4, pts1[8][1]-14, "QRS", C_ACCENT5), (pts1[12][0]+2, pts1[12][1]+6, "ST", C_ACCENT4), ] for lx, ly, txt, col in labels: c.setFillColor(col) c.drawString(lx, ly, txt) # Baseline dashed c.setStrokeColor(C_LTGRAY) c.setDash(4, 3) c.setLineWidth(0.7) c.line(0, baseline, w, baseline) c.setDash() class HeartCartoon(Flowable): """Simple cartoon heart with face.""" def __init__(self, size=80): super().__init__() self.size = size def wrap(self, aW, aH): return (self.size, self.size) def draw(self): c = self.canv s = self.size cx, cy = s/2, s/2 - 4 # heart shape using bezier curves c.setFillColor(C_ACCENT1) c.setStrokeColor(colors.HexColor("#FF0000")) c.setLineWidth(2) p = c.beginPath() # left bump p.moveTo(cx, cy - s*0.15) p.curveTo(cx - s*0.05, cy + s*0.25, cx - s*0.45, cy + s*0.25, cx - s*0.45, cy) p.curveTo(cx - s*0.45, cy - s*0.25, cx, cy - s*0.4, cx, cy - s*0.15) # right bump p.moveTo(cx, cy - s*0.15) p.curveTo(cx + s*0.05, cy + s*0.25, cx + s*0.45, cy + s*0.25, cx + s*0.45, cy) p.curveTo(cx + s*0.45, cy - s*0.25, cx, cy - s*0.4, cx, cy - s*0.15) c.drawPath(p, fill=1, stroke=1) # face eyes c.setFillColor(C_WHITE) c.circle(cx - s*0.12, cy + s*0.05, s*0.06, fill=1, stroke=0) c.circle(cx + s*0.12, cy + s*0.05, s*0.06, fill=1, stroke=0) c.setFillColor(C_BG) c.circle(cx - s*0.10, cy + s*0.05, s*0.03, fill=1, stroke=0) c.circle(cx + s*0.10, cy + s*0.05, s*0.03, fill=1, stroke=0) # smile c.setStrokeColor(C_BG) c.setLineWidth(1.5) p2 = c.beginPath() p2.moveTo(cx - s*0.10, cy - s*0.04) p2.curveTo(cx - s*0.05, cy - s*0.12, cx + s*0.05, cy - s*0.12, cx + s*0.10, cy - s*0.04) c.drawPath(p2, fill=0, stroke=1) class RhythmStrip(Flowable): """Draws various cartoon rhythm strips labelled by type.""" RHYTHMS = { "Normal Sinus": "normal", "A-Fib": "afib", "V-Fib": "vfib", "V-Tach": "vtach", "Heart Block 3rd": "chb", "ST Elevation": "stemi", } def __init__(self, rtype="normal", width=420, height=70, label=""): super().__init__() self.rtype = rtype self._w = width self._h = height self.label = label def wrap(self, aW, aH): return (self._w, self._h) def draw(self): c = self.canv w, h = self._w, self._h bl = h * 0.5 # background c.setFillColor(colors.HexColor("#0A1F0A")) c.roundRect(0, 0, w, h, 6, fill=1, stroke=0) # grid c.setStrokeColor(colors.HexColor("#143D14")) c.setLineWidth(0.5) for gx in range(0, int(w), 15): c.line(gx, 4, gx, h-4) for gy in range(4, int(h), 15): c.line(0, gy, w, gy) c.setStrokeColor(C_ACCENT3) c.setLineWidth(2) if self.rtype == "normal": pts = [] for b in range(5): ox = b * 80 + 10 pts += [(ox, bl),(ox+10,bl),(ox+14,bl+7),(ox+18,bl), (ox+23,bl),(ox+25,bl-3),(ox+28,bl+28),(ox+31,bl-7), (ox+34,bl),(ox+40,bl+9),(ox+48,bl),(ox+55,bl)] elif self.rtype == "afib": import random; random.seed(42) pts = [(0, bl)] x = 0 while x < w: x += random.randint(3, 9) pts.append((x, bl + random.randint(-5, 5))) # occasional QRS for b in [60, 160, 255, 340]: pts += [(b, bl),(b+2, bl+25),(b+4, bl-8),(b+6, bl)] elif self.rtype == "vfib": import random; random.seed(7) pts = [(0, bl)] x = 0 while x < w: x += random.randint(2, 8) pts.append((x, bl + random.randint(-22, 22))) elif self.rtype == "vtach": pts = [] for b in range(8): ox = b * 52 pts += [(ox,bl),(ox+5,bl),(ox+8,bl+24),(ox+14,bl-10), (ox+18,bl),(ox+30,bl+8),(ox+38,bl+8),(ox+45,bl),(ox+52,bl)] elif self.rtype == "chb": # P waves march independently, wide QRS slow pts = [] for pp in range(12): ox = pp*35+5 pts += [(ox,bl),(ox+4,bl+6),(ox+8,bl)] c.setStrokeColor(C_ACCENT4) c.setLineWidth(2) p2 = c.beginPath() p2.moveTo(5, bl) for pp in range(12): ox = pp*35+5 p2.lineTo(ox, bl); p2.lineTo(ox+4,bl+6); p2.lineTo(ox+8,bl) c.drawPath(p2, stroke=1, fill=0) # slow QRS c.setStrokeColor(C_ACCENT1) pts = [] for b in range(3): ox = b*145+30 pts += [(ox,bl),(ox+5,bl-4),(ox+10,bl+32),(ox+16,bl-10),(ox+22,bl)] elif self.rtype == "stemi": pts = [] for b in range(4): ox = b*100+10 pts += [(ox,bl),(ox+10,bl),(ox+14,bl+7),(ox+18,bl), (ox+22,bl-3),(ox+26,bl+38),(ox+30,bl-8), (ox+34,bl+14),(ox+50,bl+14), # ST elevation (ox+55,bl+10),(ox+65,bl),(ox+75,bl)] if self.rtype not in ("chb",): p = c.beginPath() if pts: p.moveTo(*pts[0]) for pt in pts[1:]: p.lineTo(*pt) c.drawPath(p, stroke=1, fill=0) elif self.rtype == "chb": p = c.beginPath() if pts: p.moveTo(*pts[0]) for pt in pts[1:]: p.lineTo(*pt) c.setStrokeColor(C_ACCENT1) c.drawPath(p, stroke=1, fill=0) # label if self.label: c.setFillColor(C_ACCENT2) c.setFont("Helvetica-Bold", 8) c.drawString(6, h-14, self.label) class BulletBox(Flowable): """Coloured pill-shaped bullet row.""" def __init__(self, items, bg=C_CARD1, accent=C_ACCENT4, width=None, font_size=10): super().__init__() self.items = items self.bg = bg self.accent = accent self._w = width or (W - 100) self.fs = font_size self.lh = font_size + 8 self.height = len(items) * self.lh + 16 def wrap(self, aW, aH): return (self._w, self.height) def draw(self): c = self.canv c.setFillColor(self.bg) c.roundRect(0, 0, self._w, self.height, 10, fill=1, stroke=0) y = self.height - self.lh for item in self.items: # bullet circle c.setFillColor(self.accent) c.circle(14, y + self.fs*0.35, 5, fill=1, stroke=0) c.setFillColor(C_WHITE) c.setFont("Helvetica", self.fs) c.drawString(26, y, item) y -= self.lh # ββ Paragraph styles ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ styles = getSampleStyleSheet() def S(name, **kw): return ParagraphStyle(name, **kw) title_style = S("MyTitle", fontSize=32, textColor=C_ACCENT2, fontName="Helvetica-Bold", alignment=TA_CENTER, spaceAfter=6, leading=38) subtitle_style = S("MySub", fontSize=16, textColor=C_CYAN, fontName="Helvetica-BoldOblique", alignment=TA_CENTER, spaceAfter=4) h1 = S("H1", fontSize=18, textColor=C_ACCENT2, fontName="Helvetica-Bold", spaceBefore=10, spaceAfter=4, leading=22) h2 = S("H2", fontSize=14, textColor=C_CYAN, fontName="Helvetica-Bold", spaceBefore=6, spaceAfter=3, leading=18) h3 = S("H3", fontSize=12, textColor=C_ACCENT3, fontName="Helvetica-Bold", spaceBefore=4, spaceAfter=2) body = S("Body", fontSize=10, textColor=C_LTGRAY, fontName="Helvetica", spaceBefore=3, spaceAfter=3, leading=14, alignment=TA_JUSTIFY) emph = S("Emph", fontSize=10, textColor=C_ACCENT2, fontName="Helvetica-BoldOblique", spaceBefore=2, spaceAfter=2) small = S("Small", fontSize=8, textColor=C_LTGRAY, fontName="Helvetica", spaceBefore=1, spaceAfter=1) def H(txt, st=h1): return Paragraph(txt, st) def B(txt): return Paragraph(txt, body) def SP(n=6): return Spacer(1, n) def colored_table(data, col_widths, header_bg=C_ACCENT4): t = Table(data, colWidths=col_widths) style = TableStyle([ ("BACKGROUND", (0,0), (-1,0), header_bg), ("TEXTCOLOR", (0,0), (-1,0), C_WHITE), ("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"), ("FONTSIZE", (0,0), (-1,0), 10), ("ALIGN", (0,0), (-1,-1), "CENTER"), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ("ROWBACKGROUNDS", (0,1), (-1,-1), [C_CARD1, C_CARD2]), ("TEXTCOLOR", (0,1), (-1,-1), C_LTGRAY), ("FONTNAME", (0,1), (-1,-1), "Helvetica"), ("FONTSIZE", (0,1), (-1,-1), 9), ("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#2A4A6A")), ("ROUNDEDCORNERS", [6]), ("TOPPADDING", (0,0), (-1,-1), 5), ("BOTTOMPADDING",(0,0), (-1,-1), 5), ]) t.setStyle(style) return t # ββ Build story βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story = [] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 1 β COVER # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(40), HeartCartoon(size=110), SP(10), Paragraph("ECG MASTER GUIDE", title_style), Paragraph("Complete Diagnosis + Treatment Atlas", subtitle_style), SP(6), Paragraph("β Waves β Intervals β Rhythms β Arrhythmias β STEMI β Blocks β Treatment β", S("cover_sub", fontSize=11, textColor=C_ACCENT3, fontName="Helvetica-BoldOblique", alignment=TA_CENTER)), SP(10), ECGWave(width=460, height=130), SP(12), ColorBox("π Made with β€ for Mihir β Your Pocket ECG Bible π", bg=C_ACCENT1, fg=C_WHITE, fsize=12, radius=14), SP(8), Paragraph("Crafted to make you an ECG Expert β¦ Every concept, every arrhythmia, every treatment", S("foot2", fontSize=9, textColor=C_LTGRAY, alignment=TA_CENTER)), PageBreak(), ] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 2 β WHAT IS AN ECG? # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(8), ColorBox("β‘ CHAPTER 1 : WHAT IS AN ECG?", bg=C_ACCENT4, fsize=16), SP(8), H("What is an ECG (Electrocardiogram)?", h1), B("An ECG is a graphical recording of the electrical activity of the heart over time. " "Every time the heart beats, tiny electrical signals travel through the heart muscle. " "These signals can be detected by electrodes placed on the skin and plotted as waves " "on graph paper (or screen). Think of it as the heart's own <b>WhatsApp message</b> β " "it tells you what's happening inside!"), SP(6), H("Why is ECG So Important?", h2), BulletBox([ "Detect heart attacks (MI) within minutes", "Identify life-threatening arrhythmias (V-Fib, V-Tach)", "Diagnose heart blocks and conduction defects", "Assess drug toxicity (e.g., digoxin, quinidine)", "Monitor electrolyte imbalances (K+, Ca2+)", "Screen athletes and pre-op patients", "Evaluate pacemaker function", ], accent=C_ACCENT4), SP(8), H("The ECG Paper β Your Canvas", h2), B("Standard ECG paper runs at <b>25 mm/sec</b>. Each small square = 1 mm = 0.04 sec. " "Each large square = 5 mm = 0.2 sec. Voltage: 1 mV = 10 mm (10 small boxes) in amplitude."), SP(6), colored_table( [["Parameter", "Small Box", "Large Box", "Standard Value"], ["Time (width)", "0.04 sec", "0.2 sec", "25 mm/s paper speed"], ["Voltage (height)","0.1 mV", "0.5 mV", "1 mV = 10 mm"], ["Boxes per second","25 small", "5 large", "β"], ["Normal HR calc", "300/large sq","1500/small sq","60-100 bpm"]], [120, 90, 90, 140] ), SP(8), H("The 12-Lead System β 12 Views of the Heart", h2), B("Just like photographing a building from 12 angles, 12 leads give 12 different views " "of the same electrical event. They are grouped into:"), BulletBox([ "Limb leads: I, II, III (frontal plane β left/right/up/down)", "Augmented limb leads: aVR, aVL, aVF (augmented unipolar)", "Precordial (chest) leads: V1 to V6 (horizontal plane β front/back)", "Each lead 'looks' at a different wall of the heart", ], accent=C_ACCENT3), SP(6), colored_table( [["Lead Group", "Leads", "Wall Viewed", "Artery"], ["Inferior", "II, III, aVF", "Inferior wall", "RCA"], ["Lateral", "I, aVL, V5, V6", "Lateral wall", "LCx"], ["Anterior", "V1βV4", "Anterior wall", "LAD"], ["Septal", "V1, V2", "Septum", "LAD"], ["Right ventricular","V1, V4R", "Right ventricle", "RCA"], ["Posterior", "V7βV9 (reciprocal)","Posterior wall","LCx/RCA"]], [100, 110, 120, 110] ), PageBreak(), ] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 3 β WAVES, INTERVALS, SEGMENTS # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(8), ColorBox("π CHAPTER 2 : WAVES, INTERVALS & SEGMENTS", bg=C_ACCENT3, fg=C_BG, fsize=16), SP(6), ECGWave(width=460, height=140), SP(6), H("The P Wave β Atrial Depolarisation", h2), BulletBox([ "Represents: SA node fires β both atria contract", "Normal: Upright in I, II, aVF; biphasic in V1", "Duration: < 0.12 sec (3 small boxes)", "Amplitude: < 2.5 mm in limb leads, < 1.5 mm in V1", "Absent P wave = AF, junctional rhythm, or SA block", "Tall peaked P (>2.5 mm) = P pulmonale (RA enlargement)", "Broad notched P = P mitrale (LA enlargement)", ], accent=C_ACCENT2), SP(6), H("The QRS Complex β Ventricular Depolarisation", h2), BulletBox([ "Q wave: First negative deflection β septal depolarisation", "R wave: First positive deflection β main ventricular depolarisation", "S wave: First negative deflection after R", "Normal QRS duration: 0.06β0.10 sec (< 3 small boxes)", "Wide QRS (>0.12 sec) = BBB, WPW, ventricular rhythm, hyperkalaemia", "Pathological Q: > 0.04 sec wide OR > 1/3 of R height = old MI", "Tall R in V1 = RVH, RBBB, posterior MI, WPW", ], accent=C_ACCENT1), SP(6), H("The T Wave β Ventricular Repolarisation", h2), BulletBox([ "Normally upright in I, II, V3βV6; inverted in aVR, V1 (normal)", "Tall peaked T = hyperkalaemia (early), hyperacute STEMI", "Inverted T = ischaemia, PE, hypertrophy, BBB, digoxin", "Flattened T = hypokalaemia, hypothyroidism, ischaemia", ], accent=C_ACCENT3), SP(6), H("The U Wave", h2), B("Small deflection after T wave. Best seen in V2βV3. Prominent U = hypokalaemia, " "bradycardia, hypothermia. Inverted U = ischaemia, LVH."), SP(6), colored_table( [["Interval/Segment","Duration (Normal)","What it measures", "Abnormal = "], ["PR interval", "0.12β0.20 sec", "AV node conduction", "Heart block / WPW"], ["QRS duration", "0.06β0.10 sec", "Ventricular depol.", "BBB / hyperkalaemia"], ["QT interval", "< 0.44 sec (men)", "Total ventricular act.", "Long QT syndrome"], ["QTc (Bazett)", "< 0.44 s", "Rate-corrected QT", "TdP risk"], ["ST segment", "Isoelectric", "Early repolarisation", "STEMI / NSTEMI"], ["PR segment", "Isoelectric", "AV node + Bundle", "Pericarditis (dep.)"]], [110, 100, 140, 120] ), PageBreak(), ] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 4 β SYSTEMATIC APPROACH # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(8), ColorBox("π CHAPTER 3 : SYSTEMATIC ECG READING β STEP BY STEP", bg=C_ACCENT5, fg=C_WHITE, fsize=15), SP(6), H("The 8-Step Approach (Never Miss Anything!)", h1), B("Always read an ECG systematically. Never jump to conclusions. Follow these 8 steps every single time:"), SP(4), colored_table( [["Step", "What to Check", "How to do it", "Normal Value"], ["1", "Rate", "300 Γ· large boxes between R-R", "60β100 bpm"], ["2", "Rhythm", "Regular? P before every QRS?", "Regular sinus"], ["3", "Axis", "QRS in I & aVF β both positive?", "β30Β° to +90Β°"], ["4", "P wave", "Present, upright in II, uniform?", "< 0.12 s"], ["5", "PR interval", "Measure from P start to QRS start", "0.12β0.20 s"], ["6", "QRS complex", "Width, morphology, pathological Q?", "< 0.10 s"], ["7", "ST segment & T wave", "Elevation, depression, inversion?", "Isoelectric"], ["8", "QT interval", "QTc = QT Γ· βRR (Bazett formula)", "< 0.44 s"]], [30, 110, 200, 100] ), SP(8), H("STEP 1 β Heart Rate Calculation", h2), BulletBox([ "METHOD 1 (fast): 300 Γ· number of large squares between two R peaks", "METHOD 2 (accurate): 1500 Γ· number of small squares between R-R", "METHOD 3 (irregular rhythms): Count QRS in 6 sec strip Γ 10", "Bradycardia: HR < 60 bpm | Tachycardia: HR > 100 bpm", "Extreme brady < 40 bpm β think complete heart block, hypothermia", "Extreme tachy > 150 bpm β think SVT, VT, AF with rapid ventricular response", ], accent=C_ACCENT2), SP(6), H("STEP 3 β Cardiac Axis", h2), B("The axis tells us the overall direction of ventricular depolarisation."), colored_table( [["Axis", "Lead I", "Lead aVF", "Causes"], ["Normal (β30 to +90Β°)","Positive","Positive","Normal"], ["LAD (< β30Β°)", "Positive", "Negative", "LBBB, LAHB, inferior MI, LVH"], ["RAD (> +90Β°)", "Negative", "Positive", "RBBB, LPHB, RVH, PE, dextrocardia"], ["Extreme/NW axis","Negative", "Negative", "VT, severe RVH, pacing"]], [120, 70, 70, 200] ), SP(6), H("Quick Axis Mnemonic", h3), BulletBox([ "Both positive β NORMAL β ", "Lead I positive + aVF negative β LEFT axis deviation (LAD) β¬ ", "Lead I negative + aVF positive β RIGHT axis deviation (RAD) β‘", "Both negative β EXTREME axis (North-West) β ", ], accent=C_ACCENT6, bg=C_CARD2), PageBreak(), ] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 5 β RHYTHMS NORMAL + SINUS VARIATIONS # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(8), ColorBox("π CHAPTER 4 : SINUS RHYTHMS & BASIC ARRHYTHMIAS", bg=C_ACCENT6, fg=C_WHITE, fsize=15), SP(6), H("Normal Sinus Rhythm (NSR)", h2), RhythmStrip("normal", label="Normal Sinus Rhythm β Rate 60-100, Regular, P before every QRS"), SP(4), BulletBox([ "Rate: 60β100 bpm", "P wave: upright in II, inverted in aVR, before every QRS", "PR interval: 0.12β0.20 sec (constant)", "QRS: < 0.10 sec (narrow)", "Regular rhythm", ], accent=C_ACCENT3), SP(8), H("Sinus Bradycardia", h2), BulletBox([ "Rate < 60 bpm, otherwise normal morphology", "Causes: Athletes, vagal tone, hypothyroidism, hypothermia, beta-blockers, inferior MI", "Symptoms: Dizziness, syncope, fatigue", "Treatment: Asymptomatic β no treatment | Symptomatic β Atropine 0.5 mg IV, " "consider pacing if refractory", ], accent=C_CYAN), SP(6), H("Sinus Tachycardia", h2), BulletBox([ "Rate 100β150 bpm, normal P waves, regular", "Causes: Pain, fever, anaemia, PE, hypovolaemia, anxiety, thyrotoxicosis, heart failure", "ALWAYS treat the underlying cause β not the rate itself", "Treatment: Treat precipitant (fluids for shock, antipyretics for fever, etc.)", ], accent=C_ACCENT5), SP(6), H("Sinus Arrhythmia", h2), B("Rate varies with breathing β increases on inspiration, decreases on expiration. " "Normal in young patients and athletes. P wave morphology is normal. No treatment needed."), SP(6), H("Sinus Pause / Arrest", h2), BulletBox([ "Sudden absence of P waves β SA node fails to fire", "If pause > 3 sec β symptomatic, requires treatment", "Causes: Vagal stimulation, sick sinus syndrome, digoxin toxicity", "Treatment: Atropine, permanent pacemaker if recurrent", ], accent=C_ACCENT1), SP(6), H("Sick Sinus Syndrome (SSS)", h2), BulletBox([ "Also called Tachy-Brady syndrome", "Alternates between sinus tachycardia and profound bradycardia/arrest", "Causes: Fibrosis of SA node, ischaemia, cardiomyopathy", "Treatment: Permanent dual-chamber pacemaker (DDD) β DEFINITIVE treatment", ], accent=C_GOLD), PageBreak(), ] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 6 β ATRIAL ARRHYTHMIAS # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(8), ColorBox("π΄ CHAPTER 5 : ATRIAL ARRHYTHMIAS", bg=C_ACCENT1, fg=C_WHITE, fsize=15), SP(6), H("Premature Atrial Complex (PAC)", h2), BulletBox([ "Early P wave with different morphology (ectopic atrial focus)", "QRS usually narrow (< 0.10 sec), followed by incomplete compensatory pause", "Causes: Caffeine, alcohol, stress, electrolyte imbalance", "Treatment: Usually benign β reassure, avoid triggers", ], accent=C_ACCENT4), SP(6), H("Atrial Flutter", h2), BulletBox([ "Atrial rate 250β350 bpm, ventricular rate varies (2:1, 3:1, 4:1 block)", "CLASSIC: Sawtooth flutter waves (F waves) best seen in II, III, aVF", "Regular rhythm if fixed block (2:1 β HR ~150 bpm)", "Causes: Ischaemia, RHD, PE, post-cardiac surgery, thyrotoxicosis", "Treatment: Rate control (beta-blocker, CCB, digoxin) OR rhythm control " "(cardioversion, ablation). Anticoagulate if > 48 hrs", ], accent=C_ACCENT2), SP(6), H("Atrial Fibrillation (AF) β The MOST Common Arrhythmia", h2), RhythmStrip("afib", label="ATRIAL FIBRILLATION β Irregularly irregular, no P waves, chaotic baseline"), SP(4), BulletBox([ "No discernible P waves β replaced by irregular chaotic f waves", "Irregularly IRREGULAR ventricular rhythm (key diagnostic feature!)", "Atrial rate 350β600 bpm, ventricular rate variable", "Causes: HTN, IHD, mitral valve disease, thyrotoxicosis, alcohol (holiday heart), PE", "CHADSVASC score for stroke risk stratification", ], accent=C_ACCENT1), SP(4), H("AF Treatment", h2), colored_table( [["Goal", "Drug / Method", "Notes"], ["Rate Control", "Beta-blockers (metoprolol, bisoprolol)","Target HR < 110 bpm at rest"], ["Rate Control", "CCBs (diltiazem, verapamil)", "Avoid in HF with low EF"], ["Rate Control", "Digoxin", "Useful in HF, sedentary"], ["Rhythm Control", "Electrical cardioversion (DCCV)", "Synchronised 200J biphasic"], ["Rhythm Control", "Flecainide / Propafenone", "Pill-in-pocket (no struct. disease)"], ["Rhythm Control", "Amiodarone", "AF + heart failure or LVH"], ["Anticoagulation", "DOACs (Apixaban, Rivaroxaban)", "CHA2DS2-VASc β₯ 2 in men, β₯ 3 women"], ["Anticoagulation", "Warfarin (target INR 2β3)", "Valvular AF, CKD, mechanical valve"], ["Ablation", "Pulmonary vein isolation (PVI)", "Symptomatic paroxysmal AF"]], [100, 170, 170] ), SP(6), H("SVT β Supraventricular Tachycardia", h2), BulletBox([ "Narrow complex tachycardia, rate 150β250 bpm, regular", "Sudden onset & offset (paroxysmal)", "P waves hidden in or after QRS", "Types: AVNRT (most common), AVRT (WPW), Atrial Tachycardia", "TREATMENT: Vagal manoeuvres β Adenosine 6 mg IV (then 12 mg) β " "Verapamil/Beta-blocker β DCCV if haemodynamically unstable", ], accent=C_ACCENT6), PageBreak(), ] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 7 β VENTRICULAR ARRHYTHMIAS # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(8), ColorBox("β CHAPTER 6 : VENTRICULAR ARRHYTHMIAS β CRITICAL!", bg=C_ACCENT1, fg=C_WHITE, fsize=15), SP(6), H("PVCs β Premature Ventricular Complexes", h2), BulletBox([ "Early, WIDE (>0.12 sec), bizarre QRS β no preceding P wave", "Full compensatory pause follows", "Uniform PVCs = same focus | Multiform = multiple foci (worse)", "Bigeminy: every other beat is PVC | Trigeminy: every 3rd beat", "Couplet: 2 PVCs in a row | Triplet: 3 = non-sustained VT", "Causes: IHD, hypokalaemia, hypoxia, caffeine, stimulants, cardiomyopathy", "Treatment: Benign in normal hearts. Treat if symptomatic: Beta-blockers. " "Ablation if very frequent (>10000/day).", ], accent=C_ACCENT5), SP(6), H("Ventricular Tachycardia (VT)", h2), RhythmStrip("vtach", label="VENTRICULAR TACHYCARDIA β Wide QRS, rate 120-250, may lose pulse"), SP(4), BulletBox([ "β₯ 3 consecutive PVCs at rate > 100 bpm", "Wide QRS (>0.12 sec), bizarre morphology", "AV dissociation (P waves march independently) β pathognomonic!", "Capture beats + fusion beats confirm VT", "Monomorphic VT: uniform QRS β usually ischaemic scar", "Polymorphic VT: changing QRS β ischaemia, long QT, Brugada", "Sustained VT (> 30 sec) = EMERGENCY", ], accent=C_ACCENT1), SP(4), H("VT Treatment", h2), colored_table( [["Situation", "Treatment", "Notes"], ["Pulseless VT", "Immediate defibrillation 200J", "CPR between shocks"], ["VT with pulse (unstable)","Synchronised DCCV 100-200J", "Sedate first if possible"], ["VT with pulse (stable)","Amiodarone 300mg IV over 20-60min","Can also try Lidocaine"], ["Post-resuscitation", "IV amiodarone infusion", "1mg/min for 6hrs, then 0.5mg/min"], ["Recurrent VT", "ICD implantation", "Gold standard for secondary prevention"], ["Structural heart disease","Beta-blocker + ICD", "Reduce SCD risk"]], [150, 160, 150] ), SP(6), H("Ventricular Fibrillation (VF) β CARDIAC ARREST", h2), RhythmStrip("vfib", label="VENTRICULAR FIBRILLATION β Chaotic, NO recognisable QRS β DEFIB NOW!"), SP(4), BulletBox([ "CHAOTIC, irregular fibrillatory waves β NO organised QRS complexes", "No cardiac output β patient is pulseless and unconscious", "IMMEDIATELY life-threatening β death within minutes without treatment", "Causes: Acute MI, cardiomyopathy, hypokalaemia, hypothermia, electrocution", "TREATMENT: CPR + DEFIBRILLATION 200J (biphasic) ASAP β Every second counts!", "Adrenaline 1 mg IV every 3-5 mins during CPR", "Amiodarone 300 mg IV after 3rd shock", "Continue ALS algorithm until ROSC or decision to stop", ], accent=C_ACCENT1), SP(6), H("Torsades de Pointes (TdP)", h2), BulletBox([ "Polymorphic VT where QRS 'twists' around the baseline", "Associated with LONG QT interval (QTc > 500 ms = high risk)", "Causes: Hypokalaemia, hypomagnesaemia, drugs (amiodarone, erythromycin, " "antipsychotics, methadone, quinolones), congenital LQTS", "TREATMENT: IV Magnesium sulphate 2g bolus β FIRST LINE!", "Remove offending drug | Correct electrolytes | Overdrive pacing", "NOT amiodarone (it prolongs QT further!)", ], accent=C_GOLD), PageBreak(), ] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 8 β HEART BLOCKS # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(8), ColorBox("π§± CHAPTER 7 : HEART BLOCKS (AV BLOCKS)", bg=C_ACCENT2, fg=C_BG, fsize=15), SP(6), H("1st Degree AV Block", h2), BulletBox([ "PR interval > 0.20 sec (> 1 large box) β FIXED and prolonged", "Every P wave followed by QRS β just delayed", "Causes: Vagal tone, inferior MI, myocarditis, digoxin, beta-blockers", "Treatment: Usually NONE required β benign. Monitor.", ], accent=C_ACCENT3), SP(6), H("2nd Degree AV Block β Type 1 (Wenckebach / Mobitz I)", h2), BulletBox([ "PR interval PROGRESSIVELY LENGTHENS until a P wave is not conducted (QRS drops)", "Grouped beating pattern β 'group with pause'", "Ratio: 3:2, 4:3, 5:4 (3 P waves β 2 QRS complexes, etc.)", "Level of block: AV node (proximal) β generally benign", "Causes: Inferior MI (RCA), vagal tone, myocarditis, drugs", "Treatment: Usually none. Atropine if symptomatic. Monitor.", ], accent=C_CYAN), SP(6), H("2nd Degree AV Block β Type 2 (Mobitz II)", h2), BulletBox([ "PR interval CONSTANT β then P wave suddenly drops (QRS missing) WITHOUT warning", "Wide QRS often (infranodal block)", "More dangerous than Wenckebach β can progress to complete block suddenly!", "Level of block: Bundle of His or bundle branches", "Causes: Anterior MI (LAD), fibrosis, cardiac surgery", "Treatment: URGENT pacing β temporary then permanent pacemaker!", ], accent=C_ACCENT5), SP(6), H("3rd Degree (Complete) Heart Block", h2), RhythmStrip("chb", label="COMPLETE HEART BLOCK β P waves and QRS completely dissociated"), SP(4), BulletBox([ "COMPLETE AV dissociation β P waves and QRS complexes beat INDEPENDENTLY", "Atrial rate (P waves): 60β100 bpm | Ventricular rate (QRS): 20β40 bpm", "QRS: Wide if escape from ventricle; narrow if junctional escape", "Patient may have syncope (Stokes-Adams attacks), haemodynamic collapse", "Causes: Inferior MI (usually transient), anterior MI (usually permanent), " "Lyme disease, sarcoidosis, drugs", "Treatment: PERMANENT PACEMAKER β absolutely indicated!", "Temporary: Atropine (limited benefit) or transcutaneous/transvenous pacing", ], accent=C_ACCENT1), SP(6), colored_table( [["Block Type", "PR interval", "Dropped QRS?", "QRS width", "Treatment"], ["1st degree", "Fixed, > 0.20s", "No", "Narrow", "Monitor"], ["2nd Mobitz I","Progressive β", "Yes (periodic)", "Narrow", "Monitor/Atropine"], ["2nd Mobitz II","Fixed", "Yes (sudden)", "Wide", "Urgent pacing!"], ["3rd (CHB)", "AV dissociation","All P blocked", "Wide/narrow", "Permanent PM"]], [100, 120, 100, 80, 110] ), PageBreak(), ] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 9 β BUNDLE BRANCH BLOCKS # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(8), ColorBox("πΏ CHAPTER 8 : BUNDLE BRANCH BLOCKS (BBB)", bg=C_ACCENT3, fg=C_BG, fsize=15), SP(6), H("Understanding the Conduction System", h2), B("The normal sequence: SA node β AV node β Bundle of His β Left & Right bundle branches β " "Purkinje fibres β Ventricular myocardium. If a bundle branch is blocked, the " "impulse takes a slower, abnormal route β producing WIDE QRS with characteristic patterns."), SP(6), H("Right Bundle Branch Block (RBBB)", h2), BulletBox([ "QRS duration > 0.12 sec (complete RBBB) or 0.10β0.12 sec (incomplete)", "CLASSIC: RSR' pattern ('M' pattern / Rabbit ears) in V1", "Wide, slurred S wave in I, V5, V6", "T wave inversion in V1-V3 (secondary changes β normal in BBB)", "ST depression V1-V3 (secondary β do NOT diagnose ischaemia here)", "Causes: Normal variant, RBBB can be normal! Also PE, RVH, ASD, ischaemia", "Mnemonic: 'WiLLiaM MaRRoW' β RBBB = MaRRoW (M in V1, W in V6)", ], accent=C_ACCENT4), SP(6), H("Left Bundle Branch Block (LBBB)", h2), BulletBox([ "QRS > 0.12 sec, broad QS or rS in V1 (W pattern)", "Broad monophasic R wave in I, aVL, V5, V6 (M pattern)", "WILLIAM MaRRoW: LBBB = WiLLiaM (W in V1, M in V6)", "DO NOT diagnose ST changes or ischaemia in LBBB β changes are EXPECTED", "NEW LBBB + chest pain = treat as STEMI (Sgarbossa criteria can help)", "Causes: ALWAYS pathological! IHD, HTN, cardiomyopathy, aortic stenosis", "Sgarbossa criteria: Concordant ST elevation β₯ 1mm in β₯ 1 lead = positive", ], accent=C_ACCENT1), SP(6), colored_table( [["Feature", "RBBB", "LBBB"], ["V1 pattern", "RSR' (Rabbit ears / M)", "QS or rS (W shape)"], ["V6 pattern", "Wide S wave (W shape)", "Tall broad R (M shape)"], ["QRS width", "> 0.12 sec", "> 0.12 sec"], ["Pathological?","Not always", "ALWAYS assume"], ["Secondary ST", "ST dep, T inv V1-V3", "ST/T opposite to QRS"], ["Mnemonic", "MaRRoW", "WiLLiaM"]], [110, 190, 170] ), SP(6), H("Fascicular Blocks (Hemiblocks)", h2), BulletBox([ "LAHB (Left Anterior Hemiblock): LAD (axis < β45Β°), small Q in I, small R in III, " "QRS < 0.12 sec", "LPHB (Left Posterior Hemiblock): RAD (axis > +120Β°), small R in I, small Q in III", "Bifascicular block: RBBB + LAHB (most common) or RBBB + LPHB", "Trifascicular block: Bifascicular + 1st degree block β high risk β consider PM", ], accent=C_ACCENT6), PageBreak(), ] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 10 β MI / STEMI / NSTEMI # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(8), ColorBox("β€ CHAPTER 9 : MYOCARDIAL INFARCTION β STEMI & NSTEMI", bg=C_ACCENT1, fg=C_WHITE, fsize=14), SP(6), H("ECG Evolution of STEMI β The Timeline", h2), colored_table( [["Time", "ECG Changes", "What is Happening"], ["Minutes", "Tall peaked (hyperacute) T waves", "Acute ischaemia β earliest sign!"], ["0β6 hrs", "ST elevation > 1mm (limb) / 2mm (V)","Full thickness ischaemia"], ["6β24 hrs", "Q waves develop, ST still elevated", "Necrosis beginning"], ["24β72 hrs", "T wave inversion, Q waves deepen", "Evolving infarction"], ["Daysβweeks", "ST returns to baseline, Q persists", "T waves may normalise"], ["Monthsβyears", "Persistent Q waves only", "Scar β permanent marker of old MI"]], [80, 200, 180] ), SP(6), H("STEMI β ST Elevation Patterns by Territory", h2), RhythmStrip("stemi", label="STEMI β Massive ST elevation with hyperacute T waves"), SP(4), colored_table( [["Territory", "ST elevation leads", "Culprit artery", "Reciprocal changes"], ["Inferior", "II, III, aVF β₯ 2mm", "RCA (80%)", "I, aVL"], ["Anterior", "V1βV4 β₯ 2mm", "LAD", "None (II,III,aVF mild)"], ["Lateral", "I, aVL, V5, V6", "LCx", "V1, V2"], ["Extensive Ant.", "V1βV6 + I + aVL", "Proximal LAD", "II, III, aVF"], ["Posterior", "ST dep V1-V3 + tall R V1","LCx or RCA", "V1-V3 (reciprocal = STE)"], ["RV infarction", "V4R elevation β₯ 1mm", "Proximal RCA", "Inferior STE"]], [100, 130, 100, 130] ), SP(6), H("STEMI vs NSTEMI vs Unstable Angina", h2), colored_table( [["Feature", "STEMI", "NSTEMI", "Unstable Angina"], ["ECG", "STE β₯ 1-2mm OR LBBB", "ST dep / T inv / normal","Normal or ST dep"], ["Troponin", "Elevated", "Elevated", "Normal"], ["Mechanism", "Total occlusion", "Partial occlusion", "Partial/spasm"], ["Treatment", "Primary PCI < 90 min","Heparin + PCI < 72h", "Medical + PCI if high risk"]], [100, 140, 140, 140] ), SP(6), H("STEMI Treatment β TIME IS MUSCLE!", h2), BulletBox([ "IMMEDIATE: Aspirin 300mg + Ticagrelor 180mg (or Prasugrel/Clopidogrel)", "Oxygen only if SpO2 < 94% (avoid hyperoxia in uncomplicated MI)", "Morphine 2-5mg IV for pain (cautious β may reduce platelet inhibitor absorption)", "IV Heparin / LMWH (anticoagulation)", "PRIMARY PCI: Target door-to-balloon < 90 minutes β GOLD STANDARD", "Thrombolysis if PCI not available within 120 min (e.g. Tenecteplase/Streptokinase)", "Beta-blocker (oral) within 24 hrs if no contraindication", "ACE inhibitor within 24 hrs (especially anterior MI, LV dysfunction)", "Statin (high-dose atorvastatin 80mg) β start immediately", "Secondary prevention: DAPT for 12 months, long-term aspirin + statin", ], accent=C_ACCENT1), PageBreak(), ] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 11 β WPW, LONG QT, BRUGADA, PERICARDITIS # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(8), ColorBox("π CHAPTER 10 : SPECIAL SYNDROMES & PATTERNS", bg=C_ACCENT6, fg=C_WHITE, fsize=15), SP(6), H("Wolff-Parkinson-White Syndrome (WPW)", h2), BulletBox([ "Accessory pathway (Bundle of Kent) bypasses AV node", "Triad: Short PR (< 0.12 sec) + Delta wave + Wide QRS", "Delta wave = slurred upstroke at start of QRS ('pre-excitation')", "Risk of AF β rapid conduction β VF β sudden death!", "NEVER use digoxin, verapamil, beta-blockers in WPW with AF β fatal!", "Acute SVT: IV Adenosine (if narrow complex) or cardioversion", "Definitive: Radiofrequency ablation of accessory pathway", ], accent=C_ACCENT2), SP(6), H("Long QT Syndrome (LQTS)", h2), BulletBox([ "QTc > 440 ms (men), > 460 ms (women) β risk of TdP", "QTc > 500 ms = HIGH risk of sudden cardiac death", "Congenital: Romano-Ward, Jervell-Lange-Nielsen syndromes", "Acquired: Drugs (see TdP section), hypokalaemia, hypomagnesaemia, hypothyroidism", "Drug mnemonics β ABCDE: Antibiotics (quinolones, macrolides), " "antipsychotics (haloperidol), antiemetics (domperidone), " "antiarrhythmics (amiodarone, sotalol), antidepressants (TCAs)", "Treatment: Remove offending drug, IV Mg2+, correct electrolytes, " "beta-blockers, ICD for high-risk congenital", ], accent=C_GOLD), SP(6), H("Brugada Syndrome", h2), BulletBox([ "Characteristic Type 1: Coved ST elevation (saddle-back) in V1-V2 + RBBB pattern", "Type 2 & 3: Saddle-back ST elevation (less diagnostic, may unmask with sodium channel blocker)", "Risk: VF and sudden cardiac death β especially young Asian males, at night", "Gene: SCN5A mutation (sodium channel)", "ECG may be dynamic β fever/drugs can unmask it", "Treatment: ICD implantation if symptomatic. Quinidine can reduce VT burden.", "Avoid Class IC drugs (flecainide), tricyclics, avoid fever", ], accent=C_ACCENT4), SP(6), H("Pericarditis β Saddle-Shaped ST Elevation", h2), BulletBox([ "Diffuse ST elevation in MULTIPLE leads (not territorial) β saddle-shaped", "PR DEPRESSION β classic and almost pathognomonic!", "Affects most leads simultaneously (unlike MI which is territorial)", "No reciprocal changes (unlike MI)", "Stages: Stage 1: ST elevation + PR depression | Stage 2: Normalise | " "Stage 3: T inversion | Stage 4: Normal", "Treatment: NSAIDs (ibuprofen 600mg TDS or aspirin) + Colchicine 0.5mg BD x 3 months", "Avoid exercise during acute phase | Corticosteroids if refractory", ], accent=C_CYAN), SP(6), H("Pulmonary Embolism (PE) β ECG Clues", h2), BulletBox([ "CLASSIC (but NOT pathognomonic): S1Q3T3 pattern", " β Deep S in Lead I + Q wave in Lead III + T inversion in Lead III", "Sinus tachycardia β MOST common finding in PE!", "Right heart strain: RAD, RBBB (complete or incomplete), RV strain pattern", "T wave inversion V1βV4 (right ventricular strain)", "New AF or atrial flutter", "Remember: Normal ECG does NOT exclude PE", ], accent=C_ACCENT5), PageBreak(), ] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 12 β ELECTROLYTES & DRUG EFFECTS # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(8), ColorBox("π§ͺ CHAPTER 11 : ELECTROLYTES & DRUG EFFECTS ON ECG", bg=C_ACCENT3, fg=C_BG, fsize=14), SP(6), H("Hyperkalaemia β The Silent Killer", h2), colored_table( [["Serum K+ (mmol/L)","ECG Change", "What to do"], ["5.5β6.0", "Tall, peaked, symmetrical T waves","Monitor closely"], ["6.0β7.0", "PR prolongation, QRS widening", "Start treatment"], ["7.0β8.0", "Loss of P waves, sine wave", "Urgent treatment"], ["> 8.0", "VF, asystole", "EMERGENCY"]], [120, 200, 140] ), SP(4), H("Hyperkalaemia Treatment", h2), BulletBox([ "1. Calcium gluconate 10ml 10% IV β membrane stabilisation (IMMEDIATE, within 5 min)", "2. IV Insulin + Dextrose (10 units actrapid + 50ml 50% dextrose) β shifts K+ into cells", "3. Salbutamol nebuliser 10-20mg β shifts K+ into cells", "4. Sodium bicarbonate 50-100mEq IV (if acidotic)", "5. Calcium resonium (oral/rectal) β removes K+ from body", "6. Dialysis β definitive if refractory or renal failure", ], accent=C_ACCENT1), SP(6), H("Hypokalaemia", h2), BulletBox([ "Flat/inverted T waves + Prominent U waves (appears as prolonged QT)", "U wave height > T wave height = significant hypokalaemia", "Can trigger TdP and VT", "Treatment: Oral/IV KCl replacement. IV K+ max 20 mmol/hr with monitoring.", ], accent=C_ACCENT2), SP(6), H("Hypercalcaemia vs Hypocalcaemia", h2), colored_table( [["Electrolyte", "ECG Change", "Mnemonic"], ["Hypercalcaemia", "Short QT interval", "High Ca = Short QT"], ["Hypocalcaemia", "Long QT interval", "Low Ca = Long QT"], ["Hypermagnesaemia","Prolonged PR, AV block", "β Mg = blocks conduction"], ["Hypomagnesaemia","TdP, VT, prolonged QT", "β Mg = arrhythmias"]], [130, 200, 130] ), SP(6), H("Digoxin Effects on ECG", h2), BulletBox([ "Therapeutic: 'Reverse tick' / Salvador Dali moustache β down-sloping ST depression", "Bradycardia and PR prolongation (therapeutic)", "Toxicity: AV blocks (any degree), atrial tachycardia with block", "Bidirectional VT = highly suggestive of digoxin toxicity", "Treatment of toxicity: Digibind (Fab fragments) β specific antidote", ], accent=C_GOLD), SP(6), H("Other Drug Effects", h2), colored_table( [["Drug", "ECG Effect", "Concern"], ["Tricyclic antidepressants","Wide QRS, RAD, QTc", "VT, TdP β treat with Na bicarb"], ["Amiodarone", "Prolonged QT, bradycardia", "TdP risk (long term)"], ["Beta-blockers", "Bradycardia, PR prolongation", "AV block in overdose"], ["Cocaine", "ST elevation, VT, VF", "Coronary spasm, direct cardiotox"], ["Hypothermia", "J (Osborn) waves, bradycardia", "VF at < 28Β°C"]], [120, 170, 170] ), PageBreak(), ] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 13 β HYPERTROPHY PATTERNS # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(8), ColorBox("π CHAPTER 12 : CHAMBER ENLARGEMENT & HYPERTROPHY", bg=C_ACCENT4, fg=C_WHITE, fsize=14), SP(6), H("Left Ventricular Hypertrophy (LVH)", h2), BulletBox([ "Sokolov-Lyon Criteria: S wave V1 + R wave V5 or V6 β₯ 35mm", "Cornell Criteria: R in aVL + S in V3 > 28mm (men), > 20mm (women)", "Voltage changes + Strain pattern (ST depression + T inversion in lateral leads)", "LAD, broad notched P wave, prolonged QRS", "Causes: HTN (most common), HCM, aortic stenosis, MR", ], accent=C_ACCENT1), SP(6), H("Right Ventricular Hypertrophy (RVH)", h2), BulletBox([ "Dominant R wave in V1 (R > S in V1)", "R wave in V1 + S wave in V5 or V6 β₯ 11mm", "Right axis deviation (RAD)", "ST depression + T inversion in V1βV3 (strain pattern)", "Causes: Pulmonary hypertension, COPD, PE, mitral stenosis, ASD, PS", ], accent=C_ACCENT4), SP(6), H("Left Atrial Enlargement (LAE) β P Mitrale", h2), BulletBox([ "P wave duration > 0.12 sec in limb leads", "Bifid (notched) P wave in II β M-shaped 'P mitrale'", "Biphasic P wave in V1 with deep negative component (> 1mm deep, > 1mm wide)", "Causes: Mitral stenosis, LVF, HTN", ], accent=C_ACCENT3), SP(6), H("Right Atrial Enlargement (RAE) β P Pulmonale", h2), BulletBox([ "Tall, peaked P wave in II > 2.5mm", "Positive P wave in V1 > 1.5mm", "P wave duration normal (< 0.12 sec)", "Causes: COPD, pulmonary hypertension, tricuspid stenosis", ], accent=C_CYAN), SP(6), H("Dextrocardia", h2), BulletBox([ "ECG: Global negative deflections in lead I (inverted P, QRS, T)", "Reverse R wave progression (decreasing R V1βV6)", "Confirmed by clinical exam and CXR", "Technical dextrocardia: Lead reversal β R arm/L arm swap gives same picture in lead I", "Distinguish: If leads reversed, V leads progress normally; true dextrocardia β reversed", ], accent=C_ACCENT6), SP(8), ColorBox("π QUICK REFERENCE SUMMARY TABLE", bg=C_ACCENT5, fg=C_WHITE, fsize=13), SP(6), colored_table( [["Condition", "Key ECG Finding", "First-line Treatment"], ["NSR", "Regular, 60-100, P before QRS", "None"], ["AF", "Irregularly irregular, no P waves", "Rate control + anticoagulation"], ["Atrial Flutter", "Sawtooth F waves, 2:1 block", "Rate control / cardioversion"], ["SVT", "Narrow tachy 150-250, regular", "Adenosine 6mg IV"], ["VT", "Wide QRS tachy, AV dissociation", "Amiodarone / Defibrillation"], ["VF", "Chaotic, no QRS", "Immediate defibrillation 200J"], ["TdP", "Polymorphic VT + long QT", "IV Magnesium 2g"], ["1stΒ° AV Block", "PR > 0.20 sec", "Monitor"], ["2ndΒ° Mobitz II", "Dropped QRS suddenly", "Urgent pacing"], ["3rdΒ° CHB", "AV dissociation", "Permanent pacemaker"], ["RBBB", "RSR' in V1, wide S in V6", "Treat underlying cause"], ["LBBB", "W in V1, M in V6", "Treat underlying (always pathological)"], ["STEMI", "STE β₯ 1-2mm, evolving Q waves", "Primary PCI < 90 min"], ["NSTEMI", "ST dep / T inv / normal, Trop +", "Heparin + PCI < 72h"], ["Pericarditis", "Diffuse STE, PR depression", "NSAIDs + Colchicine"], ["WPW", "Short PR, delta wave", "Ablation"], ["Hyperkalaemia", "Peaked T β sine wave", "Ca gluconate + insulin/dextrose"], ["PE", "S1Q3T3, sinus tachy, RBBB", "Anticoagulation / thrombolysis"], ["LVH", "Sokolov β₯ 35mm + strain", "Treat HTN"], ["Brugada", "Coved STE V1-V2", "ICD"]], [130, 190, 150] ), PageBreak(), ] # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 14 β CLINICAL PEARLS & MNEMONICS # ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story += [ SP(8), ColorBox("π‘ CHAPTER 13 : CLINICAL PEARLS, MNEMONICS & TIPS", bg=C_GOLD, fg=C_BG, fsize=15), SP(6), H("Essential Mnemonics", h1), BulletBox([ "WiLLiaM MaRRoW: LBBB = W in V1, M in V6 | RBBB = M in V1, W in V6", "AIVR: Rate 60-100 + wide QRS + no P = Accelerated Idioventricular Rhythm", "STEMI territories: I See LAD β Anterior (LAD) | I, aVL = Lateral (LCx) | II,III,F = Inferior (RCA)", "P wave absent: AF, junctional, SA block, ventricular rhythm", "DEAD: Delta wave, Every P has QRS, Axis check, Duration of QRS", "5 H's + 5 T's for reversible cardiac arrest causes: Hypoxia, Hypovolaemia, " "Hypo/Hyperkalaemia, Hypothermia, H+ acidosis / Tamponade, Tension pneumothorax, " "Thrombosis (PE/MI), Toxins", ], accent=C_ACCENT6, bg=C_CARD2), SP(6), H("Common Exam & Clinical Traps", h2), BulletBox([ "TRAP: SVT rate ~150 β always rule out Atrial Flutter with 2:1 block first!", "TRAP: Wide complex tachycardia = VT until proven otherwise (never assume SVT with aberrancy)", "TRAP: New LBBB + chest pain = STEMI equivalent β activate cath lab!", "TRAP: Normal ECG does NOT exclude MI (sensitivity ~55% for NSTEMI)", "TRAP: Hyperkalaemia can cause tall T waves like hyperacute MI β check U&E!", "TRAP: ST depression in V1-V3 may be posterior STEMI β do right-sided and posterior leads!", "TRAP: Digoxin causes 'reverse tick' depression β not ischaemia in isolation", "TRAP: Right lead reversal mimics dextrocardia", ], accent=C_ACCENT1, bg=C_CARD1), SP(6), H("Rate vs Rhythm vs Morphology", h2), BulletBox([ "First ask: Is the patient STABLE or UNSTABLE? (BP, GCS, perfusion)", "Unstable tachycardia of ANY type β synchronised DCCV", "Pulseless rhythm β CPR + Defibrillation (shockable: VF/VT) or Adrenaline (non-shockable)", "Narrow QRS tachy β probably supraventricular", "Wide QRS tachy β VT until proven otherwise", "Irregular rhythm β AF, flutter with variable block, multifocal atrial tachycardia, or PVCs", ], accent=C_ACCENT3, bg=C_CARD1), SP(6), H("Normal Variants β Don't Over-Diagnose!", h2), BulletBox([ "Early repolarisation: ST elevation in V2-V4 in young athletes β concave, benign", "Juvenile T wave inversion: T inversion V1-V3 in children/young women β normal", "Incomplete RBBB: QRS 0.10-0.12, RSR' in V1 β can be normal", "1st degree AV block in athletes: vagal tone β benign", "Sinus arrhythmia: HR varies with breathing β young patients β normal", "Voltage criteria for LVH in thin patients: may be normal", ], accent=C_ACCENT3, bg=C_CARD2), SP(6), ColorBox("π You've Mastered ECG! Keep Practising β Mihir is Going to Be a Legend! π", bg=C_ACCENT1, fg=C_WHITE, fsize=12, radius=14), SP(4), Paragraph("Review a real ECG every day β Practice pattern recognition β Correlate with clinical findings β When in doubt β call for help", S("final", fontSize=9, textColor=C_LTGRAY, alignment=TA_CENTER)), ] # ββ Build PDF ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ doc = SimpleDocTemplate( OUTPUT, pagesize=A4, leftMargin=40, rightMargin=40, topMargin=50, bottomMargin=50, title="ECG Master Guide β Mihir", author="Mihir", subject="Complete ECG Diagnosis & Treatment" ) doc.build(story, onFirstPage=on_page, onLaterPages=on_page) print(f"PDF created: {OUTPUT}") PYEOF echo "Script written OK"
mkdir -p /tmp/workspace/ecg-pdf && ls /tmp/workspace/ecg-pdf/
Give me a pdf that would be enough to diagnose and ecg correctly with its treatment don't generate boring pdf make it colourful with animations and don't miss any concepts I know some what ecg please help me to be better add some more details and more detailed easy and simple explanation keep details vast and include treatment too bro and keep colour radiant and add cartoonisitc and animated images generate more attractive pdf this is best this details should be there but add more with modification I mentioned plz help me out with it and at end of every page introduce a footer of my name mihir and give page number with a boundary it should be attractive create a pdf of it
mkdir -p /tmp/workspace/ecg-pdf && python3 - << 'PYEOF' from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.units import mm from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, PageBreak) from reportlab.lib.styles import ParagraphStyle from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY from reportlab.platypus.flowables import Flowable import math, os OUTPUT = "/tmp/workspace/ecg-pdf/ECG_MasterGuide_Mihir.pdf" W, H = A4 # Colours C_BG = colors.HexColor("#0D1B2A") C_CARD1 = colors.HexColor("#1A2E4A") C_CARD2 = colors.HexColor("#112233") C_RED = colors.HexColor("#FF4757") C_YELLOW = colors.HexColor("#FFD93D") C_GREEN = colors.HexColor("#2ED573") C_BLUE = colors.HexColor("#1E90FF") C_ORANGE = colors.HexColor("#FF6348") C_PURPLE = colors.HexColor("#A855F7") C_WHITE = colors.white C_LTGRAY = colors.HexColor("#C8D6E5") C_GOLD = colors.HexColor("#FFD700") C_PINK = colors.HexColor("#FF69B4") C_CYAN = colors.HexColor("#00D4FF") C_LIME = colors.HexColor("#AAFF00") def on_page(canv, doc): canv.saveState() # dark background canv.setFillColor(C_BG) canv.rect(0, 0, W, H, fill=1, stroke=0) # gradient strips at top for i, col in enumerate([C_RED, C_ORANGE, C_YELLOW, C_GREEN, C_BLUE, C_PURPLE]): canv.setFillColor(col) canv.rect(i*(W/6), H-8, W/6+1, 8, fill=1, stroke=0) # gradient strips at bottom for i, col in enumerate([C_PURPLE, C_BLUE, C_GREEN, C_YELLOW, C_ORANGE, C_RED]): canv.setFillColor(col) canv.rect(i*(W/6), 0, W/6+1, 8, fill=1, stroke=0) # outer border for i, (bc, lw) in enumerate([(C_GOLD,2.5),(C_CYAN,1.5),(C_PINK,1)]): off = 10 + i*5 canv.setStrokeColor(bc) canv.setLineWidth(lw) canv.roundRect(off, off, W-2*off, H-2*off, 10, fill=0, stroke=1) # heartbeat line at top canv.setStrokeColor(C_RED) canv.setLineWidth(2.2) p = canv.beginPath() beats = [(0,H-22),(40,H-22),(50,H-5),(58,H-40),(66,H-5),(76,H-22), (160,H-22),(170,H-5),(178,H-40),(186,H-5),(196,H-22),(W,H-22)] p.moveTo(*beats[0]) for pt in beats[1:]: p.lineTo(*pt) canv.drawPath(p) # footer box canv.setFillColor(C_GOLD) canv.roundRect(28, 12, W-56, 24, 8, fill=1, stroke=0) canv.setFillColor(C_BG) canv.setFont("Helvetica-Bold", 9) canv.drawCentredString(W/2, 20, f"β MIHIR β ECG MASTER GUIDE β Page {doc.page} β ") canv.restoreState() # ββ Flowables ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ class SectionBanner(Flowable): def __init__(self, text, bg=C_BLUE, fg=C_WHITE, fsize=15): super().__init__() self.text=text; self.bg=bg; self.fg=fg; self.fsize=fsize self.height=fsize+22 def wrap(self,aW,aH): return(W-80,self.height) def draw(self): c=self.canv; bw=W-80 # shadow c.setFillColor(colors.HexColor("#000000")) c.roundRect(3,-3,bw,self.height,12,fill=1,stroke=0) # main c.setFillColor(self.bg) c.roundRect(0,0,bw,self.height,12,fill=1,stroke=0) # shine strip c.setFillColor(colors.Color(1,1,1,alpha=0.15)) c.roundRect(0,self.height*0.55,bw,self.height*0.45,12,fill=1,stroke=0) c.setFillColor(self.fg) c.setFont("Helvetica-Bold",self.fsize) c.drawCentredString(bw/2, self.height*0.28, self.text) class ECGTrace(Flowable): def __init__(self, rtype="normal", width=460, height=110, label=""): super().__init__() self.rtype=rtype; self._w=width; self._h=height; self.label=label def wrap(self,aW,aH): return(self._w,self._h) def draw(self): c=self.canv; w=self._w; h=self._h; bl=h*0.5 c.setFillColor(colors.HexColor("#071A07")) c.roundRect(0,0,w,h,8,fill=1,stroke=0) c.setStrokeColor(colors.HexColor("#0D3D0D")) c.setLineWidth(0.4) for gx in range(0,int(w),15): c.line(gx,4,gx,h-18) for gy in range(4,int(h-18),15): c.line(0,gy,w,gy) c.setStrokeColor(colors.HexColor("#196419")) c.setLineWidth(0.8) for gx in range(0,int(w),75): c.line(gx,4,gx,h-18) c.setStrokeColor(C_GREEN) c.setLineWidth(2.5) import random if self.rtype=="normal": pts=[] for b in range(5): ox=b*88+8 pts+=[(ox,bl),(ox+12,bl),(ox+16,bl+8),(ox+20,bl),(ox+26,bl), (ox+28,bl-4),(ox+31,bl+34),(ox+34,bl-9),(ox+38,bl), (ox+43,bl+12),(ox+50,bl+18),(ox+57,bl+12),(ox+62,bl),(ox+80,bl)] elif self.rtype=="afib": random.seed(42) pts=[(0,bl)] x=0 while x<w-10: x+=random.randint(3,8); pts.append((x,bl+random.randint(-5,5))) for b in [55,145,240,325]: pts+=[(b,bl),(b+2,bl+26),(b+5,bl-9),(b+8,bl)] elif self.rtype=="vfib": random.seed(7) pts=[(0,bl)] x=0 while x<w-5: x+=random.randint(2,7); pts.append((x,bl+random.randint(-24,24))) elif self.rtype=="vtach": pts=[] for b in range(7): ox=b*60 pts+=[(ox,bl),(ox+5,bl),(ox+9,bl+28),(ox+14,bl-11), (ox+18,bl),(ox+30,bl+9),(ox+42,bl+9),(ox+55,bl),(ox+60,bl)] elif self.rtype=="stemi": pts=[] for b in range(4): ox=b*110+8 pts+=[(ox,bl),(ox+12,bl),(ox+16,bl+8),(ox+20,bl), (ox+24,bl-4),(ox+28,bl+42),(ox+33,bl-10), (ox+38,bl+16),(ox+60,bl+16),(ox+68,bl+9),(ox+80,bl),(ox+100,bl)] elif self.rtype=="chb": # P waves (blue) c.setStrokeColor(C_BLUE) c.setLineWidth(1.8) for pp in range(11): ox=pp*40+5 p2=c.beginPath() p2.moveTo(ox,bl); p2.lineTo(ox+4,bl+8); p2.lineTo(ox+8,bl) c.drawPath(p2,stroke=1,fill=0) # slow QRS (red) c.setStrokeColor(C_RED) c.setLineWidth(2.5) pts=[] for b in range(3): ox=b*150+35 pts+=[(ox,bl),(ox+6,bl-5),(ox+11,bl+36),(ox+17,bl-12),(ox+22,bl),(ox+30,bl)] elif self.rtype=="block2": pts=[] pr=20 for b in range(4): ox=b*100+10; pr_this=20+b*8 if b<3 else 999 pts+= [(ox,bl),(ox+pr_this if pr_this<60 else ox+15, bl)] if pr_this<60: pts+=[(ox+pr_this,bl-4),(ox+pr_this+4,bl+30), (ox+pr_this+8,bl-9),(ox+pr_this+14,bl)] pts+=[(ox+80,bl)] else: pts=[(0,bl),(w,bl)] if self.rtype not in ("chb",): p=c.beginPath() if pts: p.moveTo(*pts[0]) for pt in pts[1:]: p.lineTo(*pt) c.drawPath(p,stroke=1,fill=0) elif self.rtype=="chb": p=c.beginPath() if pts: p.moveTo(*pts[0]) for pt in pts[1:]: p.lineTo(*pt) c.setStrokeColor(C_RED) c.drawPath(p,stroke=1,fill=0) if self.label: c.setFillColor(C_YELLOW) c.setFont("Helvetica-Bold",8) c.drawString(7,h-14,self.label) class HeartFace(Flowable): def __init__(self,size=90): super().__init__(); self.s=size def wrap(self,aW,aH): return(self.s,self.s) def draw(self): c=self.canv; s=self.s; cx=s/2; cy=s/2-6 # glow for r,alpha in [(s*0.52,0.08),(s*0.48,0.12),(s*0.44,0.18)]: c.setFillColor(colors.Color(1,0.2,0.2,alpha=alpha)) c.circle(cx,cy,r,fill=1,stroke=0) # heart body c.setFillColor(C_RED) p=c.beginPath() p.moveTo(cx,cy-s*0.18) p.curveTo(cx-s*0.06,cy+s*0.22,cx-s*0.46,cy+s*0.22,cx-s*0.46,cy) p.curveTo(cx-s*0.46,cy-s*0.28,cx,cy-s*0.42,cx,cy-s*0.18) c.drawPath(p,fill=1,stroke=0) p2=c.beginPath() p2.moveTo(cx,cy-s*0.18) p2.curveTo(cx+s*0.06,cy+s*0.22,cx+s*0.46,cy+s*0.22,cx+s*0.46,cy) p2.curveTo(cx+s*0.46,cy-s*0.28,cx,cy-s*0.42,cx,cy-s*0.18) c.drawPath(p2,fill=1,stroke=0) # shine c.setFillColor(colors.Color(1,1,1,alpha=0.35)) c.ellipse(cx-s*0.2,cy+s*0.05,cx-s*0.02,cy+s*0.18,fill=1,stroke=0) # eyes c.setFillColor(C_WHITE) c.circle(cx-s*0.14,cy+s*0.04,s*0.07,fill=1,stroke=0) c.circle(cx+s*0.14,cy+s*0.04,s*0.07,fill=1,stroke=0) c.setFillColor(C_BG) c.circle(cx-s*0.12,cy+s*0.04,s*0.04,fill=1,stroke=0) c.circle(cx+s*0.12,cy+s*0.04,s*0.04,fill=1,stroke=0) # sparkle eyes c.setFillColor(C_WHITE) c.circle(cx-s*0.10,cy+s*0.07,s*0.015,fill=1,stroke=0) c.circle(cx+s*0.10,cy+s*0.07,s*0.015,fill=1,stroke=0) # smile c.setStrokeColor(C_BG); c.setLineWidth(1.8) p3=c.beginPath() p3.moveTo(cx-s*0.12,cy-s*0.05) p3.curveTo(cx-s*0.06,cy-s*0.16,cx+s*0.06,cy-s*0.16,cx+s*0.12,cy-s*0.05) c.drawPath(p3,fill=0,stroke=1) # cheeks c.setFillColor(colors.Color(1,0.6,0.6,alpha=0.5)) c.ellipse(cx-s*0.32,cy-s*0.06,cx-s*0.18,cy+s*0.02,fill=1,stroke=0) c.ellipse(cx+s*0.18,cy-s*0.06,cx+s*0.32,cy+s*0.02,fill=1,stroke=0) # stethoscope arc c.setStrokeColor(C_BLUE); c.setLineWidth(2) c.arc(cx-s*0.08,cy-s*0.35,cx+s*0.08,cy-s*0.15,0,180) c.line(cx-s*0.08,cy-s*0.25,cx-s*0.08,cy-s*0.40) c.setFillColor(C_BLUE) c.circle(cx-s*0.08,cy-s*0.40,3,fill=1,stroke=0) class BulletCard(Flowable): def __init__(self,items,accent=C_BLUE,bg=C_CARD1,fsize=9.5,width=None): super().__init__() self.items=items; self.accent=accent; self.bg=bg; self.fsize=fsize self._w=width or (W-80) self.lh=fsize+9 self.height=len(items)*self.lh+16 def wrap(self,aW,aH): return(self._w,self.height) def draw(self): c=self.canv # card shadow c.setFillColor(colors.Color(0,0,0,alpha=0.4)) c.roundRect(3,-3,self._w,self.height,10,fill=1,stroke=0) c.setFillColor(self.bg) c.roundRect(0,0,self._w,self.height,10,fill=1,stroke=0) # left accent bar c.setFillColor(self.accent) c.roundRect(0,0,6,self.height,4,fill=1,stroke=0) y=self.height-self.lh for item in self.items: c.setFillColor(self.accent) c.circle(22,y+self.fsize*0.38,4,fill=1,stroke=0) c.setFillColor(C_WHITE) c.setFont("Helvetica",self.fsize) # draw text (simple, no HTML) txt=item.replace("<b>","").replace("</b>","") c.drawString(32,y,txt[:100]) y-=self.lh class LabelledECG(Flowable): """Full annotated ECG wave with callout labels.""" def __init__(self,width=470,height=160): super().__init__(); self._w=width; self._h=height def wrap(self,aW,aH): return(self._w,self._h) def draw(self): c=self.canv; w=self._w; h=self._h; bl=h*0.40 # bg c.setFillColor(colors.HexColor("#071A07")) c.roundRect(0,0,w,h,8,fill=1,stroke=0) # grid c.setStrokeColor(colors.HexColor("#0D3D0D")); c.setLineWidth(0.4) for gx in range(0,int(w),20): c.line(gx,4,gx,h-4) for gy in range(4,int(h),20): c.line(0,gy,w,gy) c.setStrokeColor(colors.HexColor("#196419")); c.setLineWidth(0.8) for gx in range(0,int(w),100): c.line(gx,4,gx,h-4) # two beats def beat(ox): return [(ox,bl),(ox+18,bl),(ox+23,bl+10),(ox+28,bl),(ox+36,bl), (ox+40,bl-6),(ox+44,bl+52),(ox+48,bl-14),(ox+54,bl), (ox+60,bl),(ox+66,bl+8),(ox+76,bl+22),(ox+86,bl+8), (ox+92,bl),(ox+130,bl)] pts=beat(20)+beat(20+140)[1:] c.setStrokeColor(C_GREEN); c.setLineWidth(2.8) p=c.beginPath(); p.moveTo(*pts[0]) for pt in pts[1:]: p.lineTo(*pt) c.drawPath(p) # baseline dashed c.setStrokeColor(C_LTGRAY); c.setDash(4,3); c.setLineWidth(0.6) c.line(0,bl,w,bl); c.setDash() # labels with arrows labels_data=[ (23+20, bl+22, "P Wave", C_YELLOW, "Atrial depolarisation"), (44+20, bl+62, "R Peak", C_RED, "Ventricular depol."), (40+20, bl-16, "Q dip", C_CYAN, "Septal depol."), (48+20, bl-22, "S dip", C_PINK, "Ventricular spread"), (76+20, bl+32, "T Wave", C_GREEN, "Ventricular repol."), (34+20, bl-28, "PR seg", C_BLUE, "AV node delay"), (62+20, bl-28, "ST seg", C_ORANGE, "Early repolarisation"), ] for lx,ly,name,col,desc in labels_data: c.setFillColor(col) c.circle(lx,ly,3,fill=1,stroke=0) c.setStrokeColor(col); c.setLineWidth(0.8) # small leader line if ly>bl+30: c.line(lx,ly+3,lx,ly+16) c.setFont("Helvetica-Bold",7.5) c.setFillColor(col) c.drawCentredString(lx,ly+18,name) c.setFont("Helvetica",6.5) c.setFillColor(C_LTGRAY) c.drawCentredString(lx,ly+10,desc) else: c.line(lx,ly-3,lx,ly-16) c.setFont("Helvetica-Bold",7.5) c.setFillColor(col) c.drawCentredString(lx,ly-24,name) c.setFont("Helvetica",6.5) c.setFillColor(C_LTGRAY) c.drawCentredString(lx,ly-16,desc) def colored_table(data,widths,hdr=C_BLUE): t=Table(data,colWidths=widths) n=len(data) row_bgs=[] for i in range(1,n): row_bgs.append(("BACKGROUND",(0,i),(-1,i),C_CARD1 if i%2==1 else C_CARD2)) t.setStyle(TableStyle([ ("BACKGROUND",(0,0),(-1,0),hdr), ("TEXTCOLOR",(0,0),(-1,0),C_WHITE), ("FONTNAME",(0,0),(-1,0),"Helvetica-Bold"), ("FONTSIZE",(0,0),(-1,0),9), ("ALIGN",(0,0),(-1,-1),"CENTER"), ("VALIGN",(0,0),(-1,-1),"MIDDLE"), ("TEXTCOLOR",(0,1),(-1,-1),C_LTGRAY), ("FONTNAME",(0,1),(-1,-1),"Helvetica"), ("FONTSIZE",(0,1),(-1,-1),8.5), ("GRID",(0,0),(-1,-1),0.5,colors.HexColor("#2A4A6A")), ("TOPPADDING",(0,0),(-1,-1),5), ("BOTTOMPADDING",(0,0),(-1,-1),5), ("ROWBACKGROUNDS",(0,1),(-1,-1),[C_CARD1,C_CARD2]), ]+row_bgs)) return t def sp(n=6): return Spacer(1,n) def S(nm,**kw): return ParagraphStyle(nm,**kw) def P(txt,st): return Paragraph(txt,st) h1s=S("h1",fontSize=17,textColor=C_YELLOW,fontName="Helvetica-Bold",spaceBefore=8,spaceAfter=4,leading=20) h2s=S("h2",fontSize=13,textColor=C_CYAN,fontName="Helvetica-Bold",spaceBefore=6,spaceAfter=3) h3s=S("h3",fontSize=11,textColor=C_GREEN,fontName="Helvetica-Bold",spaceBefore=4,spaceAfter=2) bdy=S("bd",fontSize=9.5,textColor=C_LTGRAY,fontName="Helvetica",spaceBefore=2,spaceAfter=2,leading=13,alignment=TA_JUSTIFY) ctr=S("ct",fontSize=9,textColor=C_LTGRAY,fontName="Helvetica",alignment=TA_CENTER) story=[] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 1 β COVER # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(30), HeartFace(size=120), sp(10), P("ECG MASTER GUIDE",S("t1",fontSize=36,textColor=C_YELLOW,fontName="Helvetica-Bold",alignment=TA_CENTER,leading=42)), P("Complete Diagnosis + Treatment Atlas",S("t2",fontSize=15,textColor=C_CYAN,fontName="Helvetica-BoldOblique",alignment=TA_CENTER)), sp(8), P("Waves Β· Intervals Β· Rhythms Β· Arrhythmias Β· STEMI Β· Blocks Β· Treatment", S("t3",fontSize=11,textColor=C_GREEN,fontName="Helvetica-BoldOblique",alignment=TA_CENTER)), sp(12), LabelledECG(width=470,height=160), sp(14), SectionBanner("π Made with β€ for MIHIR β Your Pocket ECG Bible π",bg=C_RED,fsize=13), sp(8), P("Master every wave Β· Every arrhythmia Β· Every treatment Β· Become the ECG Legend",ctr), PageBreak(), ] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 2 β WHAT IS AN ECG + ECG PAPER # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(8), SectionBanner("β‘ CHAPTER 1 : WHAT IS AN ECG?",bg=C_BLUE,fsize=15), sp(8), P("What is an ECG (Electrocardiogram)?",h1s), P("An ECG records the heart's electrical activity over time. Every heartbeat is driven by " "electrical impulses that travel through the myocardium. Electrodes on the skin detect these " "tiny signals and plot them as waves on graph paper. Think of it as the heart sending a " "detailed WhatsApp message β and you learning to read it!",bdy), sp(6), P("Why ECG Matters β What It Can Detect",h2s), BulletCard([ "Heart attacks (MI) β within minutes of onset", "Life-threatening arrhythmias: VF, VT, complete heart block", "Drug toxicity: digoxin, tricyclics, quinolones", "Electrolyte imbalances: hyperkalaemia, hypocalcaemia", "Structural changes: LVH, RVH, atrial enlargement", "Pacemaker function and capture", "PE, pericarditis, myocarditis, hypothermia", ],accent=C_BLUE), sp(8), P("ECG Paper Explained",h2s), P("Speed: 25 mm/sec standard. Each small box = 1 mm wide = 0.04 sec. " "Each large box = 5 mm = 0.2 sec. Voltage: 10 mm = 1 mV.",bdy), colored_table( [["Parameter","Small Box","Large Box","Practical Use"], ["Time (width)","0.04 sec","0.20 sec","Count boxes to measure intervals"], ["Voltage (height)","0.1 mV","0.5 mV","Measure wave amplitude in mm"], ["HR (fast method)","β","300 / large sq","Quick rate estimate"], ["HR (precise)","1500 / small sq","β","Accurate rate calculation"], ["Paper speed","25 mm/sec","β","Standard; 50mm/s used in some labs"]], [100,80,80,170]), sp(8), P("The 12-Lead System β 12 Views of the Heart",h2s), P("Just as 12 photos of a building from 12 angles reveal the full structure, 12 ECG leads " "view the heart's electrical activity from 12 directions. This helps localise pathology " "to specific walls and their supplying arteries.",bdy), colored_table( [["Lead Group","Leads","Wall Viewed","Culprit Artery"], ["Inferior","II, III, aVF","Inferior wall (diaphragmatic)","RCA (80%)"], ["Anterior","V1, V2, V3, V4","Anterior wall + septum","LAD"], ["Lateral","I, aVL, V5, V6","Lateral wall","LCx"], ["Septal","V1, V2","Interventricular septum","LAD (septal perforators)"], ["Posterior","V7-V9 (reciprocal V1-V3)","Posterior wall","LCx or RCA"], ["Right Ventricle","V1, V4R","Right ventricle","Proximal RCA"]], [100,110,160,110]), PageBreak(), ] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 3 β WAVES INTERVALS SEGMENTS # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(8), SectionBanner("π CHAPTER 2 : WAVES, INTERVALS & SEGMENTS",bg=C_GREEN,fg=C_BG,fsize=15), sp(6), LabelledECG(width=470,height=155), sp(6), P("P Wave β Atrial Depolarisation",h2s), BulletCard([ "Represents SA node firing β both atria contract", "Normal: upright in I, II, aVF; inverted in aVR; biphasic in V1", "Duration < 0.12 sec (< 3 small boxes) | Amplitude < 2.5 mm in limb leads", "ABSENT P wave: AF, junctional rhythm, SA arrest, hyperkalaemia", "TALL peaked P (>2.5 mm) = P pulmonale β right atrial enlargement", "BROAD notched P (>0.12 sec) = P mitrale β left atrial enlargement", "INVERTED P in II: ectopic atrial focus, retrograde conduction", ],accent=C_YELLOW), sp(5), P("QRS Complex β Ventricular Depolarisation",h2s), BulletCard([ "Q wave: first negative deflection β septal depol. Pathological if >0.04s wide OR >1/3 R height", "R wave: first positive deflection β main ventricular mass depolarising", "S wave: first negative after R β represents basal depolarisation", "Normal QRS duration: 0.06β0.10 sec (< 2.5 small boxes)", "WIDE QRS (>0.12s): BBB, WPW, ventricular ectopic/rhythm, hyperkalaemia", "Tall R in V1: RBBB, posterior MI, RVH, WPW (type A)", "Poor R progression (V1-V4): anterior MI, LBBB, LVH, COPD", ],accent=C_RED), sp(5), P("T Wave & U Wave",h2s), BulletCard([ "T wave = ventricular repolarisation; normally same direction as QRS", "Normally upright: I, II, V3-V6. Normally inverted: aVR, V1", "TALL peaked T: hyperkalaemia (early), hyperacute MI", "INVERTED T: ischaemia, PE (V1-V4), RVH, LBBB, HCM, post-tachycardia", "FLAT T: hypokalaemia, hypothyroid, ischaemia", "U wave: small bump after T, best in V2-V3", "PROMINENT U wave: hypokalaemia, bradycardia, hypothermia", ],accent=C_GREEN), sp(5), colored_table( [["Interval / Segment","Normal Duration","Represents","Abnormal means..."], ["PR interval","0.12β0.20 sec","AV node conduction time","<0.12: WPW | >0.20: AV block"], ["QRS duration","0.06β0.10 sec","Ventricular depolarisation","Widened: BBB, K+, toxins"], ["QT interval","<0.44s (men) <0.46s (women)","Total ventricular electrical cycle","Long QT β TdP risk"], ["QTc (Bazett)","QT Γ· βRR","Rate-corrected QT",">500ms = HIGH risk"], ["ST segment","Isoelectric (flat)","Early repolarisation phase","Elevation: MI | Depression: ischaemia"], ["PR segment","Isoelectric","AV node + bundle conduction","Depression: pericarditis"]], [110,110,140,120]), PageBreak(), ] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 4 β SYSTEMATIC APPROACH # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(8), SectionBanner("π CHAPTER 3 : SYSTEMATIC ECG READING β 8 STEPS",bg=C_ORANGE,fg=C_WHITE,fsize=14), sp(6), P("The Golden 8-Step Method",h1s), P("Always read every ECG in the SAME order. This prevents missing diagnoses. " "Never skip steps, even if you think you already know the answer.",bdy), sp(4), colored_table( [["Step","Check","How","Normal"], ["1","RATE","300 Γ· large squares between R peaks","60β100 bpm"], ["2","RHYTHM","Regular? Is there a P before every QRS?","Regular sinus"], ["3","AXIS","QRS direction in Lead I and aVF","β30Β° to +90Β°"], ["4","P WAVE","Present? Upright in II? Same before each QRS?","<0.12s, <2.5mm"], ["5","PR INTERVAL","P start to QRS start (every beat)","0.12β0.20s fixed"], ["6","QRS","Width? Morphology? Pathological Q waves?","<0.10s, narrow"], ["7","ST & T WAVE","Elevation? Depression? T inversion?","Isoelectric / upright"], ["8","QT INTERVAL","QTc = QT Γ· β(RR in seconds)","<0.44s corrected"]], [25,80,210,100]), sp(8), P("Step 1 β Heart Rate in Detail",h2s), BulletCard([ "Method 1 (quick): 300 Γ· number of large squares between 2 R waves", "Method 2 (precise): 1500 Γ· number of small squares between R-R", "Method 3 (irregular): Count QRS complexes in 6-second strip Γ 10", "Bradycardia = HR < 60 bpm | Tachycardia = HR > 100 bpm", "HR < 40 = think complete heart block, hypothermia, drug toxicity", "HR > 150 = think SVT, atrial flutter 2:1, AF, VT", "HR ~300 = think 1:1 flutter or AVRT in WPW β DANGEROUS", ],accent=C_ORANGE), sp(6), P("Step 3 β Cardiac Axis",h2s), P("Axis = the dominant direction of ventricular depolarisation in the frontal plane.",bdy), colored_table( [["Axis","Lead I QRS","Lead aVF QRS","Common Causes"], ["Normal (β30 to +90Β°)","Positive (tall R)","Positive (tall R)","Normal heart"], ["Left axis (LAD < β30Β°)","Positive","Negative","LBBB, LAHB, inferior MI, LVH"], ["Right axis (RAD > +90Β°)","Negative","Positive","RBBB, LPHB, RVH, PE, dextrocardia"], ["Northwest (extreme)","Negative","Negative","VT, severe RVH, lead reversal"]], [110,100,100,170]), sp(6), BulletCard([ "MNEMONIC: Both up = Normal | I up, aVF down = Left | I down, aVF up = Right | Both down = NW", "LAD causes: Left hemiblock (LAHB) most common, inferior MI, WPW, pacing", "RAD causes: RVH, PE, LPHB, lateral MI, WPW, ASD, dextrocardia", "Pseudo-axis deviation: Check for lead reversal first (RA-LA swap)!", ],accent=C_PURPLE,bg=C_CARD2), PageBreak(), ] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 5 β SINUS RHYTHMS # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(8), SectionBanner("π CHAPTER 4 : SINUS RHYTHMS & VARIATIONS",bg=C_PURPLE,fg=C_WHITE,fsize=14), sp(6), P("Normal Sinus Rhythm (NSR)",h2s), ECGTrace("normal",label="Normal Sinus Rhythm β Rate 60-100bpm, Regular, P before every QRS"), sp(4), BulletCard([ "Rate: 60β100 bpm | Rhythm: Regular | P wave: upright II, inverted aVR", "PR interval: 0.12β0.20 sec, CONSTANT beat to beat", "QRS: < 0.10 sec (narrow) | T wave: upright in I, II, V3-V6", "Every P is followed by a QRS β 1:1 conduction through AV node", "The gold standard β know this pattern deeply; everything else is a deviation", ],accent=C_GREEN), sp(6), P("Sinus Bradycardia",h2s), BulletCard([ "Rate < 60 bpm, otherwise identical morphology to NSR", "Causes: Athletes (normal), vagal activation, inferior MI, hypothyroidism, " "hypothermia, beta-blockers, calcium channel blockers, digoxin", "Symptoms when severe: dizziness, presyncope, syncope, heart failure", "Treatment: Asymptomatic β no treatment | Symptomatic β Atropine 0.5 mg IV " "(max 3 mg) | Transcutaneous pacing if atropine fails | Permanent pacemaker if recurrent", ],accent=C_CYAN), sp(6), P("Sinus Tachycardia",h2s), BulletCard([ "Rate 100β150 bpm, normal P waves preceding each QRS, regular rhythm", "ALWAYS a response to something else β treat the cause, not the rate", "Causes: Pain, fever, anxiety, PE, hypovolaemia, anaemia, thyrotoxicosis, " "heart failure, drugs (salbutamol, caffeine, cocaine, atropine)", "Treatment: Identify and treat precipitant β fluids, antipyretics, analgesia, etc.", "Rarely: Inappropriate sinus tachycardia (IST) β beta-blockers or ivabradine", ],accent=C_ORANGE), sp(6), P("Sinus Arrhythmia, Pause & Sick Sinus Syndrome",h2s), BulletCard([ "Sinus arrhythmia: Rate varies with breathing; normal in young / athletes. No treatment.", "Sinus pause/arrest: Sudden loss of P wave; if >3 sec β symptomatic β atropine / PM", "Sick Sinus Syndrome (SSS): alternates between tachy and profound brady / arrest", "SSS causes: Fibrosis of SA node, ischaemia, infiltrative disease, aging", "SSS treatment: PERMANENT PACEMAKER (DDD type) β the only definitive treatment", "Avoid rate-slowing drugs (digoxin, beta-blockers, CCBs) in SSS without pacemaker", ],accent=C_GOLD), PageBreak(), ] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 6 β ATRIAL ARRHYTHMIAS # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(8), SectionBanner("π΄ CHAPTER 5 : ATRIAL ARRHYTHMIAS",bg=C_RED,fg=C_WHITE,fsize=15), sp(6), P("Atrial Fibrillation (AF) β Most Common Cardiac Arrhythmia",h2s), ECGTrace("afib",label="ATRIAL FIBRILLATION β Irregularly irregular, no P waves, chaotic baseline"), sp(4), BulletCard([ "KEY FEATURE: Irregularly IRREGULAR ventricular rhythm β no two R-R intervals the same", "No P waves β replaced by irregular chaotic fibrillatory (f) waves", "Atrial rate 350β600 bpm (unmeasurable) | Ventricular rate variable", "Causes: HTN (#1), IHD, mitral valve disease, thyrotoxicosis, alcohol (holiday heart), " "PE, cardiomyopathy, post-cardiac surgery", "CHA2DS2-VASc score: 0 (men) or 1 (women) = no anticoagulation; β₯1 (men) β₯2 (women) = anticoagulate", "CHADS mnemonic: CHF, HTN, Ageβ₯75(Γ2), DM, Stroke(Γ2), Vascular disease, Age 65-74, Sex female", ],accent=C_RED), sp(4), colored_table( [["Goal","Drug / Method","Key Points"], ["Rate Control","Bisoprolol / Metoprolol (beta-blocker)","Target resting HR < 110bpm"], ["Rate Control","Diltiazem / Verapamil (CCB)","Avoid if low EF / HF"], ["Rate Control","Digoxin","Good for sedentary patients or HF"], ["Rhythm Control","DC Cardioversion (synchronised 200J biphasic)","<48hrs or anticoagulated β₯3 weeks"], ["Rhythm Control","Flecainide / Propafenone","No structural heart disease"], ["Rhythm Control","Amiodarone","AF + HF or LVH"], ["Anticoagulation","Apixaban / Rivaroxaban / Edoxaban (DOACs)","Non-valvular AF preferred"], ["Anticoagulation","Warfarin (INR 2β3)","Valvular AF, mechanical valve, severe CKD"], ["Ablation","Pulmonary vein isolation (PVI)","Symptomatic paroxysmal AF, younger patients"]], [110,160,160]), sp(6), P("Atrial Flutter",h2s), BulletCard([ "Atrial rate 250β350 bpm β SAWTOOTH flutter waves (F waves) in II, III, aVF", "2:1 block β ventricular rate ~150 bpm (CLASSIC β always suspect if HR exactly 150)", "Variable or fixed block: 2:1, 3:1, 4:1 (always a RATIO of atrial rate)", "Causes: Same as AF β ischaemia, RHD, PE, post-surgery, thyrotoxicosis", "Treatment: Rate control (beta-blocker / CCB / digoxin) OR rhythm control (cardioversion)", "Anticoagulate same as AF if duration >48 hrs", "Cavotricuspid isthmus ablation: highly effective cure (>95%) β first-line for recurrent flutter", ],accent=C_ORANGE), sp(6), P("SVT β Supraventricular Tachycardia",h2s), BulletCard([ "Narrow complex tachycardia, rate 150β250 bpm, REGULAR, sudden onset and offset", "P waves hidden in QRS (AVNRT) or after QRS as pseudo-S in II, pseudo-R' in V1 (AVNRT)", "Types: AVNRT (60%), AVRT/WPW (30%), Atrial tachycardia (10%)", "TREATMENT LADDER: 1. Valsalva manoeuvre (modified: legs elevated) " "2. Adenosine 6mg rapid IV push (12mg if no response, then 18mg) " "3. Verapamil 5mg IV or Metoprolol IV 4. Synchronised DCCV if haemodynamically unstable", "NEVER give adenosine in WPW with wide complex (pre-excited AF) β may cause VF!", ],accent=C_PURPLE), PageBreak(), ] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 7 β VENTRICULAR ARRHYTHMIAS # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(8), SectionBanner("β CHAPTER 6 : VENTRICULAR ARRHYTHMIAS β CRITICAL!",bg=C_RED,fg=C_WHITE,fsize=14), sp(6), P("PVCs β Premature Ventricular Complexes",h2s), BulletCard([ "Early, WIDE (>0.12s), bizarre QRS β no preceding P wave", "T wave in OPPOSITE direction to QRS (discordant) β key feature", "Full compensatory pause follows (sinus P not disturbed)", "Uniform = same morphology (unifocal) | Multiform = multiple foci (more concerning)", "Bigeminy: every 2nd beat PVC | Trigeminy: every 3rd | Couplet: 2 in a row | Triplet = nsVT", "Causes: IHD, hypokalaemia, hypomagnesaemia, hypoxia, caffeine, stimulants, anxiety", "Treatment: Benign isolated PVCs in normal hearts β reassure. If symptoms / frequent: beta-blockers / ablation", ],accent=C_ORANGE), sp(6), P("Ventricular Tachycardia (VT)",h2s), ECGTrace("vtach",label="VT β Wide QRS tachycardia, rate 120-250bpm, AV dissociation"), sp(4), BulletCard([ "β₯ 3 consecutive PVCs at rate >100 bpm", "Wide QRS (>0.12s), bizarre morphology, REGULAR rhythm", "AV dissociation: P waves 'march through' independent of QRS β DIAGNOSTIC of VT", "Capture beats: P conducts to produce narrow QRS (proves AV dissociation)", "Fusion beats: Hybrid between sinus and VT beat (more evidence for VT)", "Sustained VT (>30 sec or haemodynamically compromised) = EMERGENCY", "REMEMBER: Wide complex tachycardia = VT until proven otherwise!", ],accent=C_RED), colored_table( [["Clinical State","Action","Drug/Energy"], ["Pulseless VT","CPR + Immediate defibrillation","200J biphasic, then 300J, 360J"], ["VT + pulse, unstable","Synchronised DC cardioversion","100-200J (sedate if conscious)"], ["VT + pulse, stable","IV Amiodarone","300mg over 20-60 min, then infusion"], ["VT + pulse, stable (alt.)","IV Lidocaine","1-1.5 mg/kg bolus"], ["Recurrent VT","ICD implantation","Gold standard secondary prevention"], ["VT in structural HD","Beta-blocker + ICD","Reduce sudden cardiac death risk"]], [130,160,160]), sp(6), P("Ventricular Fibrillation (VF) β CARDIAC ARREST",h2s), ECGTrace("vfib",label="VF β Chaotic electrical activity, NO QRS β DEFIBRILLATE IMMEDIATELY"), sp(4), BulletCard([ "CHAOTIC irregular waves β absolutely no recognisable QRS complexes", "NO cardiac output β patient collapses, pulseless, unconscious in seconds", "IMMEDIATELY FATAL without CPR + defibrillation", "Causes: Acute MI (#1), cardiomyopathy, hypokalaemia, hypothermia, electrocution, channelopathies", "TREATMENT: Shout for help + START CPR (30:2) + DEFIBRILLATE 200J AS FAST AS POSSIBLE", "Adrenaline (epinephrine) 1mg IV every 3-5 min after 3rd shock", "Amiodarone 300mg IV after 3rd shock, 150mg after 5th shock", "Continue ALS algorithm β aim ROSC. Consider reversible causes (4H + 4T)", ],accent=C_RED), sp(5), P("Torsades de Pointes (TdP) β Twisting of the Points",h2s), BulletCard([ "Polymorphic VT: QRS complexes appear to TWIST around the isoelectric baseline", "Associated with prolonged QT interval (QTc >500ms = very high risk)", "Self-terminating (can recur) or degenerate into VF", "Drug causes: Amiodarone, sotalol, quinolones, macrolides, antipsychotics (haloperidol, quetiapine), " "methadone, domperidone, TCAs", "Electrolyte causes: Hypokalaemia, hypomagnesaemia, hypocalcaemia", "TREATMENT: IV Magnesium Sulphate 2g (8mmol) over 10-15min β FIRST LINE!", "Remove offending drug | Correct K+ (keep >4.5) | Correct Mg2+ | Overdrive pacing at 90-110bpm", "NOT amiodarone β it prolongs QT and worsens TdP!", ],accent=C_GOLD), PageBreak(), ] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 8 β HEART BLOCKS # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(8), SectionBanner("π§± CHAPTER 7 : AV HEART BLOCKS",bg=C_YELLOW,fg=C_BG,fsize=15), sp(6), P("1st Degree AV Block",h2s), BulletCard([ "PR interval > 0.20 sec (> 1 large box) β FIXED and constant", "Every P wave IS followed by QRS β just delayed", "Causes: Increased vagal tone, athletes, inferior MI, myocarditis, drugs " "(digoxin, beta-blockers, CCBs, amiodarone)", "Treatment: None required in most cases. Monitor. Treat underlying cause.", "Rarely progresses β but if 'first degree' + fascicular block β consider PM evaluation", ],accent=C_GREEN), sp(6), P("2nd Degree Block β Mobitz Type 1 (Wenckebach)",h2s), BulletCard([ "PR interval PROGRESSIVELY LENGTHENS with each beat until one P wave is NOT conducted (QRS drops)", "Pattern: GROUPED BEATING β groups of QRS complexes followed by a pause", "Common ratios: 3:2, 4:3, 5:4 (atrial: ventricular beats)", "Level: AV node β PROXIMAL, generally BENIGN", "Causes: Inferior MI (RCA involvement), vagal tone, digoxin, myocarditis", "Treatment: Usually monitor. Atropine if symptomatic. Rarely needs pacing.", ],accent=C_CYAN), sp(6), P("2nd Degree Block β Mobitz Type 2",h2s), BulletCard([ "PR interval CONSTANT (does not lengthen) β then P wave SUDDENLY not conducted without warning", "QRS usually WIDE (block at bundle of His or below)", "More dangerous than Wenckebach β can progress suddenly to complete block!", "Causes: Anterior MI (LAD), fibrosis, cardiac surgery, Lyme disease", "Treatment: URGENT temporary pacing followed by permanent pacemaker!", ],accent=C_ORANGE), sp(6), P("3rd Degree (Complete) Heart Block",h2s), ECGTrace("chb",label="COMPLETE HEART BLOCK β Blue P waves and Red QRS are completely independent (AV dissociation)"), sp(4), BulletCard([ "COMPLETE AV DISSOCIATION β P waves and QRS complexes beat INDEPENDENTLY", "Atrial rate (P waves): 60β100 bpm (SA node driving atria normally)", "Ventricular escape rate: 20β40 bpm (slow, wide if ventricular; 40-60 if junctional)", "Wide QRS = ventricular escape (unstable, unreliable) | Narrow QRS = junctional escape (safer)", "Symptoms: Syncope (Stokes-Adams attack), haemodynamic collapse, heart failure", "Causes: Inferior MI (transient, RCA), anterior MI (permanent), Lyme, sarcoidosis, " "SLE, drug toxicity, congenital (maternal SLE), surgical damage", "Treatment: PERMANENT PACEMAKER β absolutely indicated. Temporary: transcutaneous / transvenous pacing", ],accent=C_RED), sp(5), colored_table( [["Block","PR interval","Dropped beats?","QRS width","Urgency"], ["1st degree","Fixed >0.20s","No","Narrow","Monitor"], ["2nd Mobitz I","Progressively lengthens","Yes β periodic","Narrow","Monitor/Atropine"], ["2nd Mobitz II","Fixed β then sudden drop","Yes β sudden","Wide","URGENT PACING"], ["3rd (CHB)","AV dissociation","All P blocked","Wide/narrow","PERMANENT PM"]], [100,130,110,80,110]), PageBreak(), ] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 9 β BUNDLE BRANCH BLOCKS # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(8), SectionBanner("πΏ CHAPTER 8 : BUNDLE BRANCH BLOCKS",bg=C_GREEN,fg=C_BG,fsize=15), sp(6), P("Right Bundle Branch Block (RBBB)",h2s), BulletCard([ "QRS > 0.12 sec (complete RBBB) | 0.10β0.12 sec (incomplete RBBB)", "CLASSIC V1: RSR' pattern β Rabbit ears / M-shape (wide rSR')", "V6: Wide, slurred S wave (W-shape)", "Secondary T inversion V1-V3 and ST depression V1-V3 β DO NOT diagnose ischaemia here", "Mnemonic: MaRRoW β RBBB = M in V1 (RSR'), W in V6 (wide S)", "RBBB can be NORMAL variant. Also: PE, RVH, ASD, ischaemia, post-cardiac surgery", "New RBBB + anterior chest pain = could be RBBB due to LAD occlusion β treat seriously", ],accent=C_BLUE), sp(6), P("Left Bundle Branch Block (LBBB)",h2s), BulletCard([ "QRS > 0.12 sec | Broad QS or rS in V1 (W shape) | Broad R in I, aVL, V5, V6 (M shape)", "Mnemonic: WiLLiaM β LBBB = W in V1, M in V6", "ALWAYS PATHOLOGICAL β never a normal finding", "DO NOT diagnose ST changes or ischaemia in LBBB β secondary changes are EXPECTED", "NEW LBBB + chest pain = treat as STEMI EQUIVALENT β activate cath lab immediately", "Sgarbossa Criteria (diagnose MI in LBBB): Concordant ST elevation β₯1mm = +3pts; " "Concordant ST depression β₯1mm in V1-V3 = +3pts; Discordant STE β₯5mm = +2pts. Score β₯3 = +MI", "Causes: IHD, HTN, dilated cardiomyopathy, aortic stenosis, Chagas disease", ],accent=C_RED), sp(6), colored_table( [["Feature","RBBB","LBBB"], ["V1 QRS shape","RSR' = Rabbit ears (M)","QS or rS (W shape)"], ["V6 QRS shape","Wide slurred S (W shape)","Tall broad R (M shape)"], ["QRS duration","> 0.12 sec","> 0.12 sec"], ["Pathological?","Not always (can be normal)","ALWAYS pathological"], ["Secondary ST-T","Depression + T inv V1-V3","ST/T changes opposite QRS direction"], ["New onset + chest pain","May indicate anterior MI","STEMI EQUIVALENT β cath lab!"], ["Mnemonic","MaRRoW","WiLLiaM"]], [120,190,170]), sp(6), P("Fascicular Blocks & Bifascicular Block",h2s), BulletCard([ "LAHB (Left Anterior Hemiblock): LAD (axis < -45Β°), qR in I/aVL, rS in II/III/aVF, QRS <0.12s", "LPHB (Left Posterior Hemiblock): RAD (>+120Β°), rS in I, qR in III β diagnosis of exclusion", "Bifascicular block: RBBB + LAHB (most common) or RBBB + LPHB", "Trifascicular block: Bifascicular + 1st degree block (PR prolonged) β consider permanent PM", "Clinical importance: Bifascicular disease at risk of sudden complete block in setting of anterior MI", ],accent=C_PURPLE,bg=C_CARD2), PageBreak(), ] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 10 β MI / STEMI / NSTEMI # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(8), SectionBanner("β€ CHAPTER 9 : MYOCARDIAL INFARCTION β STEMI & NSTEMI",bg=C_RED,fg=C_WHITE,fsize=13), sp(6), P("ECG Evolution of MI β Changes Over Time",h2s), colored_table( [["Time After MI","ECG Changes","What's Happening in the Myocardium"], ["First minutes","Tall, peaked (hyperacute) T waves","Acute ischaemia β EARLIEST sign, fleeting!"], ["0β6 hours","ST elevation β₯2mm (chest leads) / β₯1mm (limb)","Full thickness ischaemia β injury current"], ["6β24 hours","Q waves appear, ST still elevated","Transmural necrosis beginning"], ["24β72 hours","T wave inversion, Q waves deepen","Evolving infarction, scar forming"], ["Daysβweeks","ST normalises, Q waves + T inversion","Healing phase"], ["Monthsβyears","Only Q waves remain (permanent)","Scar β old MI marker for life"]], [80,170,200]), sp(6), P("STEMI β Localisation by Territory",h2s), ECGTrace("stemi",label="STEMI β Massive ST elevation with hyperacute T waves and evolving Q waves"), sp(4), colored_table( [["Territory","ST elevation leads","Culprit artery","Reciprocal ST depression"], ["Inferior","II, III, aVF β₯1mm","RCA (80%) / LCx (20%)","I, aVL"], ["Anterior","V1, V2, V3, V4 β₯2mm","LAD (proximal)","II, III, aVF (mild)"], ["Lateral","I, aVL, V5, V6","LCx","V1, V2"], ["Extensive anterior","V1-V6 + I + aVL","Proximal LAD (widow maker)","II, III, aVF"], ["Posterior","ST depression V1-V3 + tall R V1","LCx or RCA","V1-V3 = reciprocal STE"], ["RV infarct","V4R β₯1mm (right-sided leads)","Proximal RCA","Associated inferior STE"]], [80,130,120,130]), sp(6), P("STEMI Treatment β TIME IS MUSCLE!",h2s), BulletCard([ "IMMEDIATE: Call for help + 12-lead ECG within 10 min of presentation", "Aspirin 300mg PO STAT + Ticagrelor 180mg (or Prasugrel 60mg, or Clopidogrel 300-600mg)", "IV Heparin (UFH 60 units/kg bolus) β anticoagulation", "Oxygen only if SpO2 < 94% β hyperoxia is harmful in uncomplicated MI!", "Morphine 2-5mg IV for pain (with caution β slows platelet inhibitor absorption)", "PRIMARY PCI: Door-to-balloon time < 90 min β GOLD STANDARD treatment", "Thrombolysis (Tenecteplase / Alteplase) if PCI not available within 120 min", "Beta-blocker PO within 24hrs if stable (no heart failure, no bradycardia)", "ACE inhibitor within 24hrs (especially anterior MI / low EF)", "High-dose Statin: Atorvastatin 80mg β start immediately", "Secondary prevention: DAPT (aspirin + ticagrelor/clopidogrel) for 12 months minimum", ],accent=C_RED), PageBreak(), ] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 11 β SPECIAL SYNDROMES # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(8), SectionBanner("π CHAPTER 10 : SPECIAL SYNDROMES",bg=C_PURPLE,fg=C_WHITE,fsize=15), sp(6), P("Wolff-Parkinson-White (WPW)",h2s), BulletCard([ "Accessory pathway (Bundle of Kent) bypasses AV node β ventricles pre-excited", "TRIAD: Short PR (<0.12s) + Delta wave (slurred QRS upstroke) + Wide QRS", "Risk: AF with fast antegrade conduction via accessory path β VF β SCD", "ECG in AF+WPW: Irregularly irregular, WIDE complex, very fast (>200bpm) β DANGEROUS", "NEVER give adenosine, digoxin, verapamil, beta-blockers in AF+WPW β may cause VF!", "Acute SVT (narrow): Adenosine safe | Acute pre-excited AF: Procainamide / DCCV", "Definitive treatment: Radiofrequency catheter ablation of accessory pathway (>95% success)", ],accent=C_YELLOW), sp(6), P("Brugada Syndrome",h2s), BulletCard([ "Characteristic ECG: Type 1 β Coved-type ST elevation (>2mm) in V1-V2 + RBBB pattern", "Risk of VF and sudden death β predominantly young Asian males, during sleep/fever", "SCN5A gene mutation (sodium channel) β autosomal dominant inheritance", "ECG may be dynamic β fever or sodium channel blockers (ajmaline/flecainide) can UNMASK it", "AVOID: Class IC drugs, tricyclics, excessive alcohol, fever (treat aggressively)", "Treatment: ICD implantation if symptomatic (syncope/SCA survivor)", "Quinidine reduces VT burden and can be used as adjunct to ICD", ],accent=C_BLUE), sp(6), P("Pericarditis",h2s), BulletCard([ "DIFFUSE ST elevation in MULTIPLE LEADS (not confined to one territory) β concave/saddle shape", "PR DEPRESSION β classic and almost pathognomonic (present in 80% of cases)!", "Widespread changes unlike MI (which is territorial with reciprocal changes)", "Stages: 1: STE + PR dep β 2: Normalise β 3: T inversion β 4: Normal", "Causes: Viral (most common β Coxsackie), idiopathic, bacterial, TB, autoimmune, uraemia", "Treatment: NSAIDs (ibuprofen 600mg TDS x 2 weeks) + Colchicine 0.5mg BD x 3 months", "Avoid exercise during acute phase | Steroids only if refractory or contraindication to NSAIDs", ],accent=C_CYAN), sp(6), P("Pulmonary Embolism (PE)",h2s), BulletCard([ "CLASSIC pattern: S1Q3T3 β deep S in I, Q wave in III, T inversion in III", "Most common ECG finding: Sinus tachycardia (not S1Q3T3!)", "Right heart strain: RAD, RBBB (complete/incomplete), P pulmonale", "T inversion V1-V4 = RV strain pattern", "New AF or atrial flutter can occur due to right atrial pressure rise", "REMEMBER: Normal ECG does NOT exclude PE β normal in up to 25% of cases", "ECG is supportive evidence. Confirm with CT pulmonary angiogram (CTPA) β gold standard", ],accent=C_ORANGE), PageBreak(), ] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 12 β ELECTROLYTES & DRUGS # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(8), SectionBanner("π§ͺ CHAPTER 11 : ELECTROLYTES & DRUG EFFECTS",bg=C_CYAN,fg=C_BG,fsize=14), sp(6), P("Hyperkalaemia β Progressive ECG Changes",h2s), colored_table( [["K+ Level (mmol/L)","ECG Change","Clinical Action"], ["5.5β6.0","Tall, peaked, narrow, symmetric T waves","Close monitoring, dietary K+ restriction"], ["6.0β7.0","Flat P waves, PR prolongation, QRS widening","Start treatment urgently"], ["7.0β8.0","Loss of P waves, marked QRS widening, sine wave","Emergency treatment NOW"], ["> 8.0","VF or asystole","Immediate dialysis + full resuscitation"]], [100,200,150]), sp(4), P("Hyperkalaemia Treatment (in order)",h2s), BulletCard([ "1. Calcium gluconate 10ml 10% IV over 5-10min β membrane stabilisation (takes effect in 1-2 min!)", "2. Insulin 10 units + Dextrose 50ml 50% IV β shifts K+ into cells (lasts 4-6 hrs)", "3. Salbutamol 10-20mg nebulised β shifts K+ into cells (additive to insulin)", "4. NaHCO3 (sodium bicarbonate) 50-100 mEq β only if severe acidosis", "5. Calcium resonium (sodium/calcium polystyrene sulfonate) β removes K+ from gut (PO or PR)", "6. Haemodialysis β definitive treatment if refractory or renal failure", ],accent=C_RED), sp(6), P("Hypokalaemia",h2s), BulletCard([ "Flat/inverted T waves | Prominent U wave (appears after T wave)", "U wave taller than T wave = significant hypokalaemia (<3.0 mmol/L)", "Prolonged QU interval (may look like prolonged QT β can confuse!)", "Risk of TdP, VT, and cardiac arrest", "Treatment: PO potassium chloride (mild) | IV KCl max 20 mmol/hr with continuous monitoring (severe)", "Always correct Mg2+ simultaneously β hypomagnesaemia causes refractory hypokalaemia", ],accent=C_YELLOW), sp(6), colored_table( [["Electrolyte","ECG Effect","Memory Trick"], ["Hypercalcaemia","SHORT QT interval","HIGH Ca = SHORT QT (think: calcium contracts)"], ["Hypocalcaemia","LONG QT interval","LOW Ca = LONG QT (think: needs more time)"], ["Hypermagnesaemia","PR prolongation, AV block, widened QRS","Too much Mg = blocks everything"], ["Hypomagnesaemia","TdP, VT, QT prolongation","Low Mg = arrhythmias (treat with MgSO4)"], ["Hypothermia","J (Osborn) waves + bradycardia + QT prolongation","Cold = J waves (like a J-shaped hump)"]], [120,190,170]), sp(6), P("Drug Effects",h2s), colored_table( [["Drug","ECG Effect","Management of Toxicity"], ["Digoxin (therapeutic)","Reverse tick (down-sloping ST dep), bradycardia, PR prolongation","β"], ["Digoxin (toxic)","AV block, AT with block, bidirectional VT","Digibind (Fab fragments) β specific antidote"], ["Tricyclics (TCA)","Wide QRS, RAD, prolonged QT, sinus tachy","IV NaHCO3 (sodium bicarb) β narrows QRS"], ["Beta-blockers","Bradycardia, PR prolongation, AV block","Atropine, IV glucagon, high-dose insulin"], ["Cocaine","ST elevation, VT, VF, sinus tachy","Benzodiazepines, AVOID beta-blockers"], ["Amiodarone","Prolonged QT, bradycardia, thyroid issues","Withdraw drug, supportive"]], [100,180,180]), PageBreak(), ] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 13 β HYPERTROPHY + FINAL SUMMARY # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(8), SectionBanner("π CHAPTER 12 : HYPERTROPHY & ENLARGEMENT",bg=C_BLUE,fg=C_WHITE,fsize=14), sp(6), P("Left Ventricular Hypertrophy (LVH)",h2s), BulletCard([ "Sokolov-Lyon: S in V1 + R in V5 or V6 β₯ 35mm β MOST USED criterion", "Cornell: R in aVL + S in V3 > 28mm (men) / > 20mm (women)", "LVH strain pattern: ST depression + T inversion in I, aVL, V5, V6 (lateral leads)", "Other features: LAD, broad notched P wave (LAE), prolonged QRS", "Causes: HTN (#1 cause), HCM, aortic stenosis, aortic regurgitation, MR", ],accent=C_RED), sp(5), P("Right Ventricular Hypertrophy (RVH)",h2s), BulletCard([ "Dominant R wave in V1 (R > S in V1) β normally S > R in V1", "R in V1 + S in V5 or V6 β₯ 11mm", "Right axis deviation (RAD > +90Β°)", "RV strain: ST depression + T inversion V1-V3", "Causes: Pulmonary hypertension (#1), COPD, mitral stenosis, ASD, VSD, PE, PS", ],accent=C_BLUE), sp(5), P("Atrial Enlargement",h2s), colored_table( [["Type","ECG Finding","Causes"], ["Left atrial enlargement (P mitrale)","P duration >0.12s, bifid P in II, deep -ve V1 component","Mitral stenosis, LVF, HTN"], ["Right atrial enlargement (P pulmonale)","Tall peaked P >2.5mm in II, +ve P V1 >1.5mm","COPD, pulmonary HTN, tricuspid stenosis"]], [130,220,120]), sp(8), SectionBanner("π MEGA SUMMARY TABLE β ALL DIAGNOSES",bg=C_ORANGE,fg=C_WHITE,fsize=13), sp(6), colored_table( [["Condition","Key ECG Finding","First-line Treatment"], ["Normal Sinus Rhythm","Regular, 60-100, P before QRS","None"], ["AF","Irregularly irregular, no P waves","Rate control + anticoagulation (DOACs)"], ["Atrial Flutter","Sawtooth F waves, 2:1 block (~150bpm)","Rate control / cardioversion / ablation"], ["SVT","Narrow complex tachy 150-250, regular","Adenosine 6mg IV, then 12mg"], ["VT","Wide QRS tachy, AV dissociation","Amiodarone or DCCV; defibrillation if pulseless"], ["VF","Chaotic, no QRS complexes","Immediate defibrillation 200J + CPR"], ["TdP","Polymorphic VT + long QT","IV MgSO4 2g + remove offending drug"], ["1st degree AVB","PR > 0.20s, fixed","Monitor only"], ["2nd degree Mobitz I","Progressive PR until QRS dropped","Monitor; atropine if symptomatic"], ["2nd degree Mobitz II","Fixed PR, sudden QRS dropped, wide QRS","URGENT pacing"], ["3rd degree (CHB)","Complete AV dissociation","Permanent pacemaker"], ["RBBB","RSR' in V1, wide S in V6","Treat underlying cause"], ["LBBB","W in V1, M in V6","ALWAYS pathological β treat cause; if new + pain: PCI"], ["STEMI","STE β₯1-2mm territorial, evolving Q","Primary PCI < 90 min"], ["NSTEMI","ST dep / T inv, Trop positive","Heparin + PCI within 72hrs"], ["Pericarditis","Diffuse STE + PR depression","NSAIDs + Colchicine 3 months"], ["WPW","Short PR + Delta wave + wide QRS","Ablation; avoid AV nodal drugs in AF+WPW"], ["Hyperkalaemia","Peaked T β QRS wide β sine wave β VF","Ca gluconate + insulin/dextrose"], ["Hypokalaemia","Flat T + prominent U wave","IV/PO potassium + correct magnesium"], ["PE","Sinus tachy; S1Q3T3; RBBB; T inv V1-V4","Anticoagulation / thrombolysis / embolectomy"], ["LVH","Sokolov β₯35mm + strain pattern","Treat HTN, beta-blocker, ACEi"], ["Brugada","Coved STE V1-V2, RBBB-like","ICD; avoid triggers"], ["Digoxin toxicity","AV block, bidirectional VT","Digibind (Fab)"]], [120,200,160]), PageBreak(), ] # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ # PAGE 14 β MNEMONICS + CLINICAL PEARLS # βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ story+=[ sp(8), SectionBanner("π‘ CHAPTER 13 : MNEMONICS, PEARLS & TRAPS",bg=C_GOLD,fg=C_BG,fsize=14), sp(6), P("Essential Mnemonics You Must Know",h1s), BulletCard([ "WiLLiaM MaRRoW: LBBB=W in V1/M in V6 | RBBB=M in V1/W in V6", "CHADS-VASc: CHF, HTN, Age>75(x2), DM, Stroke(x2), Vascular, Age65-74, Sex female", "4H + 4T reversible arrest causes: Hypoxia, Hypovolaemia, Hypo/Hyperkalaemia, Hypothermia " "/ Tension pneumo, Tamponade, Thrombosis (PE/MI), Toxins", "DEAD for WPW: Delta wave, Every P has QRS, Axis check, Duration (short PR)", "AVRT vs AVNRT: Both narrow SVT. AVRT has retrograde P AFTER QRS; AVNRT P hidden IN QRS", "Rate ~150 + flutter waves vs SVT: Look for sawtooth in II, III, aVF to identify flutter", "Sgarbossa for LBBB: Concordant STE β₯1mm = positive for MI (ignore discordant changes)", ],accent=C_GOLD,bg=C_CARD2), sp(6), P("Clinical Traps β Common Mistakes",h2s), BulletCard([ "TRAP: Heart rate ~150 β always look for atrial flutter 2:1 FIRST before calling SVT", "TRAP: Wide complex tachycardia = VT until proven otherwise. Never assume aberrant SVT!", "TRAP: New LBBB + chest pain = STEMI equivalent. Call cath lab. Don't wait.", "TRAP: Normal ECG does NOT exclude MI (sensitivity ~55% for NSTEMI, 25% for PE)", "TRAP: Hyperkalaemia peaked T can mimic hyperacute MI β always check U&E", "TRAP: ST depression in V1-V3 may mean POSTERIOR STEMI β do V7-V9 and posterior leads", "TRAP: Digoxin reverse-tick ST change β ischaemia in isolation β correlate clinically", "TRAP: Lead reversal (RA-LA swap) mimics dextrocardia and LAD β check clinically", "TRAP: Never give digoxin/verapamil/BB in WPW+AF β can cause VF", "TRAP: Amiodarone + long QT = TdP risk. Monitor QTc in all patients on amiodarone.", ],accent=C_RED,bg=C_CARD1), sp(6), P("Normal Variants β Do Not Over-Diagnose",h2s), BulletCard([ "Early repolarisation: Concave ST elevation V2-V4 in young athletes β benign", "Juvenile T inversion: T inversion V1-V3 in children/young women β normal", "Incomplete RBBB: QRS 0.10-0.12s with RSR' V1 β common normal variant", "1st degree AV block in athletes: high vagal tone β benign if asymptomatic", "Sinus arrhythmia: HR varying with breathing in young β completely normal", "Voltage criteria for LVH in thin patients / athletes β false positive common", ],accent=C_GREEN,bg=C_CARD2), sp(8), HeartFace(size=80), sp(8), SectionBanner("π MIHIR β You Are Now an ECG Champion! Keep Practising Every Day!",bg=C_RED,fsize=12), sp(6), P("Practice tip: Read one real ECG daily. Always use the 8-step method. " "Correlate ECG findings with clinical history. When in doubt β always ask!",ctr), sp(4), P("Compiled exclusively for Mihir β’ ECG Master Guide β’ All Rights of Excellence Reserved", S("fin",fontSize=8,textColor=C_LTGRAY,alignment=TA_CENTER)), ] # Build doc = SimpleDocTemplate( OUTPUT, pagesize=A4, leftMargin=40, rightMargin=40, topMargin=55, bottomMargin=50, title="ECG Master Guide β Mihir", author="Mihir" ) doc.build(story, onFirstPage=on_page, onLaterPages=on_page) print("SUCCESS:", OUTPUT) PYEOF
ls -lh /tmp/workspace/ecg-pdf/ECG_MasterGuide_Mihir.pdf
ECG MasterGuide Mihir
PDF Document Β· PDF
| Chapter | Content |
|---|---|
| Cover | Cartoon heart with face + stethoscope, full annotated ECG wave |
| Ch 1 | What is ECG, ECG paper, 12-lead system with artery mapping |
| Ch 2 | P, QRS, T, U waves β every interval & segment with labelled ECG diagram |
| Ch 3 | 8-Step systematic ECG reading method + axis chart |
| Ch 4 | Sinus rhythms β NSR, bradycardia, tachycardia, SSS + treatments |
| Ch 5 | AF, Atrial Flutter, SVT β ECG strips + full treatment tables |
| Ch 6 | VT, VF, PVCs, TdP β drawn rhythm strips + emergency treatment |
| Ch 7 | Heart blocks 1st/2nd/3rd degree β CHB strip + pacemaker indications |
| Ch 8 | RBBB, LBBB, fascicular blocks β WiLLiaM MaRRoW mnemonic |
| Ch 9 | STEMI evolution, territory localisation, STEMI treatment protocol |
| Ch 10 | WPW, Brugada, Pericarditis, PE β special syndromes |
| Ch 11 | Hyperkalaemia, hypokalaemia, calcium, digoxin, drug effects |
| Ch 12 | LVH, RVH, atrial enlargement + MEGA SUMMARY TABLE of all 23 diagnoses |
| Ch 13 | Mnemonics, clinical traps, normal variants, final tips |