Supra glottic airway devices - 10 marker question
| Feature | 1st Generation | 2nd Generation |
|---|---|---|
| Gastric tube port | No | Yes |
| Seal pressure | Lower (~20 cm H₂O) | Higher (~30 cm H₂O) |
| Aspiration protection | Minimal | Better (drain channel) |
| Examples | LMA Classic, LMA Unique, Combitube | ProSeal LMA, Supreme LMA, i-gel |
| Size | Patient | Weight (kg) | Cuff Volume (mL) |
|---|---|---|---|
| 1 | Neonate/Infant | <6.5 | 2-4 |
| 2 | Child | 6.5-20 | Up to 10 |
| 3 | Small adult | 30-50 | Up to 20 |
| 4 | Normal adult | 50-70 | Up to 30 |
| 5 | Large adult | 70-100 | Up to 40 |
| 6 | XL adult | >100 | Up to 50 |

| Complication | Notes |
|---|---|
| Aspiration | Most serious; SADs do not reliably prevent aspiration |
| Inability to ventilate | Rare; usually due to malposition or laryngospasm |
| Laryngospasm / bronchospasm | Especially on premature removal |
| Postoperative sore throat | 4-50% incidence (lower than ETT at 30-60%) |
| Nerve injury | Hypoglossal, lingual, recurrent laryngeal nerves (pressure neuropraxia) - resolve in hours to 18 months |
| Gastric distension | If esophagus lies within the cuff rim |
| Device | Cuff Type | Gastric Drain | Intubation Conduit | Generation |
|---|---|---|---|---|
| LMA Classic | Inflatable | No | No (with FIS possible) | 1st |
| LMA Unique | Inflatable (disposable) | No | No | 1st |
| ProSeal LMA | Inflatable | Yes | No | 2nd |
| Supreme LMA | Inflatable (disposable) | Yes | No | 2nd |
| i-gel | Gel (non-inflatable) | Yes | Yes | 2nd |
| LMA Fastrach (ILMA) | Inflatable | No | Yes (primary purpose) | 1st/specialized |
| Combitube | Dual cuff (100mL + 15mL) | Via clear lumen | No | Rescue |
| King LT | Dual cuff (one inflation line) | Yes (LTS-D version) | No | Rescue |
Pdf on how to identify which LMA is this ?
ls /home/daytona/workspace/ 2>/dev/null || echo "workspace empty"
mkdir -p /home/daytona/workspace/lma-identification-guide
~/lma-identification-guide/build_pdf.py
#!/usr/bin/env python3
"""
LMA Identification Guide PDF Generator
Uses reportlab for full layout control
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm, cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, Image, PageBreak
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import Flowable
from io import BytesIO
import urllib.request
import os
# ── Colors ──────────────────────────────────────────────────────────────────
NAVY = colors.HexColor("#1a3a5c")
TEAL = colors.HexColor("#0d7377")
LIGHT_TEAL = colors.HexColor("#e6f4f4")
AMBER = colors.HexColor("#e07b00")
AMBER_LITE = colors.HexColor("#fff4e0")
RED_DARK = colors.HexColor("#b22222")
GREEN_DARK = colors.HexColor("#1a6b1a")
LIGHT_GREY = colors.HexColor("#f4f6f8")
MID_GREY = colors.HexColor("#d0d5de")
WHITE = colors.white
BLACK = colors.black
PAGE_W, PAGE_H = A4
LM = RM = 18*mm
TM = BM = 15*mm
OUTPUT = "/home/daytona/workspace/lma-identification-guide/LMA_Identification_Guide.pdf"
# ── Image download helper ────────────────────────────────────────────────────
def fetch_image_bytes(url, w_mm, h_mm=None):
try:
req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"})
with urllib.request.urlopen(req, timeout=10) as r:
data = r.read()
w = w_mm * mm
img = Image(BytesIO(data), width=w, height=h_mm*mm if h_mm else None)
img.hAlign = "CENTER"
return img
except Exception as e:
print(f" Image fetch failed: {url[:60]}... -> {e}")
return None
# ── Styles ───────────────────────────────────────────────────────────────────
base = getSampleStyleSheet()
def S(name, parent="Normal", **kw):
s = ParagraphStyle(name, parent=base[parent], **kw)
return s
sTitle = S("sTitle", "Title", fontSize=26, textColor=WHITE, alignment=TA_CENTER, leading=32, spaceAfter=4)
sSubtitle = S("sSubtitle", "Normal", fontSize=12, textColor=colors.HexColor("#cde8f0"), alignment=TA_CENTER, leading=16)
sH1 = S("sH1", "Normal", fontSize=15, textColor=WHITE, fontName="Helvetica-Bold", leading=20, spaceAfter=2, spaceBefore=2)
sH2 = S("sH2", "Normal", fontSize=12, textColor=NAVY, fontName="Helvetica-Bold", leading=16, spaceBefore=8, spaceAfter=4)
sH3 = S("sH3", "Normal", fontSize=10, textColor=TEAL, fontName="Helvetica-Bold", leading=14, spaceBefore=6, spaceAfter=2)
sBody = S("sBody", "Normal", fontSize=9, textColor=BLACK, leading=13, spaceAfter=3, alignment=TA_JUSTIFY)
sBullet = S("sBullet", "Normal", fontSize=9, textColor=BLACK, leading=13, spaceAfter=2, leftIndent=12, bulletIndent=0)
sCaption = S("sCaption", "Normal", fontSize=8, textColor=colors.grey, alignment=TA_CENTER, leading=10, spaceBefore=2, spaceAfter=6)
sTableH = S("sTableH", "Normal", fontSize=9, textColor=WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER, leading=12)
sTableB = S("sTableB", "Normal", fontSize=8, textColor=BLACK, alignment=TA_CENTER, leading=11)
sTableBL = S("sTableBL", "Normal", fontSize=8, textColor=BLACK, alignment=TA_LEFT, leading=11)
sKeyFeat = S("sKeyFeat", "Normal", fontSize=9, textColor=RED_DARK, fontName="Helvetica-Bold", leading=13)
sNote = S("sNote", "Normal", fontSize=8, textColor=colors.HexColor("#555555"), leading=11, leftIndent=8, spaceAfter=4)
sFooter = S("sFooter", "Normal", fontSize=7, textColor=colors.grey, alignment=TA_CENTER)
sDiag = S("sDiag", "Normal", fontSize=8.5,textColor=BLACK, leading=12, alignment=TA_JUSTIFY)
# ── Custom flowables ─────────────────────────────────────────────────────────
class ColorRect(Flowable):
def __init__(self, w, h, fill_color, radius=3):
super().__init__()
self.w, self.h, self.fill_color, self.radius = w, h, fill_color, radius
def draw(self):
self.canv.setFillColor(self.fill_color)
self.canv.roundRect(0, 0, self.w, self.h, self.radius, fill=1, stroke=0)
class TitleBanner(Flowable):
def __init__(self, w, h, text1, text2, text3):
super().__init__()
self.w, self.h = w, h
self.text1, self.text2, self.text3 = text1, text2, text3
def wrap(self, *args): return self.w, self.h
def draw(self):
c = self.canv
# Gradient-like background using two rects
c.setFillColor(NAVY)
c.roundRect(0, 0, self.w, self.h, 6, fill=1, stroke=0)
c.setFillColor(TEAL)
c.roundRect(0, 0, self.w*0.4, self.h, 6, fill=1, stroke=0)
c.setFillColor(NAVY)
c.rect(self.w*0.35, 0, self.w*0.1, self.h, fill=1, stroke=0)
# White accent line
c.setStrokeColor(colors.HexColor("#00cccc"))
c.setLineWidth(3)
c.line(0, self.h-4, self.w, self.h-4)
# Text
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 22)
c.drawCentredString(self.w/2, self.h - 40, self.text1)
c.setFont("Helvetica-Bold", 13)
c.drawCentredString(self.w/2, self.h - 62, self.text2)
c.setFont("Helvetica", 9)
c.setFillColor(colors.HexColor("#a0d8e8"))
c.drawCentredString(self.w/2, self.h - 78, self.text3)
class SectionHeader(Flowable):
def __init__(self, w, label, color=NAVY):
super().__init__()
self.w, self.label, self.color = w, label, color
self.h = 22
def wrap(self, *args): return self.w, self.h
def draw(self):
c = self.canv
c.setFillColor(self.color)
c.roundRect(0, 0, self.w, self.h, 4, fill=1, stroke=0)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 11)
c.drawString(8, 6, self.label)
class DeviceBox(Flowable):
"""Colored identification box for a device"""
def __init__(self, w, title, color, badge=None):
super().__init__()
self.w, self.title, self.color, self.badge = w, title, color, badge
self.h = 26
def wrap(self, *args): return self.w, self.h
def draw(self):
c = self.canv
c.setFillColor(self.color)
c.roundRect(0, 2, self.w, self.h-2, 4, fill=1, stroke=0)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 12)
c.drawString(10, 9, self.title)
if self.badge:
bw = len(self.badge)*6 + 10
c.setFillColor(WHITE)
c.roundRect(self.w - bw - 6, 5, bw, 16, 3, fill=1, stroke=0)
c.setFillColor(self.color)
c.setFont("Helvetica-Bold", 7)
c.drawCentredString(self.w - bw/2 - 6, 9, self.badge)
# ── Table helper ─────────────────────────────────────────────────────────────
def make_table(data, col_widths, head_color=NAVY, stripe=True, font_size=8):
rows = []
for i, row in enumerate(data):
rows.append([Paragraph(str(c), sTableH if i == 0 else sTableBL) for c in row])
style = [
("BACKGROUND", (0,0), (-1,0), head_color),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), font_size),
("ALIGN", (0,0), (-1,0), "CENTER"),
("ALIGN", (0,1), (-1,-1), "LEFT"),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_GREY] if stripe else [WHITE]),
("GRID", (0,0), (-1,-1), 0.4, MID_GREY),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("LEFTPADDING",(0,0), (-1,-1), 5),
("RIGHTPADDING",(0,0),(-1,-1), 5),
]
return Table(rows, colWidths=col_widths, style=TableStyle(style), repeatRows=1)
# ── Document build ────────────────────────────────────────────────────────────
def build():
doc = SimpleDocTemplate(
OUTPUT, pagesize=A4,
leftMargin=LM, rightMargin=RM,
topMargin=TM, bottomMargin=BM+8,
)
CW = PAGE_W - LM - RM # content width
def footer(canvas, doc):
canvas.saveState()
canvas.setFillColor(colors.HexColor("#888888"))
canvas.setFont("Helvetica", 7)
canvas.drawString(LM, BM-4, "LMA Identification Guide | Orris Medical Education")
canvas.drawRightString(PAGE_W - RM, BM-4, f"Page {doc.page}")
canvas.restoreState()
story = []
# ── COVER BANNER ─────────────────────────────────────────────────────────
story.append(TitleBanner(CW, 90,
"HOW TO IDENTIFY WHICH LMA IS THIS?",
"A Visual Identification Guide to Supraglottic Airway Devices",
"Based on Miller's Anesthesia 10e | Morgan & Mikhail 7e | Barash Clinical Anesthesia 9e"
))
story.append(Spacer(1, 6*mm))
# ── INTRO ─────────────────────────────────────────────────────────────────
story.append(SectionHeader(CW, "OVERVIEW"))
story.append(Spacer(1, 3*mm))
story.append(Paragraph(
"Supraglottic Airway Devices (SADs) sit <b>above the glottis</b> and provide a conduit "
"for ventilation without tracheal intubation. Identifying the correct type quickly is "
"essential in both elective and emergency airway management. This guide teaches you to "
"identify each LMA type by its <b>physical features, color coding, and structural landmarks</b>.",
sBody))
story.append(Spacer(1, 4*mm))
# ── QUICK ID FLOWCHART (text-based) ──────────────────────────────────────
story.append(SectionHeader(CW, "QUICK IDENTIFICATION ALGORITHM", color=TEAL))
story.append(Spacer(1, 3*mm))
algo_data = [
["STEP", "LOOK FOR", "ANSWER", "DEVICE"],
["1", "Is there an inflatable cuff?", "NO - soft gel/rubber body", "i-gel"],
["1", "Is there an inflatable cuff?", "YES - go to Step 2", "Continue"],
["2", "Is there a RIGID metal handle?", "YES", "LMA Fastrach (ILMA)"],
["2", "Is there a RIGID metal handle?", "NO - go to Step 3", "Continue"],
["3", "Is the airway tube FLEXIBLE / wire-reinforced?", "YES", "LMA Flexible"],
["3", "Is the airway tube FLEXIBLE / wire-reinforced?", "NO - go to Step 4", "Continue"],
["4", "Is there a SECOND lumen / gastric drain tube?", "YES - single-use, fixed curve", "LMA Supreme"],
["4", "Is there a SECOND lumen / gastric drain tube?", "YES - reusable, softer", "LMA ProSeal"],
["4", "Is there a SECOND lumen / gastric drain tube?", "NO - go to Step 5", "Continue"],
["5", "Is the cuff SILICONE / reusable (up to 40x)?", "YES", "LMA Classic"],
["5", "Is the cuff PVC / single-use only?", "YES", "LMA Unique"],
["6", "TWO tubes fused together + two large cuffs?", "YES", "Combitube"],
["6", "Single tube + two cuffs, ONE inflation line?", "YES", "King LT"],
]
algo_table = make_table(
algo_data,
[0.10*CW, 0.35*CW, 0.28*CW, 0.27*CW],
head_color=TEAL, font_size=8
)
story.append(algo_table)
story.append(Spacer(1, 6*mm))
# ── DEVICE COMPARISON IMAGE ───────────────────────────────────────────────
img1 = fetch_image_bytes(
"https://cdn.orris.care/cdss_images/c30ed44c9c336bb3dc13185f76a90080995c9b5f19b4da57334dcbed2ebe293d.png",
110
)
if img1:
story.append(img1)
story.append(Paragraph(
"Figure 1: Different LMA varieties side-by-side. A = Classic disposable LMA (single lumen, "
"inflatable cuff, simple connector); B = LMA ProSeal (second lumen for gastric drain, "
"posterior cuff, two inflation lines); C = Air-Q LMA (removable connector, wider bore "
"for fiberoptic intubation); D = ProSeal gastric drain lumen exit at cuff tip; E = removable connector.",
sCaption))
story.append(Spacer(1, 4*mm))
# ── PAGE 2 - DEVICE BY DEVICE ─────────────────────────────────────────────
story.append(PageBreak())
story.append(SectionHeader(CW, "DEVICE-BY-DEVICE IDENTIFICATION GUIDE"))
story.append(Spacer(1, 4*mm))
# Helper to make a 2-col device card
def device_card(name, gen, color, features, id_clues, contraindications, seal_pressure, reuse):
items = []
items.append(DeviceBox(CW, f"{name} [{gen}]", color, badge=gen))
items.append(Spacer(1, 3*mm))
half = (CW - 4*mm) / 2
# Left: features / ID clues
left_content = [
[Paragraph("<b>KEY IDENTIFYING FEATURES</b>", sH3)],
]
for f in features:
left_content.append([Paragraph(f"<bullet>•</bullet> {f}", sBullet)])
left_content.append([Spacer(1, 2*mm)])
left_content.append([Paragraph("<b>HOW TO SPOT IT AT A GLANCE</b>", sH3)])
for c in id_clues:
left_content.append([Paragraph(f"<bullet>✔</bullet> {c}", sBullet)])
right_content = [
[Paragraph("<b>QUICK STATS</b>", sH3)],
[Paragraph(f"<b>Seal pressure:</b> {seal_pressure}", sDiag)],
[Paragraph(f"<b>Reusable:</b> {reuse}", sDiag)],
[Spacer(1, 2*mm)],
[Paragraph("<b>CONTRAINDICATIONS</b>", sH3)],
]
for ci in contraindications:
right_content.append([Paragraph(f"<bullet>•</bullet> {ci}", sBullet)])
left_tbl = Table(left_content, colWidths=[half], style=TableStyle([
("VALIGN",(0,0),(-1,-1),"TOP"),
("TOPPADDING",(0,0),(-1,-1),2),
("BOTTOMPADDING",(0,0),(-1,-1),1),
]))
right_tbl = Table(right_content, colWidths=[half], style=TableStyle([
("VALIGN",(0,0),(-1,-1),"TOP"),
("TOPPADDING",(0,0),(-1,-1),2),
("BOTTOMPADDING",(0,0),(-1,-1),1),
("BACKGROUND",(0,0),(-1,-1), LIGHT_GREY),
]))
two_col = Table([[left_tbl, Spacer(4*mm, 1), right_tbl]], colWidths=[half, 4*mm, half])
two_col.setStyle(TableStyle([
("VALIGN",(0,0),(-1,-1),"TOP"),
("TOPPADDING",(0,0),(-1,-1),0),
]))
items.append(two_col)
items.append(Spacer(1, 6*mm))
return KeepTogether(items)
# 1. LMA Classic
story.append(device_card(
"LMA CLASSIC (cLMA)", "1st Gen", NAVY,
features=[
"Single wide-bore SILICONE tube (translucent/beige)",
"Oval-shaped elliptical inflatable cuff (silicone)",
"Single inflation line with blue pilot balloon",
"Standard 15-mm connector at proximal end",
"Longitudinal BLACK LINE on tube (should face upper lip)",
"Aperture bars (2-3 bars) inside the mask bowl",
"Reusable - can be sterilized up to 40 times",
"Sizes 1 to 6 printed on tube",
],
id_clues=[
"ONE tube only - no gastric channel",
"Soft silicone body - beige/tan color",
"BLUE pilot balloon with valve",
"No rigid handle or bite block",
"Straightforward curved tube shape",
],
contraindications=["Full stomach / aspiration risk", "Mouth opening <1.5 cm", "High airway pressure needed"],
seal_pressure="Up to 20 cm H2O",
reuse="Yes, up to 40x"
))
# 2. LMA Unique
story.append(device_card(
"LMA UNIQUE", "1st Gen (Disposable)", colors.HexColor("#2e6da4"),
features=[
"Single-use PVC version of the LMA Classic",
"Cuff is CLEAR/TRANSPARENT (vs beige of Classic)",
"Tube often has visible size markings",
"Same basic anatomy as Classic but LIGHTER weight",
"Non-removable 15-mm connector",
"Single inflation line, blue pilot balloon",
],
id_clues=[
"CLEAR/transparent cuff (not beige/silicone)",
"Feels lighter than Classic",
"Single use - packaged individually sterile",
"No second lumen",
],
contraindications=["Same as LMA Classic"],
seal_pressure="Up to 20 cm H2O",
reuse="No - single use only"
))
# 3. LMA ProSeal
story.append(device_card(
"LMA PROSEAL", "2nd Gen", colors.HexColor("#0a6640"),
features=[
"TWO lumens: airway tube + separate gastric drain tube",
"Gastric drain exits at the TIP of the cuff (proximal esophagus)",
"POSTERIOR CUFF behind the main cuff (dorsal component)",
"Integrated BITE BLOCK (at least 50% should remain visible in mouth)",
"Larger, wider cuff for better seal",
"Softer, more pliable cuff than Classic",
"Reusable silicone construction",
"Suprasternal notch test: press suprasternal notch - lubricant meniscus moves in drain",
],
id_clues=[
"TWO openings at the proximal end (airway + gastric)",
"DRAIN tube visible running alongside main tube",
"Visible bite block integrated into tube",
"Wider/larger cuff compared to Classic",
"Posterior inflation adds bulk to cuff",
],
contraindications=["Limited mouth opening", "Known esophageal pathology"],
seal_pressure="Up to 30-40 cm H2O",
reuse="Yes"
))
# 4. LMA Supreme
story.append(device_card(
"LMA SUPREME", "2nd Gen (Disposable)", colors.HexColor("#7b2d8b"),
features=[
"SINGLE-USE version of ProSeal concept",
"FIXED PRE-FORMED CURVE (rigid/semi-rigid tube, cannot be straightened)",
"Dual lumen: airway + gastric drain",
"Built-in BITE BLOCK",
"Cuff is WIDER and FIRMER than ProSeal",
"Integrated handle / reinforced curve makes insertion one-handed",
"Color-coded by size (e.g. size 4 = green)",
],
id_clues=[
"PRE-CURVED rigid tube - this is the key identifier!",
"Looks like it has a permanent bend built in",
"Dual port at proximal end",
"Single-use packaging",
"Handle/reinforced curve present",
],
contraindications=["Cannot be straightened for nasal use"],
seal_pressure=">35 cm H2O",
reuse="No - single use"
))
# 5. LMA Fastrach (ILMA)
story.append(device_card(
"LMA FASTRACH (ILMA - Intubating LMA)", "Specialized", AMBER,
features=[
"RIGID STAINLESS STEEL HANDLE - most distinctive feature",
"Short, curved METAL AIRWAY TUBE (not flexible plastic)",
"Wide internal diameter to accept standard ETT (6-8mm)",
"EPIGLOTTIC ELEVATING BAR inside the bowl",
"ETT has a special soft tip - wire-reinforced, straight",
"Designed for BLIND tracheal intubation through the device",
"Neutral head position used (not sniffing position)",
"Chandy maneuver: (1) rotate in sagittal plane; (2) lift from posterior pharynx",
],
id_clues=[
"METAL HANDLE - unmistakable identifier",
"Shorter, stouter tube than Classic",
"Epiglottic bar visible inside cuff aperture",
"Wider bore tube lumen",
"Comes with dedicated wire-reinforced ETT",
],
contraindications=["Small mouth opening <2.5 cm", "Posterior pharyngeal pathology"],
seal_pressure="Up to 20 cm H2O",
reuse="Yes (reusable) + disposable version available"
))
# 6. LMA Flexible
story.append(device_card(
"LMA FLEXIBLE", "1st Gen (Specialized)", colors.HexColor("#8b4513"),
features=[
"WIRE-REINFORCED kink-resistant FLEXIBLE shaft",
"Thin-walled, small-diameter tube (more flexible than Classic)",
"Tube can be positioned AWAY from midline/surgical field",
"Same cuff as LMA Classic",
"Designed for ENT, ophthalmology, oral/dental surgery",
"Available in reusable and single-use versions",
],
id_clues=[
"Can be BENT and FLEXED easily without kinking",
"Thin, spiral wire visible through tube wall",
"Longer tube than Classic (allows repositioning)",
"Same mask bowl as Classic",
],
contraindications=["High pressure ventilation needed"],
seal_pressure="Similar to Classic",
reuse="Both versions available"
))
# 7. i-gel
story.append(device_card(
"i-GEL", "2nd Gen (Cuffless)", colors.HexColor("#006994"),
features=[
"NO INFLATABLE CUFF - uses thermoplastic elastomer gel body",
"Gel body conforms to laryngeal anatomy when in situ",
"RIGID PLASTIC AIRWAY TUBE (transparent)",
"Integrated BITE BLOCK and buccal cavity stabilizer",
"GASTRIC DRAIN TUBE runs through the device",
"Color-coded by size (neonatal=pink, pediatric=purple, adult=green/orange/yellow)",
"No inflation syringe needed",
"SHORTER insertion time reported",
],
id_clues=[
"NO PILOT BALLOON anywhere on device - biggest clue!",
"Soft, gel-like elliptical body (not cuffed, not inflatable)",
"Distinctively wide, flat mask portion",
"Rigid transparent tube with color-coded connector",
"Size number stamped on tube",
],
contraindications=["Mouth opening <2 cm"],
seal_pressure="24-30 cm H2O",
reuse="No - single use"
))
# 8. Combitube
story.append(device_card(
"ESOPHAGEAL-TRACHEAL COMBITUBE", "Rescue Device", RED_DARK,
features=[
"TWO FUSED TUBES (not separate): longer BLUE tube + shorter CLEAR tube",
"100-mL large PROXIMAL pharyngeal cuff",
"15-mL smaller DISTAL esophageal cuff",
"TWO inflation lines (different volumes - label each)",
"Inserted until TWO BLACK RINGS lie between teeth",
"Blue tube: ventilate when in esophagus (side perforations direct air to larynx)",
"Clear tube: gastric decompression (or ventilate if tracheal placement)",
"Used in prehospital / rescue settings",
],
id_clues=[
"TWO tubes fused side-by-side (blue + clear)",
"TWO cuffs of VERY different sizes (100mL vs 15mL)",
"TWO black rings visible on shaft",
"No mask bowl at distal end",
],
contraindications=["Esophageal disease", "Known esophageal varices", "Caustic ingestion", "<4 ft tall patients"],
seal_pressure="N/A - esophageal occlusion",
reuse="No"
))
# 9. King LT
story.append(device_card(
"KING LARYNGEAL TUBE (King LT)", "Rescue Device", colors.HexColor("#556b2f"),
features=[
"SINGLE tube (not two fused tubes like Combitube)",
"TWO cuffs: small distal esophageal + large proximal pharyngeal",
"ONE SINGLE inflation line inflates BOTH cuffs simultaneously",
"Color-coded by size",
"Suction port distal to esophageal cuff (King LTS-D version)",
"If ventilation fails post-insertion: device is too deep - WITHDRAW slowly",
"Minimum mouth opening: 2.3 cm",
],
id_clues=[
"SINGLE tube but with TWO visible cuff bulges",
"ONE pilot balloon / inflation line only (both cuffs inflate together)",
"No mask bowl - smooth tube with two cuffs",
"Similar appearance to Combitube but ONE tube only",
],
contraindications=["Mouth opening <2.3 cm", "Known esophageal pathology"],
seal_pressure="Esophageal seal",
reuse="Reusable (LT) and single-use (LT-D) versions"
))
# ── PAGE 3 - MASTER COMPARISON TABLE ─────────────────────────────────────
story.append(PageBreak())
story.append(SectionHeader(CW, "MASTER COMPARISON TABLE - AT A GLANCE"))
story.append(Spacer(1, 4*mm))
master_data = [
["Device", "Cuff Type", "Gastric Drain", "No. of Tubes", "Special Feature", "Gen", "Reuse"],
["LMA Classic", "Inflatable silicone", "No", "1", "Beige/tan color, 40x reuse", "1st", "Yes x40"],
["LMA Unique", "Inflatable PVC", "No", "1", "Clear/transparent cuff, lighter", "1st", "No"],
["LMA ProSeal", "Inflatable + posterior","Yes", "2", "Bite block, suprasternal test", "2nd", "Yes"],
["LMA Supreme", "Inflatable, firm", "Yes", "2", "Pre-formed rigid curve", "2nd", "No"],
["LMA Fastrach", "Inflatable", "No", "1", "METAL HANDLE, epiglottic bar", "Spec", "Yes"],
["LMA Flexible", "Inflatable", "No", "1", "Wire-reinforced flexible tube", "1st", "Both"],
["i-gel", "GEL (no inflation)", "Yes", "1", "NO pilot balloon, color-coded", "2nd", "No"],
["Combitube", "Dual (100+15 mL)", "Via clear tube", "2 fused", "TWO black rings", "Rescue","No"],
["King LT", "Dual (1 inflation line)","Via LTS-D port","1", "Single line inflates both", "Rescue","Both"],
]
col_w = [0.16, 0.14, 0.10, 0.09, 0.22, 0.08, 0.08]
master_table = make_table(master_data, [r*CW for r in col_w], head_color=NAVY, font_size=7.5)
story.append(master_table)
story.append(Spacer(1, 6*mm))
# ── SIZE GUIDE ────────────────────────────────────────────────────────────
story.append(SectionHeader(CW, "LMA SIZE SELECTION GUIDE", color=TEAL))
story.append(Spacer(1, 4*mm))
size_data = [
["Size", "Patient", "Weight (kg)", "Max Cuff Volume", "ETT Size (through ILMA)"],
["1", "Neonate", "<6.5", "2-4 mL", "3.0-3.5 mm"],
["1.5", "Infant", "5-10", "Up to 7 mL", "3.5-4.0 mm"],
["2", "Child", "10-20", "Up to 10 mL","4.5 mm"],
["2.5", "Child", "20-30", "Up to 14 mL","5.0 mm"],
["3", "Small adult", "30-50", "Up to 20 mL","6.0 mm"],
["4", "Normal adult", "50-70", "Up to 30 mL","6.0 mm"],
["5", "Large adult", "70-100", "Up to 40 mL","7.0 mm"],
["6", "XL adult", ">100", "Up to 50 mL","7.0 mm"],
]
story.append(make_table(size_data, [0.08*CW, 0.16*CW, 0.15*CW, 0.17*CW, 0.44*CW], head_color=TEAL))
story.append(Spacer(1, 2*mm))
story.append(Paragraph("Tip: Average adult man -> Size 5 | Average adult woman -> Size 4", sNote))
story.append(Spacer(1, 6*mm))
# ── COLOUR CODING PANEL ───────────────────────────────────────────────────
story.append(SectionHeader(CW, "COLOUR-CODED IDENTIFICATION QUICK REFERENCE", color=colors.HexColor("#8b0000")))
story.append(Spacer(1, 3*mm))
colour_items = [
("<b>BEIGE/TAN SILICONE CUFF</b>", "LMA Classic (reusable)", LIGHT_TEAL),
("<b>CLEAR/TRANSPARENT CUFF</b>", "LMA Unique (disposable)", LIGHT_GREY),
("<b>METAL HANDLE (steel)</b>", "LMA Fastrach / ILMA", AMBER_LITE),
("<b>GEL BODY (no pilot balloon)</b>","i-gel", colors.HexColor("#e8f4e8")),
("<b>TWO FUSED TUBES (blue+clear)</b>","Combitube", colors.HexColor("#ffe8e8")),
("<b>SINGLE PILOT BALLOON + 2 CUFFS</b>","King LT", colors.HexColor("#e8ffe8")),
("<b>RIGID PRE-FORMED CURVE</b>", "LMA Supreme", colors.HexColor("#f0e8ff")),
("<b>FLEXIBLE SPIRAL WIRE IN TUBE</b>","LMA Flexible", colors.HexColor("#fff8e8")),
]
colour_rows = []
for i in range(0, len(colour_items), 2):
row = []
for j in range(2):
if i+j < len(colour_items):
feat, dev, bg = colour_items[i+j]
cell = Table([
[Paragraph(feat, S(f"c{i}{j}", "Normal", fontSize=8.5, fontName="Helvetica-Bold", textColor=NAVY, leading=12))],
[Paragraph(f"= {dev}", S(f"cc{i}{j}", "Normal", fontSize=8, textColor=TEAL, leading=11))]
], style=TableStyle([
("BACKGROUND",(0,0),(-1,-1), bg),
("TOPPADDING",(0,0),(-1,-1),4),
("BOTTOMPADDING",(0,0),(-1,-1),4),
("LEFTPADDING",(0,0),(-1,-1),6),
("BOX",(0,0),(-1,-1),0.5,MID_GREY),
("ROUNDCORNERS",[3]),
]))
row.append(cell)
else:
row.append(Spacer(1,1))
colour_rows.append(row)
colour_table = Table(colour_rows, colWidths=[CW/2-2*mm, CW/2-2*mm],
style=TableStyle([("LEFTPADDING",(0,0),(-1,-1),2),("RIGHTPADDING",(0,0),(-1,-1),2),
("TOPPADDING",(0,0),(-1,-1),2),("BOTTOMPADDING",(0,0),(-1,-1),2)]))
story.append(colour_table)
story.append(Spacer(1, 6*mm))
# ── PAGE 4 - INSERTION & CONFIRMATION ────────────────────────────────────
story.append(PageBreak())
story.append(SectionHeader(CW, "INSERTION TECHNIQUE & CONFIRMATION OF PLACEMENT"))
story.append(Spacer(1, 3*mm))
# Insertion image
img2 = fetch_image_bytes(
"https://cdn.orris.care/cdss_images/688f9f151e1b4d32dbba5e89eecbef5cf14761cd941d3b1e96d28e711a49c183.png",
120
)
if img2:
story.append(img2)
story.append(Paragraph(
"Figure 2: LMA Classic insertion technique. A: Deflated cuff ready (rim wrinkle-free, "
"facing away from aperture). B: Tip pressed against hard palate, jaw depressed. "
"C: Advanced into hypopharynx in one fluid movement with neck flexed, head extended. "
"D: Final press downward until resistance felt. (Source: Morgan & Mikhail's Clinical Anesthesiology, 7e)",
sCaption))
story.append(Spacer(1, 4*mm))
insert_data = [
["STEP", "ACTION", "KEY POINT"],
["1", "Select size", "Man=5, Woman=4; undersize causes overinflation injury"],
["2", "Deflate cuff", "Rim must be wrinkle-free, facing AWAY from aperture"],
["3", "Lubricate", "ONLY the BACK side of cuff with water-based lubricant"],
["4", "Anesthesia depth", "Slightly deeper than oral airway; propofol preferred"],
["5", "Sniffing position", "Neck flexed, head extended (EXCEPT ILMA: neutral position)"],
["6", "Insert", "Index finger guides along hard palate into hypopharynx"],
["7", "Advance", "Until resistance felt; BLACK line faces upper lip"],
["8", "Inflate cuff", "Minimum effective volume; target 40-60 cm H2O cuff pressure"],
["9", "Confirm", "ETCO2 + auscultation + visible chest rise + leak test at 18-20 cmH2O"],
["10","Secure", "Tape; insert bite block if no built-in one (e.g. Classic)"],
["11","Remove", "Only when AWAKE and opens mouth on command - avoid excitation phase"],
]
story.append(make_table(insert_data, [0.06*CW, 0.22*CW, 0.72*CW], head_color=NAVY))
story.append(Spacer(1, 4*mm))
# ── TROUBLESHOOTING ───────────────────────────────────────────────────────
story.append(SectionHeader(CW, "TROUBLESHOOTING - WHEN VENTILATION IS DIFFICULT AFTER INSERTION", color=RED_DARK))
story.append(Spacer(1, 3*mm))
trouble_data = [
["PROBLEM", "LIKELY CAUSE", "SOLUTION"],
["High resistance / no chest rise", "Down-folded epiglottis", "Up-Down maneuver: withdraw 2-4 cm, reinsert without deflating"],
["Resistance after insertion", "Insufficient anesthesia", "Deepen anesthesia; IV propofol or topical lidocaine"],
["King LT: hard to ventilate", "Tube inserted too deeply", "SLOWLY WITHDRAW until compliance improves"],
["Leak despite full inflation", "Wrong size (too small)", "Try one size larger"],
["Persistent obstruction", "Down-folded epiglottis", "Head extension + reposition; try larger size"],
["Gastric contents in barrel", "Regurgitation", "Leave in situ, suction, Trendelenburg, 100% O2"],
["Cannot ventilate at all", "Laryngospasm", "Deepen anesthesia; IV suxamethonium if severe"],
]
story.append(make_table(trouble_data, [0.25*CW, 0.30*CW, 0.45*CW], head_color=RED_DARK))
story.append(Spacer(1, 6*mm))
# ── COMPLICATIONS TABLE ───────────────────────────────────────────────────
story.append(SectionHeader(CW, "COMPLICATIONS & PREVENTION", color=colors.HexColor("#7b4f00")))
story.append(Spacer(1, 3*mm))
comp_data = [
["Complication", "Incidence", "Prevention"],
["Aspiration of gastric contents", "~2/10,000 (low risk only)", "Avoid in full stomach; use 2nd gen device if needed"],
["Postoperative sore throat", "4-50% (less than ETT)", "Correct size; minimum inflation; water-based lube"],
["Nerve injury (lingual, hypoglossal, RLN)", "Rare", "Avoid overinflation; no N2O without cuff monitoring"],
["Laryngospasm", "On premature removal", "Remove only when awake / on command"],
["Gastric distension", "If esophagus in cuff rim", "Confirm correct positioning; use ProSeal/i-gel"],
["Cuff pressure rise with N2O", "If N2O used", "Monitor cuff pressure throughout; deflate if >60 cmH2O"],
]
story.append(make_table(comp_data, [0.25*CW, 0.20*CW, 0.55*CW], head_color=colors.HexColor("#7b4f00")))
story.append(Spacer(1, 4*mm))
story.append(Paragraph(
"<b>Sources:</b> Miller's Anesthesia 10e (p.5886-5951) | Morgan & Mikhail's Clinical Anesthesiology 7e (p.581-587) | "
"Barash Clinical Anesthesia 9e (p.2320-2327) | Roberts & Hedges' Clinical Procedures in Emergency Medicine",
sNote))
# ── BUILD ─────────────────────────────────────────────────────────────────
doc.build(story, onFirstPage=footer, onLaterPages=footer)
print(f"PDF saved: {OUTPUT}")
if __name__ == "__main__":
build()
cd /home/daytona/workspace/lma-identification-guide && python3 build_pdf.py 2>&1
~/lma-identification-guide/build_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/lma-identification-guide/build_pdf.py'
cd /home/daytona/workspace/lma-identification-guide && python3 build_pdf.py 2>&1
~/lma-identification-guide/build_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/lma-identification-guide/build_pdf.py'
cd /home/daytona/workspace/lma-identification-guide && python3 build_pdf.py 2>&1
~/lma-identification-guide/build_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/lma-identification-guide/build_pdf.py'
cd /home/daytona/workspace/lma-identification-guide && python3 build_pdf.py 2>&1
ls -lh /home/daytona/workspace/lma-identification-guide/LMA_Identification_Guide…
LMA Identification Guide
PDF Document · PDF
Couldn’t download this file
ls -lh /home/daytona/workspace/lma-identification-guide/ && echo "---" && python…
cp /home/daytona/workspace/lma-identification-guide/LMA_Identification_Guide.pdf…
LMA Guide
PDF Document · PDF