Make pdf with hand written ,linear flow charts , branching flow chart , diagrams , highlights imp things , tables , thoeory of chapter 9 from this pdf
cd /home/daytona/workspace/attachments/f5a54161-12a2-41d2-ae37-2a15c857af40/ && …
cd /home/daytona/workspace/attachments/f5a54161-12a2-41d2-ae37-2a15c857af40/ && …
ls /home/daytona/workspace/ && mkdir -p /home/daytona/workspace/chapter9-narcoti…
~/chapter9-narcotic/generate_chapter9.py
#!/usr/bin/env python3
"""
Chapter 9: Narcotic & Substance Abuse
Forensic Medicine & Toxicology
Comprehensive Study PDF with handwritten-style fonts, flowcharts, diagrams,
highlights, tables, and full theory.
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, PageBreak
)
from reportlab.platypus.flowables import Flowable
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.graphics.shapes import (
Drawing, Rect, String, Line, Polygon, Circle, RoundedRect,
Arrow, Group
)
from reportlab.graphics import renderPDF
from reportlab.graphics.shapes import Drawing
import math
# ─── Colour Palette ────────────────────────────────────────────────────────────
C_BG = colors.HexColor("#FFFDF4") # warm cream page bg
C_TITLE = colors.HexColor("#1A1A2E")
C_HEADING = colors.HexColor("#16213E")
C_ACCENT = colors.HexColor("#0F3460")
C_HL_YELLOW = colors.HexColor("#FFE66D") # highlight yellow
C_HL_GREEN = colors.HexColor("#A8EDBC") # highlight green
C_HL_PINK = colors.HexColor("#FFB3C6") # highlight pink
C_HL_BLUE = colors.HexColor("#B3D9FF") # highlight blue
C_HL_ORANGE = colors.HexColor("#FFD4A3") # highlight orange
C_BOX_BORDER = colors.HexColor("#0F3460")
C_FLOW_BOX = colors.HexColor("#E8F4FD")
C_FLOW_ARROW = colors.HexColor("#0F3460")
C_TABLE_HDR = colors.HexColor("#1A1A2E")
C_TABLE_ROW1 = colors.HexColor("#EAF4FB")
C_TABLE_ROW2 = colors.HexColor("#FFFFFF")
C_WARN = colors.HexColor("#FF6B6B")
C_GREEN_BOX = colors.HexColor("#D4EDDA")
C_BLUE_BOX = colors.HexColor("#D0E8FF")
C_PURPLE_BOX = colors.HexColor("#E8D5FF")
C_ORANGE_BOX = colors.HexColor("#FFF3CD")
C_RED_BOX = colors.HexColor("#FFE0E0")
PAGE_W, PAGE_H = A4
# ─── Custom Flowables ──────────────────────────────────────────────────────────
class HandwrittenTitle(Flowable):
"""Big chapter title with underline flourish."""
def __init__(self, text, subtitle="", width=None):
Flowable.__init__(self)
self.text = text
self.subtitle = subtitle
self.w = width or (PAGE_W - 4*cm)
self.h = 5.5*cm
def wrap(self, aw, ah):
return self.w, self.h
def draw(self):
c = self.canv
w, h = self.w, self.h
# Background gradient-ish band
c.setFillColor(C_ACCENT)
c.roundRect(0, h-4*cm, w, 4*cm, 12, fill=1, stroke=0)
# Decorative corner circles
c.setFillColor(colors.HexColor("#E94560"))
c.circle(0.3*cm, h-0.3*cm, 0.25*cm, fill=1, stroke=0)
c.circle(w-0.3*cm, h-0.3*cm, 0.25*cm, fill=1, stroke=0)
c.circle(0.3*cm, h-3.7*cm, 0.25*cm, fill=1, stroke=0)
c.circle(w-0.3*cm, h-3.7*cm, 0.25*cm, fill=1, stroke=0)
# Chapter label
c.setFont("Helvetica-Bold", 11)
c.setFillColor(C_HL_YELLOW)
c.drawCentredString(w/2, h-1.1*cm, "FORENSIC MEDICINE & TOXICOLOGY")
# Main title
c.setFont("Helvetica-Bold", 22)
c.setFillColor(colors.white)
c.drawCentredString(w/2, h-2.0*cm, self.text)
# Subtitle
if self.subtitle:
c.setFont("Helvetica", 12)
c.setFillColor(C_HL_YELLOW)
c.drawCentredString(w/2, h-3.0*cm, self.subtitle)
# Wavy underline effect (series of arcs)
c.setStrokeColor(C_HL_YELLOW)
c.setLineWidth(2)
y_wave = h - 4.3*cm
x = 1*cm
seg = 0.7*cm
while x < w - 1*cm:
c.arc(x, y_wave-0.15*cm, x+seg, y_wave+0.15*cm, 0, 180)
x += seg
# Bottom label band
c.setFillColor(colors.HexColor("#E94560"))
c.rect(0, 0, w, 1.0*cm, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 10)
c.setFillColor(colors.white)
c.drawCentredString(w/2, 0.3*cm,
"Q116 · Q123 · Q124 · Q133 | 4 High-Yield Questions")
class SectionHeader(Flowable):
"""Coloured section header with a tab marker."""
def __init__(self, number, title, color=None, width=None):
Flowable.__init__(self)
self.number = number
self.title = title
self.color = color or C_ACCENT
self.w = width or (PAGE_W - 4*cm)
self.h = 1.1*cm
def wrap(self, aw, ah):
return self.w, self.h
def draw(self):
c = self.canv
w, h = self.w, self.h
# Coloured tab left
c.setFillColor(self.color)
c.rect(0, 0, 0.5*cm, h, fill=1, stroke=0)
# Light background
c.setFillColor(colors.HexColor("#F0F4FF"))
c.rect(0.5*cm, 0, w-0.5*cm, h, fill=1, stroke=0)
# Border bottom
c.setStrokeColor(self.color)
c.setLineWidth(1.5)
c.line(0.5*cm, 0, w, 0)
# Number badge
c.setFillColor(self.color)
c.roundRect(0.7*cm, 0.1*cm, 0.8*cm, 0.8*cm, 4, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 10)
c.setFillColor(colors.white)
c.drawCentredString(1.1*cm, 0.28*cm, self.number)
# Title
c.setFont("Helvetica-Bold", 13)
c.setFillColor(C_HEADING)
c.drawString(1.7*cm, 0.3*cm, self.title)
class HighlightBox(Flowable):
"""Coloured callout / highlight box with icon."""
def __init__(self, text, bg_color=None, border_color=None,
icon="★", width=None, font_size=11):
Flowable.__init__(self)
self.text = text
self.bg = bg_color or C_HL_YELLOW
self.border = border_color or C_ACCENT
self.icon = icon
self.w = width or (PAGE_W - 4*cm)
self.font_size = font_size
# estimate height
chars_per_line = int(self.w / (font_size * 0.55))
lines = max(1, math.ceil(len(text) / chars_per_line))
self.h = (lines * (font_size + 4) + 20) / 72 * 2.54 * cm
def wrap(self, aw, ah):
return self.w, self.h
def draw(self):
c = self.canv
w, h = self.w, self.h
c.setFillColor(self.bg)
c.roundRect(0, 0, w, h, 8, fill=1, stroke=0)
c.setStrokeColor(self.border)
c.setLineWidth(1.5)
c.roundRect(0, 0, w, h, 8, fill=0, stroke=1)
# left accent bar
c.setFillColor(self.border)
c.rect(0, 0, 0.3*cm, h, fill=1, stroke=0)
# icon
c.setFont("Helvetica-Bold", 14)
c.setFillColor(self.border)
c.drawString(0.5*cm, h-0.6*cm, self.icon)
# text
c.setFont("Helvetica", self.font_size)
c.setFillColor(C_HEADING)
text_x = 1.1*cm
text_y = h - 0.5*cm
for line in self._wrap_text(self.text, w - 1.3*cm, self.font_size):
c.drawString(text_x, text_y, line)
text_y -= (self.font_size + 4) / 72 * inch_to_pt()
def _wrap_text(self, text, max_w, fs):
words = text.split()
lines, current = [], ""
for word in words:
test = (current + " " + word).strip()
if len(test) * fs * 0.55 < max_w * 28.35:
current = test
else:
if current:
lines.append(current)
current = word
if current:
lines.append(current)
return lines
def inch_to_pt():
return 28.35 # pts per cm (approx)
class LinearFlowchart(Flowable):
"""A top-to-bottom linear flowchart."""
def __init__(self, title, steps, colors_list=None, width=None):
Flowable.__init__(self)
self.title = title
self.steps = steps # list of (label, text)
self.w = width or (PAGE_W - 4*cm)
box_h = 1.0*cm
self.h = 1.2*cm + len(steps) * (box_h + 0.6*cm) + 0.4*cm
self.colors_list = colors_list or [C_FLOW_BOX] * len(steps)
def wrap(self, aw, ah):
return self.w, self.h
def draw(self):
c = self.canv
w, h = self.w, self.h
box_h = 1.0*cm
box_w = w * 0.72
x_start = (w - box_w) / 2
y = h - 1.0*cm
# Title
c.setFont("Helvetica-Bold", 12)
c.setFillColor(C_HEADING)
c.drawCentredString(w/2, y, self.title)
y -= 0.5*cm
for i, (label, text) in enumerate(self.steps):
col = self.colors_list[i % len(self.colors_list)]
# Box
c.setFillColor(col)
c.roundRect(x_start, y - box_h, box_w, box_h, 6, fill=1, stroke=0)
c.setStrokeColor(C_BOX_BORDER)
c.setLineWidth(1)
c.roundRect(x_start, y - box_h, box_w, box_h, 6, fill=0, stroke=1)
# Step badge
c.setFillColor(C_BOX_BORDER)
c.circle(x_start + 0.4*cm, y - box_h/2, 0.28*cm, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 8)
c.setFillColor(colors.white)
c.drawCentredString(x_start + 0.4*cm, y - box_h/2 - 0.1*cm, str(i+1))
# Label (bold) + text
c.setFont("Helvetica-Bold", 9)
c.setFillColor(C_ACCENT)
c.drawString(x_start + 0.85*cm, y - 0.35*cm, label + ":")
label_w = len(label) * 6.5 + 8 + x_start + 0.85*cm
c.setFont("Helvetica", 9)
c.setFillColor(C_HEADING)
c.drawString(label_w, y - 0.35*cm, text)
y -= box_h
# Arrow (except after last)
if i < len(self.steps) - 1:
mid_x = w / 2
c.setStrokeColor(C_FLOW_ARROW)
c.setLineWidth(1.5)
c.line(mid_x, y, mid_x, y - 0.45*cm)
# Arrowhead
c.setFillColor(C_FLOW_ARROW)
c.polygon([mid_x-0.15*cm, y-0.38*cm,
mid_x+0.15*cm, y-0.38*cm,
mid_x, y-0.55*cm], fill=1, stroke=0)
y -= 0.6*cm
class BranchingFlowchart(Flowable):
"""A diamond decision flowchart with YES/NO branches."""
def __init__(self, question, yes_path, no_path,
yes_outcome, no_outcome, title="", width=None):
Flowable.__init__(self)
self.question = question
self.yes_path = yes_path # list of strings
self.no_path = no_path
self.yes_outcome = yes_outcome
self.no_outcome = no_outcome
self.title = title
self.w = width or (PAGE_W - 4*cm)
self.h = 12*cm
def wrap(self, aw, ah):
return self.w, self.h
def draw(self):
c = self.canv
w, h = self.w, self.h
mid = w / 2
if self.title:
c.setFont("Helvetica-Bold", 11)
c.setFillColor(C_HEADING)
c.drawCentredString(mid, h-0.5*cm, self.title)
# Diamond (decision)
dia_top = h - 1.5*cm
dia_mid = h - 3.0*cm
dia_bot = h - 4.5*cm
dia_w = 4.5*cm
c.setFillColor(colors.HexColor("#FFF9C4"))
c.setStrokeColor(colors.HexColor("#F9A825"))
c.setLineWidth(1.5)
c.polygon([mid, dia_top, mid+dia_w/2, dia_mid,
mid, dia_bot, mid-dia_w/2, dia_mid], fill=1, stroke=1)
c.setFont("Helvetica-Bold", 8)
c.setFillColor(C_HEADING)
# wrap question
words = self.question.split()
q_lines = []
cur = ""
for w_ in words:
test = (cur + " " + w_).strip()
if len(test) < 22:
cur = test
else:
q_lines.append(cur)
cur = w_
q_lines.append(cur)
line_h = 0.32*cm
q_y = dia_mid + len(q_lines)*line_h/2
for ql in q_lines:
c.drawCentredString(mid, q_y, ql)
q_y -= line_h
# Arrow left (NO)
y_arrow = dia_mid
c.setStrokeColor(C_FLOW_ARROW)
c.setLineWidth(1.5)
c.line(mid - dia_w/2, y_arrow, 1.2*cm, y_arrow)
c.setFont("Helvetica-Bold", 9)
c.setFillColor(C_WARN)
c.drawString(mid - dia_w/2 - 0.5*cm, y_arrow + 0.1*cm, "NO")
c.line(1.2*cm, y_arrow, 1.2*cm, dia_bot - 1.5*cm)
# arrowhead down
ax = 1.2*cm
ay = dia_bot - 1.5*cm
c.setFillColor(C_FLOW_ARROW)
c.polygon([ax-0.15*cm, ay+0.2*cm, ax+0.15*cm, ay+0.2*cm, ax, ay],
fill=1, stroke=0)
# NO branch boxes
box_w = 3.5*cm
no_box_x = 0.3*cm
no_box_y = dia_bot - 1.7*cm
for step in self.no_path:
c.setFillColor(C_RED_BOX)
c.roundRect(no_box_x, no_box_y - 0.7*cm, box_w, 0.7*cm,
4, fill=1, stroke=0)
c.setStrokeColor(C_WARN)
c.setLineWidth(0.8)
c.roundRect(no_box_x, no_box_y - 0.7*cm, box_w, 0.7*cm,
4, fill=0, stroke=1)
c.setFont("Helvetica", 8)
c.setFillColor(C_HEADING)
c.drawString(no_box_x + 0.15*cm, no_box_y - 0.45*cm, step[:45])
# arrow down
if self.no_path.index(step) < len(self.no_path)-1:
c.setStrokeColor(C_FLOW_ARROW)
c.line(no_box_x+box_w/2, no_box_y-0.7*cm,
no_box_x+box_w/2, no_box_y-1.0*cm)
c.setFillColor(C_FLOW_ARROW)
bx = no_box_x+box_w/2
by = no_box_y-1.0*cm
c.polygon([bx-0.1*cm, by+0.15*cm,
bx+0.1*cm, by+0.15*cm, bx, by], fill=1, stroke=0)
no_box_y -= 1.0*cm
# NO outcome box
c.setFillColor(C_HL_PINK)
c.roundRect(no_box_x, no_box_y-0.8*cm, box_w, 0.8*cm,
5, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 8)
c.setFillColor(C_HEADING)
c.drawString(no_box_x+0.1*cm, no_box_y-0.5*cm, self.no_outcome[:40])
# Arrow right (YES)
c.setStrokeColor(C_FLOW_ARROW)
c.setLineWidth(1.5)
c.line(mid + dia_w/2, y_arrow, w-1.2*cm, y_arrow)
c.setFont("Helvetica-Bold", 9)
c.setFillColor(colors.HexColor("#2E7D32"))
c.drawString(mid + dia_w/2 + 0.1*cm, y_arrow + 0.1*cm, "YES")
c.line(w-1.2*cm, y_arrow, w-1.2*cm, dia_bot-1.5*cm)
ax2 = w-1.2*cm
ay2 = dia_bot-1.5*cm
c.setFillColor(C_FLOW_ARROW)
c.polygon([ax2-0.15*cm, ay2+0.2*cm,
ax2+0.15*cm, ay2+0.2*cm, ax2, ay2], fill=1, stroke=0)
# YES branch boxes
yes_box_x = w - 3.8*cm
yes_box_y = dia_bot - 1.7*cm
for step in self.yes_path:
c.setFillColor(C_GREEN_BOX)
c.roundRect(yes_box_x, yes_box_y-0.7*cm, box_w, 0.7*cm,
4, fill=1, stroke=0)
c.setStrokeColor(colors.HexColor("#2E7D32"))
c.setLineWidth(0.8)
c.roundRect(yes_box_x, yes_box_y-0.7*cm, box_w, 0.7*cm,
4, fill=0, stroke=1)
c.setFont("Helvetica", 8)
c.setFillColor(C_HEADING)
c.drawString(yes_box_x+0.15*cm, yes_box_y-0.45*cm, step[:45])
if self.yes_path.index(step) < len(self.yes_path)-1:
c.setStrokeColor(C_FLOW_ARROW)
bx2 = yes_box_x+box_w/2
c.line(bx2, yes_box_y-0.7*cm, bx2, yes_box_y-1.0*cm)
by2 = yes_box_y-1.0*cm
c.setFillColor(C_FLOW_ARROW)
c.polygon([bx2-0.1*cm, by2+0.15*cm,
bx2+0.1*cm, by2+0.15*cm, bx2, by2], fill=1, stroke=0)
yes_box_y -= 1.0*cm
# YES outcome box
c.setFillColor(C_HL_GREEN)
c.roundRect(yes_box_x, yes_box_y-0.8*cm, box_w, 0.8*cm,
5, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 8)
c.setFillColor(C_HEADING)
c.drawString(yes_box_x+0.1*cm, yes_box_y-0.5*cm, self.yes_outcome[:40])
class MindMapDiagram(Flowable):
"""Simple radial mind-map style diagram."""
def __init__(self, center, branches, width=None):
Flowable.__init__(self)
self.center = center
self.branches = branches # list of (label, sub_items list)
self.w = width or (PAGE_W - 4*cm)
self.h = 9*cm
def wrap(self, aw, ah):
return self.w, self.h
def draw(self):
c = self.canv
w, h = self.w, self.h
cx, cy = w/2, h/2 - 0.5*cm
# Center ellipse
c.setFillColor(C_ACCENT)
c.ellipse(cx-2.2*cm, cy-0.55*cm, cx+2.2*cm, cy+0.55*cm, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 10)
c.setFillColor(colors.white)
c.drawCentredString(cx, cy-0.15*cm, self.center)
branch_colors = [
colors.HexColor("#E94560"),
colors.HexColor("#0F3460"),
colors.HexColor("#533483"),
colors.HexColor("#05C46B"),
colors.HexColor("#F19C65"),
colors.HexColor("#3AAFA9"),
]
n = len(self.branches)
for i, (label, subs) in enumerate(self.branches):
angle = math.pi/2 + (2*math.pi/n)*i
r = 3.2*cm
bx = cx + r * math.cos(angle)
by = cy + r * math.sin(angle)
bc = branch_colors[i % len(branch_colors)]
# Line from center to branch
c.setStrokeColor(bc)
c.setLineWidth(2)
c.line(cx + 2.2*cm*math.cos(angle), cy + 0.55*cm*math.sin(angle),
bx, by)
# Branch box
bw, bh = 3.0*cm, 0.65*cm
c.setFillColor(bc)
c.roundRect(bx-bw/2, by-bh/2, bw, bh, 5, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 8)
c.setFillColor(colors.white)
c.drawCentredString(bx, by-0.15*cm, label[:20])
# Sub items
sub_r = r + 2.0*cm
sub_count = len(subs)
spread = 0.35
for j, sub in enumerate(subs):
if sub_count == 1:
sa = angle
else:
sa = angle - spread/2 + spread*(j/(sub_count-1)) if sub_count > 1 else angle
sx = cx + sub_r*math.cos(sa)
sy = cy + sub_r*math.sin(sa)
c.setStrokeColor(bc)
c.setLineWidth(0.8)
c.setDash([2,2])
c.line(bx, by, sx, sy)
c.setDash()
sw = 2.4*cm
c.setFillColor(colors.HexColor("#F8F9FA"))
c.roundRect(sx-sw/2, sy-0.28*cm, sw, 0.55*cm,
3, fill=1, stroke=0)
c.setStrokeColor(bc)
c.setLineWidth(0.5)
c.roundRect(sx-sw/2, sy-0.28*cm, sw, 0.55*cm,
3, fill=0, stroke=1)
c.setFont("Helvetica", 7)
c.setFillColor(C_HEADING)
c.drawCentredString(sx, sy-0.1*cm, sub[:22])
class ComparisonDiagram(Flowable):
"""Two-column comparison (Venn-style side by side)."""
def __init__(self, title, left_title, right_title,
left_items, right_items, common_items=None,
width=None):
Flowable.__init__(self)
self.title = title
self.lt = left_title
self.rt = right_title
self.left = left_items
self.right = right_items
self.common = common_items or []
self.w = width or (PAGE_W - 4*cm)
rows = max(len(left_items), len(right_items), len(common_items or []))
self.h = 1.8*cm + rows * 0.65*cm + (1.2*cm if self.common else 0)
def wrap(self, aw, ah):
return self.w, self.h
def draw(self):
c = self.canv
w, h = self.w, self.h
# Title
c.setFillColor(C_ACCENT)
c.rect(0, h-0.8*cm, w, 0.8*cm, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 11)
c.setFillColor(colors.white)
c.drawCentredString(w/2, h-0.55*cm, self.title)
col_w = w/2 - 0.1*cm
# Left col
c.setFillColor(C_RED_BOX)
c.rect(0, 0, col_w, h-0.8*cm, fill=1, stroke=0)
c.setStrokeColor(C_WARN)
c.setLineWidth(1)
c.rect(0, 0, col_w, h-0.8*cm, fill=0, stroke=1)
c.setFont("Helvetica-Bold", 10)
c.setFillColor(C_WARN)
c.drawCentredString(col_w/2, h-1.3*cm, self.lt)
c.setFont("Helvetica", 9)
c.setFillColor(C_HEADING)
y = h - 1.7*cm
for item in self.left:
c.drawString(0.2*cm, y, u"\u25cf " + item)
y -= 0.65*cm
# Right col
rx = w/2 + 0.1*cm
c.setFillColor(C_GREEN_BOX)
c.rect(rx, 0, col_w, h-0.8*cm, fill=1, stroke=0)
c.setStrokeColor(colors.HexColor("#2E7D32"))
c.rect(rx, 0, col_w, h-0.8*cm, fill=0, stroke=1)
c.setFont("Helvetica-Bold", 10)
c.setFillColor(colors.HexColor("#2E7D32"))
c.drawCentredString(rx+col_w/2, h-1.3*cm, self.rt)
c.setFont("Helvetica", 9)
c.setFillColor(C_HEADING)
y = h - 1.7*cm
for item in self.right:
c.drawString(rx+0.2*cm, y, u"\u25cf " + item)
y -= 0.65*cm
class InfographicBanner(Flowable):
"""A horizontal row of stat boxes."""
def __init__(self, stats, width=None):
Flowable.__init__(self)
self.stats = stats # list of (number/icon, label, color)
self.w = width or (PAGE_W - 4*cm)
self.h = 2.5*cm
def wrap(self, aw, ah):
return self.w, self.h
def draw(self):
c = self.canv
n = len(self.stats)
box_w = (self.w - (n-1)*0.2*cm) / n
x = 0
for val, label, col in self.stats:
c.setFillColor(col)
c.roundRect(x, 0, box_w, self.h, 8, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 18)
c.setFillColor(colors.white)
c.drawCentredString(x+box_w/2, self.h-1.1*cm, str(val))
c.setFont("Helvetica", 8)
c.drawCentredString(x+box_w/2, 0.3*cm, label)
x += box_w + 0.2*cm
class HorizontalTimeline(Flowable):
"""Horizontal timeline flowchart."""
def __init__(self, title, steps, width=None):
Flowable.__init__(self)
self.title = title
self.steps = steps # list of (label, text)
self.w = width or (PAGE_W - 4*cm)
self.h = 4.0*cm
def wrap(self, aw, ah):
return self.w, self.h
def draw(self):
c = self.canv
w, h = self.w, self.h
n = len(self.steps)
mid_y = h/2 - 0.3*cm
step_w = w / n
c.setFont("Helvetica-Bold", 11)
c.setFillColor(C_HEADING)
c.drawCentredString(w/2, h-0.5*cm, self.title)
# Main line
c.setStrokeColor(C_ACCENT)
c.setLineWidth(2.5)
c.line(step_w/2, mid_y, w-step_w/2, mid_y)
timeline_colors = [
colors.HexColor("#E94560"), colors.HexColor("#0F3460"),
colors.HexColor("#533483"), colors.HexColor("#05C46B"),
colors.HexColor("#F19C65"), colors.HexColor("#3AAFA9"),
]
for i, (label, text) in enumerate(self.steps):
cx = step_w/2 + i*step_w
col = timeline_colors[i % len(timeline_colors)]
# Circle node
c.setFillColor(col)
c.circle(cx, mid_y, 0.32*cm, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 8)
c.setFillColor(colors.white)
c.drawCentredString(cx, mid_y-0.12*cm, str(i+1))
# Alternating above/below
if i % 2 == 0:
# above
c.setStrokeColor(col)
c.setLineWidth(1)
c.line(cx, mid_y+0.32*cm, cx, mid_y+0.7*cm)
c.setFillColor(col)
box_h = 0.75*cm
bw = step_w*0.9
c.roundRect(cx-bw/2, mid_y+0.7*cm, bw, box_h,
4, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 7)
c.setFillColor(colors.white)
c.drawCentredString(cx, mid_y+0.7*cm+box_h*0.6, label)
c.setFont("Helvetica", 6.5)
c.drawCentredString(cx, mid_y+0.7*cm+0.18*cm, text[:20])
else:
# below
c.setStrokeColor(col)
c.setLineWidth(1)
c.line(cx, mid_y-0.32*cm, cx, mid_y-0.7*cm)
c.setFillColor(col)
box_h = 0.75*cm
bw = step_w*0.9
c.roundRect(cx-bw/2, mid_y-0.7*cm-box_h, bw, box_h,
4, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 7)
c.setFillColor(colors.white)
c.drawCentredString(cx, mid_y-0.7*cm-box_h*0.35, label)
c.setFont("Helvetica", 6.5)
c.drawCentredString(cx, mid_y-0.7*cm-box_h+0.18*cm, text[:20])
# ─── Style Setup ──────────────────────────────────────────────────────────────
def build_styles():
styles = getSampleStyleSheet()
base = ParagraphStyle(
'Base', parent=styles['Normal'],
fontName='Helvetica', fontSize=10,
leading=15, textColor=C_HEADING,
spaceBefore=4, spaceAfter=4,
)
bold = ParagraphStyle(
'Bold', parent=base,
fontName='Helvetica-Bold', fontSize=10,
)
body = ParagraphStyle(
'Body', parent=base,
firstLineIndent=0.5*cm,
alignment=TA_JUSTIFY,
)
bullet = ParagraphStyle(
'Bullet', parent=base,
leftIndent=0.8*cm,
bulletIndent=0.3*cm,
spaceBefore=2, spaceAfter=2,
)
sub_bullet = ParagraphStyle(
'SubBullet', parent=bullet,
leftIndent=1.4*cm,
bulletIndent=0.9*cm,
fontSize=9.5,
)
q_style = ParagraphStyle(
'Question', parent=base,
fontName='Helvetica-Bold',
fontSize=11,
textColor=colors.HexColor("#E94560"),
spaceBefore=10, spaceAfter=4,
borderPad=0.2*cm,
)
imp = ParagraphStyle(
'Important', parent=base,
fontName='Helvetica-Bold',
fontSize=10,
backColor=C_HL_YELLOW,
textColor=C_HEADING,
borderPad=0.1*cm,
)
return {
'base': base, 'bold': bold, 'body': body,
'bullet': bullet, 'sub_bullet': sub_bullet,
'q': q_style, 'imp': imp,
}
def B(text, style):
"""Bullet point."""
return Paragraph(u"\u2022 " + text, style['bullet'])
def SB(text, style):
"""Sub-bullet."""
return Paragraph(u"\u2013 " + text, style['sub_bullet'])
def P(text, style):
return Paragraph(text, style['body'])
def Bold(text, style):
return Paragraph(text, style['bold'])
def IMP(text, style):
return Paragraph("<b>" + text + "</b>", style['imp'])
def sp(h=0.2):
return Spacer(1, h*cm)
def hr():
return HRFlowable(width="100%", thickness=0.5, color=colors.HexColor("#CCCCCC"))
# ─── Table Builder ─────────────────────────────────────────────────────────────
def make_table(headers, rows, col_widths=None, title=None):
data = [headers] + rows
if col_widths is None:
col_widths = [(PAGE_W - 4*cm) / len(headers)] * len(headers)
ts = TableStyle([
# Header
('BACKGROUND', (0,0), (-1,0), C_TABLE_HDR),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 10),
('ALIGN', (0,0), (-1,0), 'CENTER'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('ROWBACKGROUNDS', (0,1), (-1,-1), [C_TABLE_ROW1, C_TABLE_ROW2]),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,1), (-1,-1), 9.5),
('GRID', (0,0), (-1,-1), 0.5, colors.HexColor("#AAAAAA")),
('LEFTPADDING', (0,0), (-1,-1), 6),
('RIGHTPADDING', (0,0), (-1,-1), 6),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('ROUNDEDCORNERS', [5, 5, 5, 5]),
])
t = Table(data, colWidths=col_widths)
t.setStyle(ts)
return t
# ─── Page Setup ────────────────────────────────────────────────────────────────
def on_page(canvas, doc):
"""Header/footer on every page."""
canvas.saveState()
# Footer
canvas.setFillColor(colors.HexColor("#F0F0F0"))
canvas.rect(0, 0, PAGE_W, 0.8*cm, fill=1, stroke=0)
canvas.setFont("Helvetica", 8)
canvas.setFillColor(colors.HexColor("#666666"))
canvas.drawString(2*cm, 0.25*cm,
"Chapter 9: Narcotic & Substance Abuse | Forensic Medicine & Toxicology")
canvas.drawRightString(PAGE_W-2*cm, 0.25*cm,
f"Page {doc.page}")
# Top thin bar
canvas.setFillColor(C_ACCENT)
canvas.rect(0, PAGE_H-0.25*cm, PAGE_W, 0.25*cm, fill=1, stroke=0)
canvas.restoreState()
# ─── BUILD PDF ─────────────────────────────────────────────────────────────────
def build_pdf(output_path):
doc = SimpleDocTemplate(
output_path,
pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=1.5*cm, bottomMargin=1.5*cm,
)
style = build_styles()
story = []
W = PAGE_W - 4*cm
# ══════════════════════════════════════════════════════════════════════
# COVER / TITLE PAGE
# ══════════════════════════════════════════════════════════════════════
story.append(sp(0.5))
story.append(HandwrittenTitle(
"CHAPTER 9: NARCOTIC & SUBSTANCE ABUSE",
"Forensic Medicine & Toxicology | Complete Study Notes",
width=W,
))
story.append(sp(0.4))
story.append(InfographicBanner([
("4", "Questions in\nChapter", colors.HexColor("#E94560")),
("3", "Types of\nSubstances", colors.HexColor("#0F3460")),
("2", "Key\nDefinitions", colors.HexColor("#533483")),
("★", "High-Yield\nTopic", colors.HexColor("#F19C65")),
("⚕", "Forensic\nRelevance", colors.HexColor("#05C46B")),
], width=W))
story.append(sp(0.4))
story.append(HighlightBox(
"HIGH-YIELD TOPICS: Cannabis preparation (Q116) | Narcoanalysis (Q123) | "
"Solvent abuse (Q124) | Drug addiction vs habituation (Q133). "
"These 4 questions are repeatedly asked in MBBS forensic exams.",
bg_color=C_HL_YELLOW,
border_color=colors.HexColor("#F9A825"),
icon="⚑",
width=W,
))
story.append(sp(0.3))
# Table of contents
toc_data = [
["#", "Topic", "Q. No.", "Page"],
["1", "Cannabis Preparation", "Q116", "2"],
["2", "Narcoanalysis", "Q123", "3"],
["3", "Solvent Abuse", "Q124", "4"],
["4", "Drug Addiction vs Habituation", "Q133", "5"],
["5", "Comparison Tables & Diagrams", "—", "6"],
]
story.append(make_table(
toc_data[0], toc_data[1:],
col_widths=[1*cm, 7*cm, 2*cm, 2*cm],
))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# Q116: PREPARATION OF CANNABIS
# ══════════════════════════════════════════════════════════════════════
story.append(SectionHeader("Q116", "PREPARATION OF CANNABIS", colors.HexColor("#E94560"), W))
story.append(sp(0.25))
story.append(HighlightBox(
"Q. Describe the preparation of cannabis. [Forensic / Toxicology]",
bg_color=C_PURPLE_BOX,
border_color=colors.HexColor("#6A0DAD"),
icon="?",
width=W,
))
story.append(sp(0.2))
# Theory
story.append(Bold("<b>1. Introduction</b>", style))
story.append(P(
"Cannabis is derived from the plant <b>Cannabis sativa</b> (family Cannabaceae). "
"The active principle is <b>tetrahydrocannabinol (THC)</b>, which is responsible "
"for all psychoactive effects. THC is found mainly in the <b>resin</b> of the flowering "
"tops and leaves of the female plant. The plant is <b>dioecious</b> (separate male and female plants).",
style
))
story.append(sp(0.15))
story.append(Bold("<b>2. Parts of Plant Used</b>", style))
story.append(B("Flowering tops (female plant) - highest THC content", style))
story.append(B("Leaves and small stems - moderate THC", style))
story.append(B("Resin secreted from glandular trichomes - concentrated THC", style))
story.append(B("Seeds - negligible/no THC", style))
story.append(sp(0.2))
# Linear flowchart - preparation steps
story.append(LinearFlowchart(
"LINEAR FLOW: Cannabis Preparation Process",
[
("PLANT", "Harvest Cannabis sativa (female plant at flowering stage)"),
("DRYING", "Sun-dry the plant material (reduces moisture)"),
("SEPARATION", "Separate flowering tops, leaves from stems/roots"),
("PROCESSING", "Process differently for each product (see below)"),
("PRODUCTS", "Bhang / Ganja / Charas / Hashish Oil"),
("USE", "Smoked / Eaten / Drunk"),
],
colors_list=[C_HL_BLUE, C_HL_GREEN, C_HL_YELLOW,
C_HL_ORANGE, C_HL_PINK, C_HL_GREEN],
width=W,
))
story.append(sp(0.3))
story.append(Bold("<b>3. Products of Cannabis and Their Preparation</b>", style))
story.append(sp(0.1))
cannabis_table = [
["Product", "Part Used", "Preparation Method", "THC Content", "Route of Use"],
["Bhang\n(India)", "Dried leaves +\nseeds + stems",
"Pounded into paste;\nmixed with milk/water", "Lowest (1-2%)",
"Oral (drunk as\nthandai/lassi)"],
["Ganja\n(India)\n= Marijuana\n(West)",
"Dried flowering\ntops (female)", "Simply dried &\ncollected; rolled\ninto cigarettes",
"Moderate (4-8%)", "Smoked (beedis,\npipes, joints)"],
["Charas\n(India)\n= Hashish\n(Arab/West)",
"Resin from\nflowering tops", "Resin manually rubbed\noff the plant;\ncompressed into slabs/balls",
"High (8-14%)", "Smoked (pipes,\nwith tobacco)"],
["Hashish Oil\n(Honey Oil)",
"Charas/plant\nmaterial",
"Solvent extraction\n(alcohol/petroleum ether);\nthen evaporation",
"Highest (15-50%)",
"Added to cigarettes;\nvaporized"],
]
story.append(make_table(
cannabis_table[0], cannabis_table[1:],
col_widths=[2.2*cm, 2.5*cm, 3.5*cm, 2.3*cm, 2.5*cm],
))
story.append(sp(0.25))
story.append(HighlightBox(
"MNEMONIC: 'B-G-C-H' = Bhang (leaves) → Ganja (tops) → Charas (resin) → Hashish Oil (extract). "
"Potency increases in this order!",
bg_color=C_HL_YELLOW,
border_color=colors.HexColor("#F9A825"),
icon="★",
width=W,
))
story.append(sp(0.25))
story.append(Bold("<b>4. Pharmacology of Cannabis</b>", style))
story.append(B("Active principle: <b>Delta-9-tetrahydrocannabinol (Δ9-THC)</b>", style))
story.append(B("Acts on <b>CB1 receptors</b> (brain) and <b>CB2 receptors</b> (immune system)", style))
story.append(B("Produces euphoria, altered perception, relaxation, increased appetite", style))
story.append(B("High doses cause hallucinations, paranoia, anxiety", style))
story.append(sp(0.2))
story.append(Bold("<b>5. Legal Status in India</b>", style))
story.append(B("Regulated under the <b>NDPS Act 1985</b> (Narcotic Drugs and Psychotropic Substances)", style))
story.append(B("Bhang is exempt from NDPS Act in many states (sold legally at licensed shops)", style))
story.append(B("Ganja, charas, and hashish oil are <b>strictly prohibited</b>", style))
story.append(sp(0.2))
story.append(HighlightBox(
"IMP FORENSIC POINT: Cannabis is detected in urine for 3-30 days after use "
"(longer in chronic users due to fat storage of THC). Hair analysis can detect "
"use up to 90 days. THC is highly lipid-soluble.",
bg_color=C_HL_PINK,
border_color=colors.HexColor("#E94560"),
icon="⚠",
width=W,
))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# Q123: NARCOANALYSIS
# ══════════════════════════════════════════════════════════════════════
story.append(SectionHeader("Q123", "NARCOANALYSIS (TRUTH SERUM TEST)", colors.HexColor("#0F3460"), W))
story.append(sp(0.25))
story.append(HighlightBox(
"Q. What is narcoanalysis? [Forensic / Medico-legal]",
bg_color=C_PURPLE_BOX,
border_color=colors.HexColor("#6A0DAD"),
icon="?",
width=W,
))
story.append(sp(0.2))
story.append(Bold("<b>1. Definition</b>", style))
story.append(P(
"Narcoanalysis (also called <b>narcotic analysis</b> or <b>truth serum test</b>) is "
"a technique of criminal investigation in which a subject is placed in a "
"<b>semi-conscious/hypnotic state</b> by administering a <b>narcotic drug</b> "
"(most commonly <b>sodium pentothal / sodium amytal</b>), in order to elicit "
"information that the subject may be unwilling or unable to give in a fully "
"conscious state.",
style
))
story.append(sp(0.15))
story.append(Bold("<b>2. Drugs Used</b>", style))
drugs_table = [
["Drug", "Class", "Dose / Route", "Mechanism"],
["Sodium Pentothal\n(Sodium Thiopentone)", "Barbiturate\n(ultra-short acting)",
"IV: 3-4 mg/kg slow",
"GABA-A receptor\npotentiation → CNS depression"],
["Sodium Amytal\n(Amobarbital)", "Barbiturate",
"IV: 250-500 mg slow",
"GABA-A agonist;\nproduces sedation"],
["Scopolamine\n(Hyoscine)", "Anticholinergic",
"SC/IM: 0.3-0.6 mg",
"Blocks muscarinic receptors;\nproduce delirium"],
]
story.append(make_table(
drugs_table[0], drugs_table[1:],
col_widths=[3.5*cm, 2.5*cm, 3.0*cm, 4.0*cm],
))
story.append(sp(0.25))
# Linear flowchart - procedure
story.append(LinearFlowchart(
"LINEAR FLOW: Narcoanalysis Procedure",
[
("CONSENT", "Obtain court order (NOT self-consent) - voluntary use prohibited"),
("SETUP", "Anaesthesiologist + forensic expert + investigator present"),
("DRUG", "Sodium pentothal IV: titrate to achieve hypnotic state"),
("INTERVIEW", "Subject in twilight (semi-conscious) state - questions asked"),
("RECORDING", "Entire session audio/video recorded"),
("ANALYSIS", "Experts analyze responses for forensic value"),
("REPORT", "Report submitted to court"),
],
colors_list=[C_HL_BLUE, C_HL_GREEN, C_HL_YELLOW, C_HL_ORANGE,
C_HL_PINK, C_HL_BLUE, C_HL_GREEN],
width=W,
))
story.append(sp(0.25))
story.append(Bold("<b>3. Principle / Rationale</b>", style))
story.append(P(
"Under the influence of barbiturates, the <b>higher cortical centres</b> responsible "
"for conscious inhibition are depressed. The subject loses the ability to "
"exercise deliberate control over responses. However, lower brain centres "
"remain partially functional, allowing speech and response to questions. "
"This 'twilight state' is thought to reduce deliberate lying.",
style
))
story.append(sp(0.2))
story.append(Bold("<b>4. Legal Status in India</b>", style))
story.append(B("Supreme Court of India ruling (<b>Selvi & Others vs State of Karnataka, 2010</b>): "
"Compulsory narcoanalysis violates <b>Article 20(3)</b> of the Constitution "
"(Right against self-incrimination)", style))
story.append(B("Also violates <b>Article 21</b> (Right to life and personal liberty)", style))
story.append(B("Can be done <b>ONLY with the consent</b> of the individual", style))
story.append(B("Results are <b>NOT admissible as direct evidence</b> in court", style))
story.append(B("Can be used as <b>investigative leads</b> only", style))
story.append(sp(0.2))
# Branching flowchart - is it admissible?
story.append(BranchingFlowchart(
question="Accused gives VOLUNTARY consent?",
yes_path=["Narcoanalysis performed", "Results analyzed"],
no_path=["Cannot be forced", "Constitutional violation"],
yes_outcome="Leads valid (NOT direct evidence)",
no_outcome="Test CANNOT be done",
title="BRANCHING: Is Narcoanalysis Admissible?",
width=W,
))
story.append(sp(0.2))
story.append(HighlightBox(
"IMP: Selvi vs Karnataka 2010 - Supreme Court held narcoanalysis, brain mapping, "
"and polygraph WITHOUT CONSENT are unconstitutional. Remember: 3 tests (Narco + Brain "
"Mapping + Polygraph) - all require CONSENT.",
bg_color=C_HL_YELLOW,
border_color=colors.HexColor("#F9A825"),
icon="★",
width=W,
))
story.append(sp(0.2))
story.append(Bold("<b>5. Limitations of Narcoanalysis</b>", style))
story.append(B("Results are <b>unreliable</b> - subject may confabulate (invent memories)", style))
story.append(B("Highly suggestible state means examiner can inadvertently plant ideas", style))
story.append(B("Drug tolerance in addicts may alter the effect", style))
story.append(B("Risk of respiratory depression and death with high doses", style))
story.append(B("Medical contraindications: respiratory disease, hepatic failure", style))
story.append(sp(0.2))
story.append(Bold("<b>6. Comparison: Narcoanalysis vs Polygraph vs Brain Mapping</b>", style))
story.append(sp(0.1))
compare_table = [
["Feature", "Narcoanalysis", "Polygraph\n(Lie Detector)", "Brain Mapping\n(BEOS/P300)"],
["Principle", "Drug-induced\nsemi-consciousness", "Measures physio-\nlogical responses\nto lies", "EEG detects\nbrain response to\nfamiliar stimuli"],
["Drug Used", "Sodium pentothal/\nAmytal", "None", "None"],
["Type", "Chemical", "Instrumental", "Neuro-imaging"],
["Consent\nRequired", "YES (mandatory)", "YES", "YES"],
["Admissibility", "NOT direct\nevidence", "NOT direct\nevidence", "NOT direct\nevidence"],
["Reliability", "Low", "Moderate", "Higher"],
]
story.append(make_table(
compare_table[0], compare_table[1:],
col_widths=[2.5*cm, 3.8*cm, 3.8*cm, 3.8*cm],
))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# Q124: SOLVENT ABUSE
# ══════════════════════════════════════════════════════════════════════
story.append(SectionHeader("Q124", "SOLVENT ABUSE (INHALANT ABUSE)", colors.HexColor("#533483"), W))
story.append(sp(0.25))
story.append(HighlightBox(
"Q. What is solvent abuse? [Toxicology / Substance Abuse]",
bg_color=C_PURPLE_BOX,
border_color=colors.HexColor("#6A0DAD"),
icon="?",
width=W,
))
story.append(sp(0.2))
story.append(Bold("<b>1. Definition</b>", style))
story.append(P(
"Solvent abuse (also called <b>inhalant abuse</b> or <b>volatile substance abuse / VSA</b>) "
"refers to the deliberate inhalation of volatile chemical substances to achieve "
"a <b>psychoactive/euphoric effect</b>. It is most common among <b>adolescents "
"and street children</b> as these substances are cheap and easily available.",
style
))
story.append(sp(0.2))
story.append(Bold("<b>2. Classification of Inhalants</b>", style))
story.append(sp(0.1))
inhalants_table = [
["Category", "Examples", "Common Sources", "Key Toxin"],
["Volatile Solvents", "Toluene, benzene,\nhexane, acetone",
"Glue, paint thinner,\nmarker pens, nail polish", "Toluene"],
["Aerosols", "Fluorocarbons,\npropellants",
"Spray paint, hair spray,\ndeodorant cans", "Fluorocarbons"],
["Gases", "Butane, propane,\nnitrous oxide",
"Lighter refills,\nwhipped cream canisters", "Butane"],
["Nitrites\n(Poppers)", "Amyl nitrite,\nbutyl nitrite",
"Room deodorizers,\n'poppers'", "Amyl nitrite"],
]
story.append(make_table(
inhalants_table[0], inhalants_table[1:],
col_widths=[3*cm, 3.5*cm, 3.5*cm, 3*cm],
))
story.append(sp(0.25))
story.append(Bold("<b>3. Methods of Inhalation</b>", style))
story.append(B("<b>Sniffing</b>: Directly inhaling from the container", style))
story.append(B("<b>Huffing</b>: Soaking a cloth in the substance and placing over mouth/nose", style))
story.append(B("<b>Bagging</b>: Breathing in and out from a bag containing the substance "
"(most dangerous - causes hypoxia + rebreathing)", style))
story.append(sp(0.2))
# Branching flowchart - outcome
story.append(BranchingFlowchart(
question="Chronic / Repeated Solvent Abuse?",
yes_path=["Neuronal damage (white matter)", "Dementia, ataxia develop"],
no_path=["Acute intoxication", "Euphoria / hallucinations"],
yes_outcome="Chronic organ failure",
no_outcome="Usually recovers",
title="BRANCHING: Acute vs Chronic Effects",
width=W,
))
story.append(sp(0.2))
story.append(Bold("<b>4. Effects of Solvent Abuse</b>", style))
story.append(sp(0.1))
effects_table = [
["System", "Acute Effects", "Chronic Effects"],
["CNS", "Euphoria, dizziness,\nhallucinations, ataxia", "Dementia, cerebellar ataxia,\nneuropathy, leukoencephalopathy"],
["Cardiovascular", "Arrhythmias\n(Sudden Sniffing Death)", "Cardiomyopathy"],
["Renal", "Haematuria", "Renal tubular acidosis\n(toluene)"],
["Hepatic", "Nausea", "Hepatotoxicity (benzene)"],
["Haematological", "—", "Aplastic anaemia\n(benzene - BIG EXAM Q)"],
["Respiratory", "Bronchospasm", "Pulmonary hypertension"],
["Psychological", "Disinhibition", "Depression, personality\nchange, addiction"],
]
story.append(make_table(
effects_table[0], effects_table[1:],
col_widths=[2.5*cm, 5*cm, 5.5*cm],
))
story.append(sp(0.25))
story.append(HighlightBox(
"SUDDEN SNIFFING DEATH: Most common cause of death in acute solvent abuse. "
"Mechanism = cardiac arrhythmia (ventricular fibrillation) due to sensitization "
"of myocardium to catecholamines by fluorocarbons/hydrocarbons. "
"Occurs even with FIRST-TIME use!",
bg_color=C_HL_PINK,
border_color=C_WARN,
icon="☠",
width=W,
))
story.append(sp(0.2))
story.append(HighlightBox(
"BENZENE specifically causes: (a) Aplastic anaemia (b) Leukaemia "
"- both due to bone marrow toxicity. TOLUENE specifically causes renal tubular acidosis.",
bg_color=C_HL_YELLOW,
border_color=colors.HexColor("#F9A825"),
icon="★",
width=W,
))
story.append(sp(0.2))
story.append(Bold("<b>5. Mind Map: Solvent Abuse</b>", style))
story.append(MindMapDiagram(
center="SOLVENT\nABUSE",
branches=[
("Types", ["Volatile solvents", "Aerosols", "Gases", "Nitrites"]),
("Methods", ["Sniffing", "Huffing", "Bagging"]),
("Acute FX", ["Euphoria", "Hallucinations", "Arrhythmia"]),
("Chronic FX", ["Dementia", "Aplastic anaemia", "Renal tubular acidosis"]),
("Death", ["Sudden Sniffing Death", "VF/cardiac arrest"]),
("Treatment", ["Remove exposure", "O2 therapy", "Cardiac monitoring"]),
],
width=W,
))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# Q133: DRUG ADDICTION vs HABITUATION
# ══════════════════════════════════════════════════════════════════════
story.append(SectionHeader("Q133", "DRUG ADDICTION vs DRUG HABITUATION", colors.HexColor("#05C46B"), W))
story.append(sp(0.25))
story.append(HighlightBox(
"Q. What is the difference between drug addiction and drug habituation? [Toxicology]",
bg_color=C_PURPLE_BOX,
border_color=colors.HexColor("#6A0DAD"),
icon="?",
width=W,
))
story.append(sp(0.2))
story.append(Bold("<b>1. Definitions</b>", style))
story.append(sp(0.1))
story.append(Paragraph(
"<b>Drug Addiction (WHO Definition)</b>: A state of periodic or chronic intoxication "
"detrimental to the individual and to society, produced by the repeated consumption "
"of a drug (natural or synthetic). Characteristics include: (1) an overpowering "
"desire or need (compulsion) to continue taking the drug, (2) a tendency to increase "
"the dose, (3) psychological and generally physical dependence, (4) detrimental "
"effect on individual and society.",
style['body']
))
story.append(sp(0.1))
story.append(Paragraph(
"<b>Drug Habituation (WHO Definition)</b>: A condition resulting from repeated "
"consumption of a drug. Characteristics include: (1) desire (not compulsion) to "
"continue taking the drug, (2) little or no tendency to increase dose, "
"(3) some degree of psychological dependence but absence of physical dependence, "
"(4) detrimental effect primarily on the individual.",
style['body']
))
story.append(sp(0.2))
story.append(Bold("<b>2. Comparison Table (KEY TABLE - Very High Yield)</b>", style))
story.append(sp(0.1))
diff_table = [
["Feature", "Drug ADDICTION", "Drug HABITUATION"],
["Compulsion", "YES - Overpowering compulsion\n(cannot stop)", "NO - Desire only\n(can stop)"],
["Dose tendency", "Strong tendency to\nINCREASE dose", "Little/no tendency\nto increase dose"],
["Physical\nDependence", "YES - Present\n(withdrawal syndrome)", "NO - Absent"],
["Psychological\nDependence", "YES - Strong", "YES - Mild/moderate"],
["Tolerance", "YES - Develops", "Minimal"],
["Withdrawal\nSyndrome", "YES - Severe\n(physical symptoms)", "NO (or very mild\npsychological symptoms)"],
["Harm to Society", "YES - Significant\n(crime, violence)", "Mainly individual harm"],
["Detrimental\nEffect", "Individual AND\nSociety", "Mainly INDIVIDUAL"],
["Examples", "Heroin, morphine,\ncocaine, alcohol", "Tobacco (nicotine),\ncaffeine, cannabis"],
]
story.append(make_table(
diff_table[0], diff_table[1:],
col_widths=[3*cm, 5.5*cm, 5.5*cm],
))
story.append(sp(0.25))
# Branching flowchart
story.append(BranchingFlowchart(
question="Physical withdrawal symptoms present?",
yes_path=["Compulsion to use", "Dose escalation seen"],
no_path=["Only desire, no compulsion", "No dose escalation"],
yes_outcome="ADDICTION",
no_outcome="HABITUATION",
title="BRANCHING: Addiction or Habituation?",
width=W,
))
story.append(sp(0.25))
story.append(Bold("<b>3. Note on WHO Terminology (1964 Update)</b>", style))
story.append(P(
"In 1964, WHO replaced both 'addiction' and 'habituation' with the single term "
"<b>'Drug Dependence'</b> to avoid confusion. Drug dependence is now classified as: "
"<b>Physical dependence</b> (body adapts, withdrawal on stopping) and "
"<b>Psychological/Psychic dependence</b> (craving, emotional reliance). "
"However, for examination purposes, the old WHO definitions of addiction vs "
"habituation are still tested and should be memorized.",
style
))
story.append(sp(0.2))
story.append(Bold("<b>4. Tolerance</b>", style))
story.append(P(
"Tolerance is the state in which the same dose of a drug produces diminishing "
"effects OR progressively larger doses are needed to produce the same effect. "
"Types: <b>(a) Pharmacokinetic tolerance</b> (increased metabolism), "
"<b>(b) Pharmacodynamic tolerance</b> (receptor downregulation), "
"<b>(c) Cross-tolerance</b> (tolerance to one drug causes tolerance to another in same class).",
style
))
story.append(sp(0.2))
story.append(Bold("<b>5. Withdrawal Syndrome</b>", style))
story.append(sp(0.1))
withdraw_table = [
["Drug", "Key Withdrawal Features", "Onset", "Duration"],
["Heroin/\nMorphine\n(Opioids)", "Yawning, lacrimation, rhinorrhoea,\ngoosebumps (cold turkey), muscle\ncramps, diarrhoea, insomnia", "6-24 hrs", "7-10 days"],
["Alcohol", "Tremors, sweating, seizures,\ndelirium tremens (DTs) - most\ndangerous withdrawal", "6-24 hrs", "3-7 days"],
["Benzodiazepines", "Anxiety, insomnia, seizures\n(similar to alcohol)", "1-3 days\n(long-acting)", "Weeks"],
["Cocaine", "Depression, fatigue, hypersomnia,\nincreased appetite ('crash')", "Hours", "Days-weeks"],
["Nicotine", "Irritability, difficulty\nconcentrating, increased appetite", "Hours", "Weeks"],
]
story.append(make_table(
withdraw_table[0], withdraw_table[1:],
col_widths=[2.5*cm, 5.5*cm, 2*cm, 2*cm],
))
story.append(sp(0.2))
story.append(HighlightBox(
"COLD TURKEY = Opioid withdrawal. Goosebumps (piloerection) look like turkey skin. "
"DTs (Delirium Tremens) = ALCOHOL withdrawal - most medically dangerous withdrawal "
"(can be fatal due to seizures + autonomic instability).",
bg_color=C_HL_YELLOW,
border_color=colors.HexColor("#F9A825"),
icon="★",
width=W,
))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# COMPARISON & EXTRA DIAGRAMS
# ══════════════════════════════════════════════════════════════════════
story.append(SectionHeader("★", "SUMMARY TABLES & HIGH-YIELD COMPARISONS",
colors.HexColor("#F19C65"), W))
story.append(sp(0.25))
# Timeline - NDPS Act
story.append(HorizontalTimeline(
"TIMELINE: Key NDPS Act 1985 Provisions",
[
("NDPS 1985", "Enacted to control narcotic drugs"),
("Schedule I", "Most restricted substances"),
("Bhang Exempt", "Some states exempted"),
("NDPS 2001", "Amendment - stricter penalties"),
("Selvi 2010", "SC ruling on narcoanalysis"),
("NDPS 2014", "Further amendments"),
],
width=W,
))
story.append(sp(0.3))
# Comparison - Addiction vs Habituation visual
story.append(ComparisonDiagram(
title="ADDICTION vs HABITUATION (Visual Summary)",
left_title="ADDICTION",
right_title="HABITUATION",
left_items=[
"Physical dependence",
"Compulsion (MUST have it)",
"Dose escalation",
"Severe withdrawal",
"Social harm",
"e.g. Heroin, cocaine",
],
right_items=[
"No physical dependence",
"Desire (can stop)",
"Stable dose",
"Mild/no withdrawal",
"Individual harm only",
"e.g. Caffeine, tobacco",
],
width=W,
))
story.append(sp(0.3))
# Full drug summary table
story.append(Bold("<b>All Chapter 9 Drugs - Quick Reference Table</b>", style))
story.append(sp(0.1))
drug_ref = [
["Drug / Substance", "Source", "Active Principle", "Addiction?", "NDPS?"],
["Cannabis (Ganja)", "Cannabis sativa", "Δ9-THC", "Habituation\n→ Addiction", "YES"],
["Heroin", "Morphine (opium\npoppy semisynthetic)", "Diacetylmorphine", "Strong Addiction", "YES"],
["Cocaine", "Erythroxylum coca", "Cocaine alkaloid", "Addiction", "YES"],
["Alcohol", "Fermentation", "Ethanol", "Addiction", "NO"],
["Tobacco", "Nicotiana tabacum", "Nicotine", "Habituation\n→ Addiction", "NO"],
["Solvents", "Industrial chemicals", "Toluene/benzene\n/fluorocarbons", "Habituation", "NO"],
["LSD", "Ergot fungus\n(semisynthetic)", "Lysergic acid\ndiethylamide", "Habituation", "YES"],
["Amphetamine", "Synthetic", "Amphetamine", "Addiction", "YES"],
]
story.append(make_table(
drug_ref[0], drug_ref[1:],
col_widths=[3*cm, 3.5*cm, 3.0*cm, 2.5*cm, 1.5*cm],
))
story.append(sp(0.3))
story.append(HighlightBox(
"MNEMONICS: (1) 'Physical dependence = ABCOS' = Alcohol, Barbiturates, "
"Cannabis (mild), Opioids, Sedative-hypnotics. "
"(2) Ganja-Charas-Bhang in order of DECREASING potency. "
"(3) Narco = Sodium Pentothal (barbiturate). "
"(4) Sudden Sniffing Death = VF due to sensitized myocardium.",
bg_color=C_HL_GREEN,
border_color=colors.HexColor("#05C46B"),
icon="✓",
width=W,
))
story.append(sp(0.25))
# Final Important Points
story.append(SectionHeader("!", "IMPORTANT FORENSIC POINTS TO REMEMBER",
colors.HexColor("#E94560"), W))
story.append(sp(0.15))
imp_points = [
"Bhang is the WEAKEST preparation of cannabis; Hashish oil is the STRONGEST.",
"Charas = Hashish = Resin collected by hand from flowering tops of female Cannabis sativa.",
"Narcoanalysis uses sodium pentothal (ultra-short acting barbiturate) IV.",
"Selvi vs Karnataka 2010 (Supreme Court): Narco/polygraph/brain mapping require CONSENT.",
"Results of narcoanalysis are NOT admissible as direct evidence - only as investigative leads.",
"ADDICTION = Physical + psychological dependence; HABITUATION = Only psychological.",
"WHO 1964: Replaced 'addiction' and 'habituation' with 'Drug Dependence'.",
"Sudden Sniffing Death (solvent abuse) = Ventricular fibrillation - can occur on first use.",
"Benzene → Aplastic anaemia + leukaemia (bone marrow toxicity).",
"Toluene → Renal tubular acidosis.",
"DTs (Delirium Tremens) is the most dangerous withdrawal - seen in alcohol dependence.",
"Cold Turkey = Opioid withdrawal signs (gooseflesh, rhinorrhoea, muscle cramps).",
"THC detectable in urine for 3-30 days; in hair for up to 90 days.",
"NDPS Act 1985 governs all narcotic and psychotropic substances in India.",
]
for i, pt in enumerate(imp_points, 1):
story.append(Paragraph(
f"<b>{i}.</b> {pt}",
ParagraphStyle(
f'ImpPt{i}', parent=style['bullet'],
backColor=C_HL_YELLOW if i % 2 == 0 else C_HL_GREEN,
borderPad=3,
spaceBefore=2,
spaceAfter=2,
)
))
story.append(sp(0.3))
# Build
doc.build(story, onFirstPage=on_page, onLaterPages=on_page)
print(f"PDF created: {output_path}")
if __name__ == "__main__":
output = "/home/daytona/workspace/chapter9-narcotic/Chapter9_Narcotic_Substance_Abuse.pdf"
build_pdf(output)
cd /home/daytona/workspace/chapter9-narcotic && python3 generate_chapter9.py 2>&…
~/chapter9-narcotic/generate_chapter9.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/chapter9-narcotic/generate_chapter9.py'
cd /home/daytona/workspace/chapter9-narcotic && python3 generate_chapter9.py 2>&…
~/chapter9-narcotic/generate_chapter9.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/chapter9-narcotic/generate_chapter9.py'
cd /home/daytona/workspace/chapter9-narcotic && python3 generate_chapter9.py 2>&…
Oyee ediot
Make ppt not pdf
~/chapter9-narcotic/chapter9.js
const pptxgen = require("pptxgenjs");
const pres = new pptxgen();
pres.layout = "LAYOUT_16x9";
pres.title = "Chapter 9: Narcotic & Substance Abuse";
pres.author = "Forensic Medicine & Toxicology";
// ── COLOUR PALETTE ──────────────────────────────────────────────────────────
const C = {
dark: "0D1B2A",
navy: "1A2E4A",
blue: "1B4F72",
accent: "E94560",
gold: "F4C430",
green: "1E8449",
teal: "148F77",
purple: "6C3483",
white: "FFFFFF",
offWhite:"F8F9FA",
lgray: "ECF0F1",
mgray: "BDC3C7",
yellow: "FFF9C4",
lgreen: "D5F5E3",
lred: "FADBD8",
lBlue: "D6EAF8",
lpurp: "E8DAEF",
orange: "F39C12",
lOrange: "FDEBD0",
};
// ── HELPERS ──────────────────────────────────────────────────────────────────
/** Slide header bar */
function addHeader(slide, title, sub, bgColor) {
bgColor = bgColor || C.dark;
slide.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 1.1, fill: { color: bgColor } });
slide.addText(title, {
x: 0.3, y: 0.08, w: 8, h: 0.55,
fontSize: 22, bold: true, color: C.white, fontFace: "Calibri",
});
if (sub) {
slide.addText(sub, {
x: 0.3, y: 0.62, w: 9, h: 0.38,
fontSize: 12, color: C.gold, italic: true, fontFace: "Calibri",
});
}
// Accent stripe
slide.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 0.18, h: 1.1, fill: { color: C.accent } });
}
/** Footer bar */
function addFooter(slide, page) {
slide.addShape(pres.ShapeType.rect, { x: 0, y: 5.35, w: 10, h: 0.28, fill: { color: C.navy } });
slide.addText("Chapter 9: Narcotic & Substance Abuse | Forensic Medicine & Toxicology", {
x: 0.2, y: 5.37, w: 8, h: 0.22, fontSize: 7.5, color: C.mgray, fontFace: "Calibri",
});
slide.addText("" + page, {
x: 9.5, y: 5.37, w: 0.4, h: 0.22, fontSize: 7.5, color: C.gold, bold: true, align: "right",
});
}
/** Highlight / callout box */
function addCallout(slide, text, x, y, w, h, bg, border, textColor) {
slide.addShape(pres.ShapeType.roundRect, {
x, y, w, h,
fill: { color: bg },
line: { color: border, width: 1.5 },
rectRadius: 0.1,
});
slide.addText(text, {
x: x + 0.12, y: y + 0.06, w: w - 0.24, h: h - 0.12,
fontSize: 10.5, color: textColor || C.dark, fontFace: "Calibri",
wrap: true, valign: "middle",
});
}
/** Flowchart box */
function fcBox(slide, text, x, y, w, h, fill, textColor) {
slide.addShape(pres.ShapeType.roundRect, {
x, y, w, h,
fill: { color: fill },
line: { color: C.blue, width: 1 },
rectRadius: 0.08,
shadow: { type: "outer", color: "888888", blur: 3, offset: 1, angle: 45, opacity: 0.3 },
});
slide.addText(text, {
x: x + 0.08, y, w: w - 0.16, h,
fontSize: 10, bold: true, color: textColor || C.dark,
align: "center", valign: "middle", fontFace: "Calibri", wrap: true,
});
}
/** Down-arrow between flowchart boxes */
function fcArrow(slide, x, y) {
slide.addShape(pres.ShapeType.line, {
x, y, w: 0, h: 0.18,
line: { color: C.blue, width: 2 },
});
// Arrowhead triangle
slide.addShape(pres.ShapeType.isosceles_triangle, {
x: x - 0.08, y: y + 0.15, w: 0.16, h: 0.12,
fill: { color: C.blue },
line: { color: C.blue, width: 0 },
rotate: 180,
});
}
/** Section label pill */
function addPill(slide, text, x, y, bg) {
slide.addShape(pres.ShapeType.roundRect, {
x, y, w: 1.6, h: 0.32,
fill: { color: bg || C.accent },
line: { color: bg || C.accent, width: 0 },
rectRadius: 0.16,
});
slide.addText(text, {
x, y, w: 1.6, h: 0.32,
fontSize: 9, bold: true, color: C.white, align: "center", valign: "middle",
});
}
/** Table helper */
function addTable(slide, headers, rows, x, y, w) {
const colW = headers.map(() => w / headers.length);
const tableRows = [
headers.map(h => ({
text: h,
options: {
bold: true, color: C.white,
fill: { color: C.blue },
fontSize: 10, align: "center", fontFace: "Calibri",
border: { pt: 1, color: C.navy },
},
})),
...rows.map((row, i) =>
row.map(cell => ({
text: cell,
options: {
fontSize: 9.5, color: C.dark, fontFace: "Calibri",
fill: { color: i % 2 === 0 ? C.lBlue : C.white },
border: { pt: 0.5, color: C.mgray },
valign: "middle",
},
}))
),
];
slide.addTable(tableRows, { x, y, w, colW, rowH: 0.38 });
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 1 — COVER
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
// Full dark bg
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.dark } });
// Left accent strip
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 0.4, h: 5.63, fill: { color: C.accent } });
// Gold horizontal line
s.addShape(pres.ShapeType.line, { x: 0.6, y: 2.35, w: 8.8, h: 0, line: { color: C.gold, width: 1.5 } });
s.addShape(pres.ShapeType.line, { x: 0.6, y: 3.82, w: 8.8, h: 0, line: { color: C.gold, width: 0.5 } });
s.addText("FORENSIC MEDICINE & TOXICOLOGY", {
x: 0.6, y: 1.5, w: 9, h: 0.5,
fontSize: 13, color: C.gold, charSpacing: 4, bold: true, fontFace: "Calibri",
});
s.addText("CHAPTER 9", {
x: 0.6, y: 2.0, w: 9, h: 0.5,
fontSize: 20, color: C.accent, bold: true, fontFace: "Calibri",
});
s.addText("NARCOTIC &\nSUBSTANCE ABUSE", {
x: 0.6, y: 2.45, w: 9, h: 1.3,
fontSize: 38, bold: true, color: C.white, fontFace: "Calibri", lineSpacingMultiple: 1.1,
});
s.addText("Cannabis · Narcoanalysis · Solvent Abuse · Addiction vs Habituation", {
x: 0.6, y: 3.88, w: 9, h: 0.45,
fontSize: 12, color: C.mgray, italic: true, fontFace: "Calibri",
});
// 4 stat boxes bottom row
const stats = [
["4", "Questions"], ["Q116","Cannabis"], ["Q123","Narcoanalysis"], ["Q133","Addiction vs Habit."],
];
const colors_stat = [C.accent, C.blue, C.teal, C.purple];
stats.forEach(([num, lbl], i) => {
const bx = 0.6 + i * 2.35;
s.addShape(pres.ShapeType.roundRect, {
x: bx, y: 4.45, w: 2.15, h: 0.9,
fill: { color: colors_stat[i] }, line: { color: colors_stat[i], width: 0 }, rectRadius: 0.08,
});
s.addText(num, { x: bx, y: 4.48, w: 2.15, h: 0.42, fontSize: 18, bold: true, color: C.white, align: "center" });
s.addText(lbl, { x: bx, y: 4.88, w: 2.15, h: 0.28, fontSize: 8.5, color: C.white, align: "center" });
});
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 2 — TABLE OF CONTENTS
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "TABLE OF CONTENTS", "Chapter 9 – Narcotic & Substance Abuse", C.navy);
addFooter(s, 2);
const items = [
["01", "Preparation of Cannabis", "Q116", C.accent],
["02", "Narcoanalysis (Truth Serum Test)", "Q123", C.blue],
["03", "Solvent Abuse (Inhalant Abuse)", "Q124", C.purple],
["04", "Drug Addiction vs Drug Habituation", "Q133", C.green],
["05", "Comparison Tables & Summary", "—", C.teal],
["06", "High-Yield Points & Mnemonics", "—", C.orange],
];
items.forEach(([num, title, q, col], i) => {
const y = 1.25 + i * 0.68;
s.addShape(pres.ShapeType.roundRect, {
x: 0.4, y, w: 9.2, h: 0.55,
fill: { color: i % 2 === 0 ? C.lBlue : C.white },
line: { color: col, width: 1.5 }, rectRadius: 0.06,
});
s.addShape(pres.ShapeType.rect, { x: 0.4, y, w: 0.5, h: 0.55, fill: { color: col }, line: { color: col, width: 0 } });
s.addText(num, { x: 0.4, y, w: 0.5, h: 0.55, fontSize: 13, bold: true, color: C.white, align: "center", valign: "middle" });
s.addText(title, { x: 1.05, y: y + 0.1, w: 6.5, h: 0.35, fontSize: 13, bold: true, color: C.dark, fontFace: "Calibri" });
s.addShape(pres.ShapeType.roundRect, { x: 8.5, y: y + 0.1, w: 0.9, h: 0.32, fill: { color: col }, line: { color: col, width: 0 }, rectRadius: 0.12 });
s.addText(q, { x: 8.5, y: y + 0.1, w: 0.9, h: 0.32, fontSize: 9, bold: true, color: C.white, align: "center", valign: "middle" });
});
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 3 — CANNABIS: INTRO & PLANT
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Q116: CANNABIS — Introduction", "Cannabis sativa | Active principle: Δ9-THC", C.green);
addFooter(s, 3);
// Left column – theory
addCallout(s, "Cannabis sativa (Family: Cannabaceae)\nDioecious plant — separate male & female plants\nActive principle: Delta-9-Tetrahydrocannabinol (Δ9-THC)\nTHC found mainly in RESIN of female flowering tops\nHigher THC → stronger effect", 0.3, 1.22, 4.5, 1.6, C.lgreen, C.green);
// Parts of plant used
s.addText("Parts of Plant Used:", { x: 0.3, y: 2.95, w: 4.5, h: 0.32, fontSize: 11, bold: true, color: C.green, fontFace: "Calibri" });
const parts = [
["🌸", "Flowering tops (female)", "HIGHEST THC"],
["🍃", "Leaves & small stems", "Moderate THC"],
["💧", "Resin (trichomes)", "Concentrated THC"],
["🌰", "Seeds", "NEGLIGIBLE THC"],
];
parts.forEach(([icon, part, note], i) => {
const y = 3.3 + i * 0.48;
s.addShape(pres.ShapeType.roundRect, { x: 0.3, y, w: 4.4, h: 0.4, fill: { color: i % 2 === 0 ? C.lgreen : C.white }, line: { color: C.green, width: 0.7 }, rectRadius: 0.05 });
s.addText(icon + " " + part, { x: 0.4, y: y + 0.05, w: 2.8, h: 0.3, fontSize: 9.5, color: C.dark });
s.addText(note, { x: 3.4, y: y + 0.05, w: 1.2, h: 0.3, fontSize: 8.5, bold: true, color: C.green, align: "right" });
});
// Right column – linear flowchart (preparation steps)
s.addText("Preparation Flow:", { x: 5.1, y: 1.2, w: 4.5, h: 0.32, fontSize: 11, bold: true, color: C.blue, fontFace: "Calibri" });
const steps = [
["HARVEST", C.lBlue],
["DRY (sun-dry)", C.lgreen],
["SEPARATE parts", C.yellow],
["PROCESS by type", C.lOrange],
["FINAL PRODUCT", C.lred],
["USE / Consume", C.lpurp],
];
steps.forEach(([label, fill], i) => {
const bx = 5.5, by = 1.57 + i * 0.6;
fcBox(s, label, bx, by, 3.5, 0.42, fill, C.dark);
if (i < steps.length - 1) fcArrow(s, bx + 1.75, by + 0.42);
});
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 4 — CANNABIS PRODUCTS TABLE
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Q116: Cannabis Products & Preparation", "B → G → C → H (increasing potency order)", C.green);
addFooter(s, 4);
addTable(s,
["Product", "Part Used", "Method", "THC %", "Route"],
[
["Bhang\n(India)", "Dried leaves +\nseeds + stems", "Pounded into paste;\nmixed with milk/water", "1–2%\n(Lowest)", "Oral"],
["Ganja / Marijuana", "Dried flowering\ntops (female)", "Dried & collected;\nrolled into cigarettes", "4–8%\n(Moderate)", "Smoked"],
["Charas / Hashish", "Resin from\nflowering tops", "Resin rubbed off manually;\ncompressed into slabs/balls", "8–14%\n(High)", "Smoked"],
["Hashish Oil\n(Honey Oil)", "Charas /\nplant material", "Solvent extraction;\nthen evaporation", "15–50%\n(Highest)", "Vaped /\nCigarettes"],
],
0.3, 1.22, 9.4
);
// Mnemonic banner
s.addShape(pres.ShapeType.roundRect, {
x: 0.3, y: 3.85, w: 9.4, h: 0.65,
fill: { color: C.yellow }, line: { color: C.orange, width: 2 }, rectRadius: 0.1,
});
s.addText("★ MNEMONIC: B-G-C-H = Bhang (leaves) → Ganja (tops) → Charas (resin) → Hashish Oil (extract) | Potency INCREASES in this order!", {
x: 0.5, y: 3.88, w: 9, h: 0.58,
fontSize: 11, bold: true, color: C.dark, fontFace: "Calibri", align: "center", valign: "middle",
});
// Legal box
addCallout(s,
"⚖ LEGAL STATUS (India): Governed by NDPS Act 1985.\nBhang = Exempt in many states (sold legally).\nGanja, Charas, Hashish Oil = STRICTLY PROHIBITED.\nTHC detectable in urine 3–30 days; hair up to 90 days.",
0.3, 4.6, 9.4, 0.75, C.lred, C.accent, C.dark
);
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 5 — NARCOANALYSIS: DEFINITION & DRUGS
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Q123: NARCOANALYSIS — Definition & Drugs Used", "Truth Serum Test | Sodium Pentothal", C.blue);
addFooter(s, 5);
// Definition box
addCallout(s,
"DEFINITION: Narcoanalysis is a technique of criminal investigation in which a subject is placed in a SEMI-CONSCIOUS/HYPNOTIC state by administering a narcotic drug (most commonly Sodium Pentothal / Sodium Amytal) to elicit information that the subject may be unwilling to give in a fully conscious state.",
0.3, 1.2, 9.4, 1.0, C.lBlue, C.blue, C.dark
);
// Drugs table
s.addText("Drugs Used in Narcoanalysis:", { x: 0.3, y: 2.32, w: 6, h: 0.32, fontSize: 11, bold: true, color: C.blue });
addTable(s,
["Drug", "Class", "Dose / Route", "Mechanism"],
[
["Sodium Pentothal\n(Thiopentone)★", "Barbiturate\n(ultra-short acting)", "IV: 3–4 mg/kg slow", "GABA-A potentiation → CNS depression"],
["Sodium Amytal\n(Amobarbital)", "Barbiturate", "IV: 250–500 mg slow", "GABA-A agonist → sedation"],
["Scopolamine\n(Hyoscine)", "Anticholinergic", "SC/IM: 0.3–0.6 mg", "Blocks muscarinic receptors → delirium"],
],
0.3, 2.68, 9.4
);
// Principle box
addCallout(s,
"⚙ PRINCIPLE: Barbiturates depress higher cortical centres responsible for conscious inhibition. Subject loses deliberate control → cannot exercise calculated lying. Lower brain centres remain partially active → speech & response possible. This 'twilight state' may reduce deliberate deception.",
0.3, 4.08, 9.4, 0.85, C.lpurp, C.purple, C.dark
);
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 6 — NARCOANALYSIS: PROCEDURE FLOWCHART
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Q123: Narcoanalysis — Procedure (Linear Flowchart)", "Step-by-step process", C.blue);
addFooter(s, 6);
const fcSteps = [
["1. COURT ORDER", "Obtain judicial court order — voluntary/forced both require it", C.lred],
["2. TEAM", "Anaesthesiologist + Forensic Expert + Investigator present", C.lBlue],
["3. DRUG", "Sodium Pentothal IV — titrate to achieve hypnotic (twilight) state", C.lpurp],
["4. INTERVIEW", "Questions asked while subject is in semi-conscious state", C.lgreen],
["5. RECORDING", "Entire session audio + video recorded", C.yellow],
["6. ANALYSIS", "Experts analyse responses for forensic value", C.lOrange],
["7. REPORT", "Report submitted to court as investigative aid ONLY", C.lred],
];
// Two columns of flowchart
fcSteps.forEach(([label, desc, fill], i) => {
const col = i < 4 ? 0 : 1;
const row = i < 4 ? i : i - 4;
const bx = col === 0 ? 0.3 : 5.1;
const by = 1.28 + row * 0.98;
s.addShape(pres.ShapeType.roundRect, {
x: bx, y: by, w: 4.5, h: 0.72,
fill: { color: fill }, line: { color: C.blue, width: 1.2 }, rectRadius: 0.08,
});
// Step number badge
s.addShape(pres.ShapeType.ellipse, { x: bx + 0.08, y: by + 0.18, w: 0.36, h: 0.36, fill: { color: C.blue }, line: { color: C.blue, width: 0 } });
s.addText(String(i + 1), { x: bx + 0.08, y: by + 0.18, w: 0.36, h: 0.36, fontSize: 9, bold: true, color: C.white, align: "center", valign: "middle" });
s.addText(label, { x: bx + 0.52, y: by + 0.04, w: 3.9, h: 0.28, fontSize: 9.5, bold: true, color: C.blue, fontFace: "Calibri" });
s.addText(desc, { x: bx + 0.52, y: by + 0.3, w: 3.9, h: 0.38, fontSize: 8.5, color: C.dark, fontFace: "Calibri", wrap: true });
// Arrow down (within same column)
if ((col === 0 && i < 3) || (col === 1 && i < 6)) {
s.addShape(pres.ShapeType.line, {
x: bx + 2.25, y: by + 0.72, w: 0, h: 0.22,
line: { color: C.blue, width: 1.5 },
});
}
});
// Cross-column arrow at bottom of col 0
s.addShape(pres.ShapeType.line, { x: 2.55, y: 5.0, w: 2.55, h: 0, line: { color: C.accent, width: 1.5 } });
s.addText("→ continues", { x: 2.6, y: 4.95, w: 2, h: 0.22, fontSize: 8, color: C.accent, italic: true });
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 7 — NARCOANALYSIS: LEGAL & BRANCHING
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Q123: Narcoanalysis — Legal Status & Admissibility", "Selvi vs Karnataka 2010 | Supreme Court", C.blue);
addFooter(s, 7);
// Selvi box
s.addShape(pres.ShapeType.roundRect, {
x: 0.3, y: 1.2, w: 9.4, h: 0.85,
fill: { color: C.lred }, line: { color: C.accent, width: 2 }, rectRadius: 0.1,
});
s.addText("⚖ Selvi & Others vs State of Karnataka (2010) — Supreme Court of India", {
x: 0.5, y: 1.22, w: 9, h: 0.36, fontSize: 11, bold: true, color: C.accent,
});
s.addText("Compulsory narcoanalysis violates Article 20(3) — Right against self-incrimination & Article 21 — Right to life and personal liberty.", {
x: 0.5, y: 1.57, w: 9, h: 0.42, fontSize: 10, color: C.dark, wrap: true,
});
// BRANCHING FLOWCHART — manual
// Diamond shape (using rotated square visual with text)
s.addText("BRANCHING FLOWCHART: Is Narcoanalysis Admissible?", {
x: 0.3, y: 2.18, w: 9.4, h: 0.3, fontSize: 10.5, bold: true, color: C.navy, align: "center",
});
// Decision diamond
s.addShape(pres.ShapeType.diamond, {
x: 3.5, y: 2.55, w: 3.0, h: 0.9,
fill: { color: C.yellow }, line: { color: C.orange, width: 1.5 },
});
s.addText("Accused gives\nVOLUNTARY consent?", {
x: 3.5, y: 2.55, w: 3.0, h: 0.9, fontSize: 9, bold: true, color: C.dark, align: "center", valign: "middle",
});
// YES branch (right)
s.addShape(pres.ShapeType.line, { x: 6.5, y: 3.0, w: 1.5, h: 0, line: { color: C.green, width: 1.5 } });
s.addText("YES ✓", { x: 6.52, y: 2.78, w: 1.0, h: 0.22, fontSize: 9, bold: true, color: C.green });
s.addShape(pres.ShapeType.roundRect, { x: 8.0, y: 2.72, w: 1.7, h: 0.58, fill: { color: C.lgreen }, line: { color: C.green, width: 1 }, rectRadius: 0.06 });
s.addText("Test CAN\nbe done", { x: 8.0, y: 2.72, w: 1.7, h: 0.58, fontSize: 9, bold: true, color: C.green, align: "center", valign: "middle" });
// Arrow down
s.addShape(pres.ShapeType.line, { x: 8.85, y: 3.3, w: 0, h: 0.35, line: { color: C.green, width: 1.2 } });
s.addShape(pres.ShapeType.roundRect, { x: 8.0, y: 3.65, w: 1.7, h: 0.7, fill: { color: C.lgreen }, line: { color: C.green, width: 1 }, rectRadius: 0.06 });
s.addText("Investigative\nleads ONLY\n(NOT direct evidence)", { x: 8.0, y: 3.65, w: 1.7, h: 0.7, fontSize: 8, color: C.dark, align: "center", valign: "middle" });
// NO branch (left)
s.addShape(pres.ShapeType.line, { x: 2.0, y: 3.0, w: 1.5, h: 0, line: { color: C.accent, width: 1.5 } });
s.addText("NO ✗", { x: 2.05, y: 2.78, w: 1.0, h: 0.22, fontSize: 9, bold: true, color: C.accent });
s.addShape(pres.ShapeType.roundRect, { x: 0.3, y: 2.72, w: 1.7, h: 0.58, fill: { color: C.lred }, line: { color: C.accent, width: 1 }, rectRadius: 0.06 });
s.addText("CANNOT\nbe forced", { x: 0.3, y: 2.72, w: 1.7, h: 0.58, fontSize: 9, bold: true, color: C.accent, align: "center", valign: "middle" });
s.addShape(pres.ShapeType.line, { x: 1.15, y: 3.3, w: 0, h: 0.35, line: { color: C.accent, width: 1.2 } });
s.addShape(pres.ShapeType.roundRect, { x: 0.3, y: 3.65, w: 1.7, h: 0.7, fill: { color: C.lred }, line: { color: C.accent, width: 1 }, rectRadius: 0.06 });
s.addText("Constitutional\nViolation\n(Art 20(3) + 21)", { x: 0.3, y: 3.65, w: 1.7, h: 0.7, fontSize: 8, color: C.dark, align: "center", valign: "middle" });
// Limitations
s.addText("Limitations:", { x: 0.3, y: 4.48, w: 2, h: 0.28, fontSize: 10, bold: true, color: C.navy });
const lims = ["Results unreliable — subject may confabulate", "Examiner can inadvertently plant ideas", "Tolerance in addicts alters effect", "Risk: respiratory depression at high doses"];
s.addText(lims.map(l => "• " + l).join(" | "), {
x: 0.3, y: 4.76, w: 9.4, h: 0.52, fontSize: 9, color: C.dark, wrap: true, fontFace: "Calibri",
});
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 8 — NARCOANALYSIS vs POLYGRAPH vs BRAIN MAPPING
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Q123: Narcoanalysis vs Polygraph vs Brain Mapping", "All 3 require CONSENT — None are direct evidence", C.blue);
addFooter(s, 8);
addTable(s,
["Feature", "Narcoanalysis", "Polygraph (Lie Detector)", "Brain Mapping (BEOS/P300)"],
[
["Principle", "Drug-induced semi-consciousness", "Measures physiological responses to lies", "EEG detects brain response to familiar stimuli"],
["Drug Used", "Sodium Pentothal / Amytal", "None", "None"],
["Type", "Chemical", "Instrumental", "Neuro-imaging"],
["Consent Required", "YES (mandatory)", "YES", "YES"],
["Admissibility", "NOT direct evidence", "NOT direct evidence", "NOT direct evidence"],
["Reliability", "Low (confabulation risk)", "Moderate", "Higher"],
["Legal basis", "Selvi 2010 (SC)", "Selvi 2010 (SC)", "Selvi 2010 (SC)"],
],
0.3, 1.22, 9.4
);
addCallout(s,
"★ REMEMBER: The Selvi vs Karnataka 2010 Supreme Court ruling covers ALL THREE — Narcoanalysis + Polygraph + Brain Mapping. All require CONSENT. None can be used as direct evidence.",
0.3, 4.62, 9.4, 0.65, C.yellow, C.orange, C.dark
);
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 9 — SOLVENT ABUSE: DEFINITION & TYPES
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Q124: SOLVENT ABUSE — Definition & Classification", "Inhalant / Volatile Substance Abuse | VSA", C.purple);
addFooter(s, 9);
addCallout(s,
"DEFINITION: Solvent abuse (Inhalant abuse / VSA) = deliberate inhalation of volatile chemical substances to achieve a psychoactive/euphoric effect. Most common in ADOLESCENTS & STREET CHILDREN — cheap and easily available.",
0.3, 1.2, 9.4, 0.82, C.lpurp, C.purple, C.dark
);
addTable(s,
["Category", "Examples", "Common Sources", "Key Toxin"],
[
["Volatile Solvents", "Toluene, benzene, hexane, acetone", "Glue, paint thinner, marker pens, nail polish", "Toluene / Benzene"],
["Aerosols", "Fluorocarbons, propellants", "Spray paint, hair spray, deodorant cans", "Fluorocarbons"],
["Gases", "Butane, propane, nitrous oxide", "Lighter refills, whipped cream canisters", "Butane"],
["Nitrites (Poppers)", "Amyl nitrite, butyl nitrite", "Room deodorizers, 'poppers'", "Amyl nitrite"],
],
0.3, 2.12, 9.4
);
// Methods
s.addText("Methods of Inhalation:", { x: 0.3, y: 3.82, w: 3, h: 0.32, fontSize: 10.5, bold: true, color: C.purple });
const methods = [
["SNIFFING", "Directly inhale from container", C.lpurp],
["HUFFING", "Soaked cloth over mouth/nose", C.lBlue],
["BAGGING ☠", "Breathe in/out from bag — MOST DANGEROUS (hypoxia + rebreathing)", C.lred],
];
methods.forEach(([m, desc, col], i) => {
s.addShape(pres.ShapeType.roundRect, { x: 0.3 + i * 3.2, y: 4.18, w: 3.0, h: 0.88, fill: { color: col }, line: { color: C.purple, width: 1 }, rectRadius: 0.08 });
s.addText(m, { x: 0.3 + i * 3.2, y: 4.2, w: 3.0, h: 0.3, fontSize: 10, bold: true, color: C.purple, align: "center" });
s.addText(desc, { x: 0.4 + i * 3.2, y: 4.52, w: 2.8, h: 0.5, fontSize: 8.5, color: C.dark, align: "center", wrap: true });
});
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 10 — SOLVENT ABUSE: EFFECTS TABLE
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Q124: Solvent Abuse — Effects on Body", "Acute vs Chronic | Sudden Sniffing Death", C.purple);
addFooter(s, 10);
addTable(s,
["System", "ACUTE Effects", "CHRONIC Effects"],
[
["CNS", "Euphoria, dizziness, hallucinations, ataxia", "Dementia, cerebellar ataxia, neuropathy, leukoencephalopathy"],
["Cardiovascular ★", "Arrhythmias → SUDDEN SNIFFING DEATH", "Cardiomyopathy"],
["Renal", "Haematuria", "Renal tubular acidosis (Toluene)"],
["Hepatic", "Nausea/vomiting", "Hepatotoxicity (Benzene)"],
["Haematological ★", "—", "APLASTIC ANAEMIA + Leukaemia (Benzene)"],
["Respiratory", "Bronchospasm", "Pulmonary hypertension"],
["Psychological", "Disinhibition, euphoria", "Depression, personality change, addiction"],
],
0.3, 1.22, 9.4
);
// Two highlight boxes
s.addShape(pres.ShapeType.roundRect, {
x: 0.3, y: 4.28, w: 4.55, h: 0.98, fill: { color: C.lred }, line: { color: C.accent, width: 2 }, rectRadius: 0.1,
});
s.addText("☠ SUDDEN SNIFFING DEATH", { x: 0.4, y: 4.3, w: 4.3, h: 0.3, fontSize: 10, bold: true, color: C.accent });
s.addText("Mechanism: Cardiac arrhythmia (VF) due to sensitization of myocardium to catecholamines by fluorocarbons/hydrocarbons. Occurs even on FIRST USE!", {
x: 0.4, y: 4.6, w: 4.3, h: 0.6, fontSize: 8.5, color: C.dark, wrap: true,
});
s.addShape(pres.ShapeType.roundRect, {
x: 5.15, y: 4.28, w: 4.55, h: 0.98, fill: { color: C.yellow }, line: { color: C.orange, width: 2 }, rectRadius: 0.1,
});
s.addText("★ KEY SPECIFIC TOXINS", { x: 5.25, y: 4.3, w: 4.3, h: 0.3, fontSize: 10, bold: true, color: C.orange });
s.addText("BENZENE → Aplastic anaemia + Leukaemia (bone marrow)\nTOLUENE → Renal tubular acidosis\nFLUOROCARBONS → Sudden Sniffing Death (VF)", {
x: 5.25, y: 4.6, w: 4.3, h: 0.6, fontSize: 8.5, color: C.dark, wrap: true,
});
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 11 — SOLVENT ABUSE: BRANCHING FLOWCHART (Acute vs Chronic)
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Q124: Solvent Abuse — Outcome Branching Flowchart", "Acute vs Chronic pathway", C.purple);
addFooter(s, 11);
// Start box
fcBox(s, "SOLVENT INHALED", 3.5, 1.2, 3.0, 0.55, C.lpurp, C.dark);
s.addShape(pres.ShapeType.line, { x: 5.0, y: 1.75, w: 0, h: 0.35, line: { color: C.purple, width: 1.5 } });
// Decision
s.addShape(pres.ShapeType.diamond, {
x: 3.1, y: 2.1, w: 3.8, h: 0.95,
fill: { color: C.yellow }, line: { color: C.orange, width: 1.5 },
});
s.addText("Single/Occasional\nuse or Chronic?", { x: 3.1, y: 2.1, w: 3.8, h: 0.95, fontSize: 9.5, bold: true, color: C.dark, align: "center", valign: "middle" });
// Left: Single/Acute
s.addShape(pres.ShapeType.line, { x: 1.5, y: 2.57, w: 1.6, h: 0, line: { color: C.blue, width: 1.5 } });
s.addText("ACUTE", { x: 1.55, y: 2.35, w: 1.3, h: 0.25, fontSize: 9, bold: true, color: C.blue });
const acuteSteps = ["Euphoria, dizziness", "Hallucinations, ataxia", "Arrhythmia risk"];
acuteSteps.forEach((t, i) => {
fcBox(s, t, 0.2, 2.72 + i * 0.7, 2.8, 0.52, C.lBlue, C.dark);
if (i < acuteSteps.length - 1)
s.addShape(pres.ShapeType.line, { x: 1.6, y: 3.24 + i * 0.7, w: 0, h: 0.18, line: { color: C.blue, width: 1.2 } });
});
fcBox(s, "Usually RECOVERS\n(if exposure stops)", 0.2, 4.82, 2.8, 0.52, C.lgreen, C.green);
// Right: Chronic
s.addShape(pres.ShapeType.line, { x: 6.9, y: 2.57, w: 1.6, h: 0, line: { color: C.accent, width: 1.5 } });
s.addText("CHRONIC", { x: 7.05, y: 2.35, w: 1.3, h: 0.25, fontSize: 9, bold: true, color: C.accent });
const chronSteps = ["White matter damage", "Dementia, ataxia", "Organ failure"];
chronSteps.forEach((t, i) => {
fcBox(s, t, 7.0, 2.72 + i * 0.7, 2.8, 0.52, C.lred, C.dark);
if (i < chronSteps.length - 1)
s.addShape(pres.ShapeType.line, { x: 8.4, y: 3.24 + i * 0.7, w: 0, h: 0.18, line: { color: C.accent, width: 1.2 } });
});
fcBox(s, "IRREVERSIBLE damage\n(Dementia, Aplastic anaemia)", 7.0, 4.82, 2.8, 0.52, C.lred, C.accent);
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 12 — DRUG ADDICTION vs HABITUATION: DEFINITIONS
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Q133: Drug Addiction vs Drug Habituation", "WHO Definitions | Key Distinction", C.teal);
addFooter(s, 12);
// ADDICTION box
s.addShape(pres.ShapeType.roundRect, { x: 0.3, y: 1.2, w: 4.45, h: 2.1, fill: { color: C.lred }, line: { color: C.accent, width: 2 }, rectRadius: 0.1 });
s.addText("DRUG ADDICTION (WHO)", { x: 0.4, y: 1.24, w: 4.2, h: 0.36, fontSize: 11, bold: true, color: C.accent });
s.addText([
{ text: "• ", options: {} },
{ text: "COMPULSION", options: { bold: true } },
{ text: " to continue (cannot stop)\n", options: {} },
{ text: "• Strong tendency to ", options: {} },
{ text: "INCREASE dose\n", options: { bold: true } },
{ text: "• Physical + Psychological dependence\n", options: {} },
{ text: "• Detrimental to ", options: {} },
{ text: "INDIVIDUAL & SOCIETY", options: { bold: true } },
], { x: 0.4, y: 1.62, w: 4.2, h: 1.6, fontSize: 10, color: C.dark, fontFace: "Calibri", wrap: true });
// HABITUATION box
s.addShape(pres.ShapeType.roundRect, { x: 5.25, y: 1.2, w: 4.45, h: 2.1, fill: { color: C.lgreen }, line: { color: C.green, width: 2 }, rectRadius: 0.1 });
s.addText("DRUG HABITUATION (WHO)", { x: 5.35, y: 1.24, w: 4.2, h: 0.36, fontSize: 11, bold: true, color: C.green });
s.addText([
{ text: "• ", options: {} },
{ text: "DESIRE", options: { bold: true } },
{ text: " to continue (not compulsion)\n", options: {} },
{ text: "• Little/no tendency to increase dose\n", options: {} },
{ text: "• ", options: {} },
{ text: "Only psychological", options: { bold: true } },
{ text: " dependence\n", options: {} },
{ text: "• Detrimental mainly to ", options: {} },
{ text: "INDIVIDUAL only", options: { bold: true } },
], { x: 5.35, y: 1.62, w: 4.2, h: 1.6, fontSize: 10, color: C.dark, fontFace: "Calibri", wrap: true });
// vs label
s.addShape(pres.ShapeType.ellipse, { x: 4.55, y: 1.9, w: 0.9, h: 0.9, fill: { color: C.navy }, line: { color: C.gold, width: 2 } });
s.addText("VS", { x: 4.55, y: 1.9, w: 0.9, h: 0.9, fontSize: 16, bold: true, color: C.gold, align: "center", valign: "middle" });
// WHO 1964 note
s.addShape(pres.ShapeType.roundRect, { x: 0.3, y: 3.42, w: 9.4, h: 0.75, fill: { color: C.lBlue }, line: { color: C.blue, width: 1.5 }, rectRadius: 0.08 });
s.addText("WHO 1964 UPDATE:", { x: 0.5, y: 3.45, w: 2, h: 0.3, fontSize: 10, bold: true, color: C.blue });
s.addText("WHO replaced both 'Addiction' and 'Habituation' with the single term 'DRUG DEPENDENCE' to avoid confusion. Divided into: Physical Dependence (withdrawal on stopping) + Psychological/Psychic Dependence (craving). OLD definitions still tested in exams!", {
x: 0.5, y: 3.72, w: 9.1, h: 0.4, fontSize: 9.5, color: C.dark, wrap: true,
});
// Examples row
s.addText("ADDICTION examples: Heroin, Morphine, Cocaine, Alcohol, Amphetamine", {
x: 0.3, y: 4.28, w: 4.45, h: 0.35, fontSize: 9.5, bold: true, color: C.accent, fontFace: "Calibri",
});
s.addText("HABITUATION examples: Tobacco (nicotine), Caffeine, Cannabis (mild), LSD", {
x: 5.25, y: 4.28, w: 4.45, h: 0.35, fontSize: 9.5, bold: true, color: C.green, fontFace: "Calibri",
});
addCallout(s,
"KEY: Physical Dependence = ABCOS = Alcohol, Barbiturates, Cannabis (mild), Opioids, Sedative-hypnotics",
0.3, 4.72, 9.4, 0.55, C.yellow, C.orange, C.dark
);
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 13 — ADDICTION vs HABITUATION: COMPARISON TABLE
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Q133: Addiction vs Habituation — Full Comparison", "Most High-Yield Table in Chapter 9", C.teal);
addFooter(s, 13);
addTable(s,
["Feature", "ADDICTION", "HABITUATION"],
[
["Compulsion", "YES — overpowering compulsion", "NO — only desire/wish"],
["Dose tendency", "Strong tendency to INCREASE", "Little/NO tendency to increase"],
["Physical dependence", "YES — present", "NO — absent"],
["Psychological dependence", "YES — strong", "YES — mild/moderate"],
["Tolerance", "YES — develops", "Minimal"],
["Withdrawal syndrome", "YES — severe (physical Sx)", "NO (or very mild psychological Sx)"],
["Harm to society", "YES — significant (crime/violence)", "NO — mainly individual"],
["Detrimental effect", "Individual AND Society", "INDIVIDUAL only"],
["Examples", "Heroin, Morphine, Cocaine, Alcohol", "Tobacco, Caffeine, Cannabis (mild)"],
],
0.3, 1.22, 9.4
);
addCallout(s,
"★ ONE-LINE DIFFERENCE: Addiction = COMPULSION + Physical dependence + Social harm. Habituation = DESIRE only + No physical dependence + Individual harm only.",
0.3, 4.72, 9.4, 0.55, C.yellow, C.orange, C.dark
);
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 14 — WITHDRAWAL SYNDROMES TABLE
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Q133: Withdrawal Syndromes — Drug by Drug", "Cold Turkey | DTs | Crash", C.teal);
addFooter(s, 14);
addTable(s,
["Drug", "Key Withdrawal Features", "Onset", "Duration"],
[
["Heroin/Morphine\n(Opioids) ★", "Yawning, lacrimation, rhinorrhoea, gooseflesh (COLD TURKEY), muscle cramps, diarrhoea, insomnia", "6–24 hrs", "7–10 days"],
["Alcohol ★★\n(MOST DANGEROUS)", "Tremors, sweating, tachycardia → DELIRIUM TREMENS (DTs): seizures, hallucinations, autonomic instability", "6–24 hrs", "3–7 days"],
["Benzodiazepines", "Anxiety, insomnia, seizures (similar to alcohol)", "1–3 days (long-acting)", "Weeks"],
["Cocaine", "Depression, fatigue, hypersomnia, increased appetite ('CRASH')", "Hours", "Days–weeks"],
["Nicotine", "Irritability, difficulty concentrating, increased appetite", "Hours", "Weeks"],
["Cannabis", "Irritability, insomnia, decreased appetite (mild)", "1–3 days", "1–2 weeks"],
],
0.3, 1.22, 9.4
);
// Two key boxes
s.addShape(pres.ShapeType.roundRect, { x: 0.3, y: 4.28, w: 4.5, h: 0.98, fill: { color: C.lred }, line: { color: C.accent, width: 2 }, rectRadius: 0.1 });
s.addText("COLD TURKEY = OPIOID withdrawal", { x: 0.45, y: 4.3, w: 4.2, h: 0.3, fontSize: 10, bold: true, color: C.accent });
s.addText("Goosebumps (piloerection) look like plucked turkey skin. Signs: rhinorrhoea, lacrimation, yawning, muscle cramps.", {
x: 0.45, y: 4.6, w: 4.2, h: 0.62, fontSize: 8.5, color: C.dark, wrap: true,
});
s.addShape(pres.ShapeType.roundRect, { x: 5.2, y: 4.28, w: 4.5, h: 0.98, fill: { color: C.yellow }, line: { color: C.orange, width: 2 }, rectRadius: 0.1 });
s.addText("DTs = ALCOHOL withdrawal (most dangerous)", { x: 5.35, y: 4.3, w: 4.2, h: 0.3, fontSize: 10, bold: true, color: C.orange });
s.addText("Delirium Tremens: seizures + autonomic instability + hallucinations. Can be FATAL. Treat with benzodiazepines.", {
x: 5.35, y: 4.6, w: 4.2, h: 0.62, fontSize: 8.5, color: C.dark, wrap: true,
});
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 15 — ADDICTION BRANCHING FLOWCHART
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Q133: Is It Addiction or Habituation? — Branching Flow", "Decision tree", C.teal);
addFooter(s, 15);
// Start
fcBox(s, "Drug Use Reported", 3.5, 1.15, 3.0, 0.55, C.lgray, C.dark);
s.addShape(pres.ShapeType.line, { x: 5.0, y: 1.7, w: 0, h: 0.32, line: { color: C.teal, width: 1.5 } });
// Q1
s.addShape(pres.ShapeType.diamond, { x: 3.1, y: 2.02, w: 3.8, h: 0.9, fill: { color: C.yellow }, line: { color: C.orange, width: 1.5 } });
s.addText("Physical withdrawal\nsymptoms present?", { x: 3.1, y: 2.02, w: 3.8, h: 0.9, fontSize: 9.5, bold: true, color: C.dark, align: "center", valign: "middle" });
// YES (right)
s.addShape(pres.ShapeType.line, { x: 6.9, y: 2.47, w: 1.3, h: 0, line: { color: C.accent, width: 1.5 } });
s.addText("YES", { x: 6.95, y: 2.26, w: 0.8, h: 0.25, fontSize: 9, bold: true, color: C.accent });
s.addShape(pres.ShapeType.diamond, { x: 7.2, y: 2.86, w: 2.5, h: 0.8, fill: { color: C.lOrange }, line: { color: C.orange, width: 1.2 } });
s.addText("Dose\nescalation?", { x: 7.2, y: 2.86, w: 2.5, h: 0.8, fontSize: 9, bold: true, color: C.dark, align: "center", valign: "middle" });
s.addShape(pres.ShapeType.line, { x: 8.45, y: 3.66, w: 0, h: 0.35, line: { color: C.accent, width: 1.2 } });
fcBox(s, "ADDICTION\n(Physical + Psych dependence)", 7.15, 4.01, 2.55, 0.75, C.lred, C.accent);
// NO (left)
s.addShape(pres.ShapeType.line, { x: 1.8, y: 2.47, w: 1.3, h: 0, line: { color: C.green, width: 1.5 } });
s.addText("NO", { x: 1.9, y: 2.26, w: 0.8, h: 0.25, fontSize: 9, bold: true, color: C.green });
s.addShape(pres.ShapeType.diamond, { x: 0.3, y: 2.86, w: 2.5, h: 0.8, fill: { color: C.lgreen }, line: { color: C.green, width: 1.2 } });
s.addText("Compulsion\nto use?", { x: 0.3, y: 2.86, w: 2.5, h: 0.8, fontSize: 9, bold: true, color: C.dark, align: "center", valign: "middle" });
s.addShape(pres.ShapeType.line, { x: 1.55, y: 3.66, w: 0, h: 0.35, line: { color: C.green, width: 1.2 } });
fcBox(s, "HABITUATION\n(Only Psych dependence)", 0.28, 4.01, 2.55, 0.75, C.lgreen, C.green);
// Center result — tolerance
fcBox(s, "Assess TOLERANCE\n(dose needed increasing?)", 3.4, 3.85, 3.2, 0.7, C.lpurp, C.purple);
s.addShape(pres.ShapeType.line, { x: 5.0, y: 2.92, w: 0, h: 0.93, line: { color: C.purple, width: 1.2 } });
addCallout(s,
"Tolerance = same dose produces diminishing effect OR larger doses needed for same effect. Types: Pharmacokinetic | Pharmacodynamic | Cross-tolerance.",
0.3, 4.9, 9.4, 0.48, C.lBlue, C.blue, C.dark
);
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 16 — FULL DRUG REFERENCE TABLE
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.offWhite } });
addHeader(s, "Chapter 9 — All Drugs Quick Reference Table", "Source | Active Principle | Dependence | NDPS", C.navy);
addFooter(s, 16);
addTable(s,
["Drug / Substance", "Source", "Active Principle", "Dependence Type", "NDPS?"],
[
["Cannabis (Ganja)", "Cannabis sativa", "Δ9-THC", "Habituation → Addiction", "YES"],
["Heroin", "Semisynthetic (morphine)", "Diacetylmorphine", "Strong ADDICTION", "YES"],
["Cocaine", "Erythroxylum coca", "Cocaine alkaloid", "ADDICTION", "YES"],
["Alcohol", "Fermentation", "Ethanol", "ADDICTION (physical)", "NO"],
["Tobacco", "Nicotiana tabacum", "Nicotine", "Habituation → Addiction", "NO"],
["Solvents (toluene)", "Industrial chemicals", "Toluene / Benzene", "Habituation", "NO"],
["LSD", "Ergot fungus (semisynthetic)", "Lysergic acid diethylamide", "Habituation", "YES"],
["Amphetamine", "Synthetic", "Amphetamine", "ADDICTION", "YES"],
],
0.3, 1.22, 9.4
);
addCallout(s,
"★ NDPS Act 1985 = Narcotic Drugs and Psychotropic Substances Act (India). Governs possession, sale, production of all scheduled narcotic & psychotropic substances.",
0.3, 4.78, 9.4, 0.52, C.yellow, C.orange, C.dark
);
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 17 — HIGH-YIELD POINTS & MNEMONICS
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.dark } });
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 0.18, h: 5.63, fill: { color: C.gold } });
addHeader(s, "HIGH-YIELD POINTS & MNEMONICS", "Remember these for your exam!", C.dark);
const pts = [
["★", "B-G-C-H order = increasing potency: Bhang → Ganja → Charas → Hashish Oil", C.gold],
["⚖", "Narco drug = Sodium PENTOTHAL (ultra-short barbiturate) IV slow", C.lBlue],
["⚖", "Selvi 2010: ALL 3 (Narco + Polygraph + Brain mapping) need CONSENT", C.lred],
["☠", "Sudden Sniffing Death = VF (ventricular fibrillation) — can occur on 1st use!", C.lred],
["🧪", "BENZENE → Aplastic anaemia + Leukaemia | TOLUENE → Renal tubular acidosis", C.yellow],
["💊", "Addiction = Compulsion + Physical dependence + Social harm", C.lgreen],
["💊", "Habituation = Desire only + No physical dependence + Individual harm", C.lgreen],
["🥶", "COLD TURKEY = Opioid withdrawal | DTs = Alcohol withdrawal (most dangerous)", C.lOrange],
["📅", "WHO 1964: Replaced both terms with 'DRUG DEPENDENCE'", C.lpurp],
["🕐", "THC in urine: 3–30 days | Hair: up to 90 days (lipid soluble)", C.lBlue],
];
pts.forEach(([icon, text, col], i) => {
const col_idx = i % 2;
const row = Math.floor(i / 2);
const bx = col_idx === 0 ? 0.25 : 5.1;
const by = 1.25 + row * 0.95;
s.addShape(pres.ShapeType.roundRect, {
x: bx, y: by, w: 4.65, h: 0.78,
fill: { color: "1A2E4A" }, line: { color: col.replace("#","") || C.gold, width: 1 }, rectRadius: 0.08,
});
s.addText(icon, { x: bx + 0.08, y: by + 0.18, w: 0.4, h: 0.4, fontSize: 15, color: col || C.white });
s.addText(text, { x: bx + 0.55, y: by + 0.08, w: 4.05, h: 0.62, fontSize: 9, color: C.white, wrap: true, fontFace: "Calibri" });
});
addFooter(s, 17);
}
// ════════════════════════════════════════════════════════════════════════════
// SLIDE 18 — THANK YOU / END
// ════════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 10, h: 5.63, fill: { color: C.dark } });
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 0.18, h: 5.63, fill: { color: C.accent } });
s.addShape(pres.ShapeType.line, { x: 0.5, y: 3.2, w: 9.0, h: 0, line: { color: C.gold, width: 1 } });
s.addText("CHAPTER 9 COMPLETE", { x: 0.5, y: 1.4, w: 9, h: 0.6, fontSize: 28, bold: true, color: C.white, align: "center" });
s.addText("Narcotic & Substance Abuse", { x: 0.5, y: 2.05, w: 9, h: 0.45, fontSize: 16, color: C.gold, align: "center", italic: true });
s.addText("Cannabis | Narcoanalysis | Solvent Abuse | Addiction vs Habituation", { x: 0.5, y: 2.55, w: 9, h: 0.35, fontSize: 11, color: C.mgray, align: "center" });
s.addText("Key Takeaways:", { x: 2.0, y: 3.4, w: 6, h: 0.38, fontSize: 13, bold: true, color: C.gold, align: "center" });
const keys = ["B-G-C-H potency order", "Sodium Pentothal for Narco", "Selvi 2010 = Consent mandatory", "Physical dependence = ADDICTION"];
keys.forEach((k, i) => {
s.addShape(pres.ShapeType.roundRect, { x: 0.3 + i * 2.38, y: 3.82, w: 2.18, h: 0.62, fill: { color: C.navy }, line: { color: C.accent, width: 1 }, rectRadius: 0.08 });
s.addText("✓ " + k, { x: 0.38 + i * 2.38, y: 3.85, w: 2.02, h: 0.56, fontSize: 8.5, color: C.white, wrap: true, fontFace: "Calibri" });
});
s.addText("Forensic Medicine & Toxicology | MBBS Exam Preparation", {
x: 0.5, y: 5.0, w: 9, h: 0.35, fontSize: 9, color: C.mgray, align: "center",
});
}
// ── WRITE FILE ────────────────────────────────────────────────────────────────
pres.writeFile({ fileName: "/home/daytona/workspace/chapter9-narcotic/Chapter9_Narcotic_Substance_Abuse.pptx" })
.then(() => console.log("✅ PPT created: Chapter9_Narcotic_Substance_Abuse.pptx"))
.catch(e => { console.error("ERROR:", e); process.exit(1); });
cd /home/daytona/workspace/chapter9-narcotic && node chapter9.js 2>&1
node -e "const p = require('pptxgenjs'); const pr = new p(); console.log(Object.…
node -e "const p = require('pptxgenjs'); const pr = new p(); console.log(Object.…
node -e " const p = require('pptxgenjs'); const pr = new p(); const s = pr.add…
cd /home/daytona/workspace/chapter9-narcotic && sed -i 's/pres\.ShapeType\.line/…
python3 -c " content = open('/home/daytona/workspace/chapter9-narcotic/chapter9.…
cd /home/daytona/workspace/chapter9-narcotic && node chapter9.js 2>&1
Chapter9 Narcotic Substance Abuse
Presentation · PPTX
| Slide | Content |
|---|---|
| 1 | Cover slide with dark theme + stat badges |
| 2 | Table of Contents |
| 3 | Q116 - Cannabis intro, plant parts, linear flowchart (preparation steps) |
| 4 | Q116 - Cannabis products comparison table (Bhang/Ganja/Charas/Hashish Oil) + mnemonic highlight |
| 5 | Q123 - Narcoanalysis definition, drugs table, principle box |
| 6 | Q123 - Linear flowchart of procedure (7 steps, 2-column layout) |
| 7 | Q123 - Branching flowchart (Consent? → YES/NO paths) + legal highlights |
| 8 | Q123 - Narcoanalysis vs Polygraph vs Brain Mapping comparison table |
| 9 | Q124 - Solvent abuse definition, classification table, methods (Sniffing/Huffing/Bagging) |
| 10 | Q124 - Effects table (Acute vs Chronic) + Sudden Sniffing Death box + Benzene/Toluene highlights |
| 11 | Q124 - Branching flowchart (Acute vs Chronic outcome pathway) |
| 12 | Q133 - Addiction vs Habituation definitions (side-by-side boxes) + WHO 1964 note |
| 13 | Q133 - Full comparison table (9 features) |
| 14 | Q133 - Withdrawal syndromes table + Cold Turkey vs DTs callout boxes |
| 15 | Q133 - Branching flowchart (Addiction or Habituation decision tree) |
| 16 | All drugs quick reference table |
| 17 | High-yield points & mnemonics (dark theme, 10 points) |
| 18 | Summary end slide |
Now make ppt and pdf for chapter 10 use less colour
mkdir -p /home/daytona/workspace/chapter10 && echo "done"
~/chapter10/chapter10_ppt.js
const pptxgen = require("pptxgenjs");
const pres = new pptxgen();
pres.layout = "LAYOUT_16x9";
pres.title = "Chapter 10: Reproductive Forensics, Sexual Offences & MTP Act";
// ── MINIMAL COLOUR PALETTE (2-3 colours only) ─────────────────────────────
const C = {
black: "1A1A1A",
darkG: "2C3E50",
mid: "5D6D7E",
light: "BDC3C7",
offW: "F5F5F5",
white: "FFFFFF",
accent: "2E4057", // one dark blue-slate accent
hl: "D4AC0D", // single gold highlight
hlLight: "FEF9E7", // very light gold bg
stripe: "E8ECF0", // light grey stripe for tables
};
// ── HELPERS ───────────────────────────────────────────────────────────────
function hdr(s, title, sub) {
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:1.0, fill:{color:C.accent} });
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:0.15, h:1.0, fill:{color:C.hl} });
s.addText(title, { x:0.3, y:0.1, w:9.4, h:0.52, fontSize:20, bold:true, color:C.white, fontFace:"Calibri" });
if(sub) s.addText(sub, { x:0.3, y:0.62, w:9.4, h:0.3, fontSize:10, color:C.light, italic:true, fontFace:"Calibri" });
}
function ftr(s, n) {
s.addShape(pres.ShapeType.rect, { x:0, y:5.38, w:10, h:0.25, fill:{color:C.darkG} });
s.addText("Chapter 10: Reproductive Forensics, Sexual Offences & MTP Act | Forensic Medicine", {
x:0.2, y:5.39, w:8.5, h:0.2, fontSize:7, color:C.light });
s.addText(""+n, { x:9.6, y:5.39, w:0.3, h:0.2, fontSize:7, bold:true, color:C.hl, align:"right" });
}
function box(s, txt, x, y, w, h, bg, border) {
s.addShape(pres.ShapeType.roundRect, { x,y,w,h, fill:{color:bg||C.offW}, line:{color:border||C.accent,width:1.2}, rectRadius:0.07 });
s.addText(txt, { x:x+0.1, y:y+0.05, w:w-0.2, h:h-0.1, fontSize:9.5, color:C.black, fontFace:"Calibri", wrap:true, valign:"middle" });
}
function boldBox(s, txt, x, y, w, h) {
s.addShape(pres.ShapeType.roundRect, { x,y,w,h, fill:{color:C.hlLight}, line:{color:C.hl,width:1.5}, rectRadius:0.07 });
s.addText(txt, { x:x+0.12, y:y+0.06, w:w-0.24, h:h-0.12, fontSize:10, bold:true, color:C.darkG, fontFace:"Calibri", wrap:true, valign:"middle" });
}
function fcBox(s, txt, x, y, w, h) {
s.addShape(pres.ShapeType.roundRect, { x,y,w,h, fill:{color:C.stripe}, line:{color:C.accent,width:1}, rectRadius:0.07 });
s.addText(txt, { x:x+0.08, y, w:w-0.16, h, fontSize:9.5, bold:true, color:C.accent, align:"center", valign:"middle", fontFace:"Calibri", wrap:true });
}
function arrow(s, x, y) {
s.addShape("line", { x, y, w:0, h:0.2, line:{color:C.mid,width:1.5} });
s.addShape(pres.ShapeType.triangle, { x:x-0.08, y:y+0.18, w:0.16, h:0.12, fill:{color:C.mid}, line:{color:C.mid,width:0}, rotate:180 });
}
function tbl(s, headers, rows, x, y, w) {
const cw = headers.map(()=>w/headers.length);
const data = [
headers.map(h=>({ text:h, options:{ bold:true, color:C.white, fill:{color:C.accent}, fontSize:9.5, align:"center", fontFace:"Calibri", border:{pt:0.5,color:C.mid} }})),
...rows.map((r,i)=> r.map(c=>({ text:c, options:{ fontSize:9, color:C.black, fontFace:"Calibri", fill:{color: i%2===0 ? C.stripe : C.white}, border:{pt:0.5,color:C.light}, valign:"middle" }})))
];
s.addTable(data, { x, y, w, colW:cw, rowH:0.4 });
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 1 — COVER
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.accent} });
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:0.18, h:5.63, fill:{color:C.hl} });
s.addShape("line", { x:0.4, y:2.1, w:9.2, h:0, line:{color:C.hl,width:1} });
s.addShape("line", { x:0.4, y:3.85, w:9.2, h:0, line:{color:C.light,width:0.5} });
s.addText("FORENSIC MEDICINE & TOXICOLOGY", { x:0.4, y:1.4, w:9, h:0.42, fontSize:11, color:C.light, charSpacing:3, fontFace:"Calibri" });
s.addText("CHAPTER 10", { x:0.4, y:1.85, w:9, h:0.42, fontSize:16, bold:true, color:C.hl, fontFace:"Calibri" });
s.addText("REPRODUCTIVE FORENSICS,\nSEXUAL OFFENCES & MTP ACT", { x:0.4, y:2.18, w:9.2, h:1.5, fontSize:30, bold:true, color:C.white, fontFace:"Calibri", lineSpacingMultiple:1.1 });
s.addText("Abortion · Consent · Pregnancy Signs · Hymen · MTP Act · Intersex · Surrogacy", { x:0.4, y:3.9, w:9.2, h:0.38, fontSize:11, color:C.light, italic:true, fontFace:"Calibri" });
// stat row
const stats = [["14","Questions"],["Q27/52","Abortion"],["Q60/104","MTP Act"],["Q78","Hymen Types"]];
stats.forEach(([n,l],i)=>{
const bx = 0.4+i*2.38;
s.addShape(pres.ShapeType.roundRect, { x:bx, y:4.42, w:2.18, h:0.88, fill:{color:"1A2D40"}, line:{color:C.hl,width:1}, rectRadius:0.07 });
s.addText(n, { x:bx, y:4.44, w:2.18, h:0.42, fontSize:18, bold:true, color:C.white, align:"center" });
s.addText(l, { x:bx, y:4.84, w:2.18, h:0.28, fontSize:8.5, color:C.light, align:"center" });
});
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 2 — TABLE OF CONTENTS
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.offW} });
hdr(s,"TABLE OF CONTENTS","Chapter 10 — 14 Questions");
ftr(s,2);
const items = [
["01","Natural vs Criminal Abortion","Q27/52"],
["02","Unnatural Sexual Offences","Q39"],
["03","Signs of Pregnancy (Positive/Confirmatory)","Q56/68/164"],
["04","MTP Act 1971","Q60/104/152"],
["05","Stillborn vs Deadborn Fetus","Q74"],
["06","Types of Hymen","Q78"],
["07","True Virgin vs False Virgin","Q112"],
["08","Abortifacient Drugs","Q115"],
["09","Bestiality","Q149"],
["10","Impotency & Sterility in Males","Q165"],
["11","Signs of Liveborn Child","Q169"],
["12","Surrogacy & Intersex & Turner Syndrome","Q25/31/88"],
];
items.forEach(([num,title,q],i)=>{
const col = i%2===0 ? C.stripe : C.white;
const y = 1.1+i*0.36;
s.addShape(pres.ShapeType.roundRect, { x:0.3, y, w:9.4, h:0.3, fill:{color:col}, line:{color:C.light,width:0.5}, rectRadius:0.04 });
s.addShape(pres.ShapeType.rect, { x:0.3, y, w:0.4, h:0.3, fill:{color:C.accent}, line:{color:C.accent,width:0} });
s.addText(num, { x:0.3, y, w:0.4, h:0.3, fontSize:8.5, bold:true, color:C.white, align:"center", valign:"middle" });
s.addText(title, { x:0.82, y:y+0.04, w:7.2, h:0.22, fontSize:10, bold:true, color:C.darkG });
s.addShape(pres.ShapeType.roundRect, { x:8.5, y:y+0.04, w:1.1, h:0.22, fill:{color:C.hlLight}, line:{color:C.hl,width:0.7}, rectRadius:0.08 });
s.addText(q, { x:8.5, y:y+0.04, w:1.1, h:0.22, fontSize:7.5, bold:true, color:C.darkG, align:"center", valign:"middle" });
});
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 3 — NATURAL vs CRIMINAL ABORTION (Q27/52)
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.offW} });
hdr(s,"Q27/52: Natural vs Criminal Abortion","Definition | Differences | Medico-legal significance");
ftr(s,3);
box(s,"ABORTION = Expulsion of the products of conception before the fetus is viable (before 28 weeks / 500g in Indian law). After 28 wks = PREMATURE LABOUR.", 0.3,1.08,9.4,0.68, C.hlLight, C.hl);
tbl(s,
["Feature","Natural (Spontaneous) Abortion","Criminal Abortion"],
[
["Definition","Occurs without deliberate interference; due to natural causes","Induced deliberately to terminate pregnancy — UNLAWFUL"],
["Cause","Chromosomal defects, uterine anomaly, infection, hormonal","Mechanical/chemical methods used by unqualified persons"],
["Legal status","NOT a crime","CRIME under IPC Sec 312 (unless MTP Act)"],
["Signs","No signs of external injury","Signs of instrumentation, laceration, infection"],
["Post-mortem findings","No foreign material","Instruments, abortifacients may be found"],
["Medico-legal duty","No reporting needed","Must be reported; doctors duty to preserve evidence"],
],
0.3,1.88,9.4
);
boldBox(s,"IMP: IPC Sec 312 = causing miscarriage (criminal abortion). MTP Act 1971 provides LEGAL exceptions.", 0.3,4.68,9.4,0.58);
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 4 — UNNATURAL SEXUAL OFFENCES (Q39)
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.offW} });
hdr(s,"Q39: Unnatural Sexual Offences","IPC provisions | Classification");
ftr(s,4);
s.addText("Definition: Sexual acts considered unnatural / against the order of nature.", { x:0.3, y:1.1, w:9.4, h:0.32, fontSize:10.5, bold:true, color:C.darkG });
tbl(s,
["Offence","IPC Section","Description"],
[
["Sodomy (Buggery)","Sec 377 (now amended)","Penile penetration of anus — between male-male, male-female, or human-animal"],
["Bestiality","Sec 377","Sexual intercourse with an animal"],
["Tribadism","—","Vulvo-vulvar friction between females (lesbian act)"],
["Fellatio","—","Oral stimulation of male genitalia"],
["Cunnilingus","—","Oral stimulation of female genitalia"],
["Frotteurism","—","Rubbing against non-consenting person"],
["Exhibitionism","—","Indecent exposure of genitalia in public"],
],
0.3,1.5,9.4
);
box(s,"NOTE: IPC Sec 377 was partially read down by Supreme Court in Navtej Singh Johar vs UOI (2018) — consensual homosexual acts between adults are NO LONGER criminal. Non-consensual and acts with minors remain criminal.", 0.3,4.48,9.4,0.75, C.stripe, C.mid);
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 5 — SIGNS OF PREGNANCY (Q56/68/164)
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.offW} });
hdr(s,"Q56/68/164: Signs of Pregnancy — Positive / Confirmatory","Presumptive | Probable | Positive");
ftr(s,5);
tbl(s,
["Category","Signs","Reliability"],
[
["PRESUMPTIVE\n(Subjective)","Amenorrhoea, nausea/vomiting, breast changes, frequency of urination, quickening (fetal movement felt by mother 16–20 wks)","Least reliable — can occur in other conditions"],
["PROBABLE\n(Objective)","Uterine enlargement, Hegar's sign, Goodell's sign, Chadwick's sign, Ballottement, Braxton Hicks contractions, +ve pregnancy test (urine hCG)","More reliable but NOT conclusive"],
["POSITIVE\n(Confirmatory) ★","1. Fetal heart sounds (auscultation / Doppler)\n2. Fetal movements felt by EXAMINER\n3. Ultrasound (fetal parts visible)\n4. Fetal skeleton on X-ray\n5. Electrocardiography of fetus","CONCLUSIVE — cannot be mimicked"],
],
0.3,1.08,9.4
);
boldBox(s,"★ EXAM Q: POSITIVE (Confirmatory) signs — only 5: (1) FHS heard (2) Fetal movements felt by doctor (3) USG fetal parts (4) X-ray fetal skeleton (5) Fetal ECG", 0.3,3.82,9.4,0.65);
// Hegar/Goodell/Chadwick mini-table
tbl(s,
["Sign","What it is","Weeks"],
[
["Hegar's sign","Softening of lower uterine segment","6–8"],
["Goodell's sign","Softening of cervix","5–6"],
["Chadwick's sign","Bluish/violet discolouration of cervix & vagina","6–8"],
],
0.3,4.58,9.4
);
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 6 — MTP ACT (Q60/104/152)
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.offW} });
hdr(s,"Q60/104/152: MTP Act 1971 (Medical Termination of Pregnancy)","Amended 2021 | Legal abortion framework");
ftr(s,6);
box(s,"MTP Act 1971 (amended 2021): Provides legal provisions for TERMINATION of pregnancy under defined circumstances. Overrides IPC Sec 312.", 0.3,1.08,9.4,0.58, C.hlLight, C.hl);
// Linear flowchart of gestational limit
s.addText("Gestational Age Flowchart:", { x:0.3, y:1.78, w:4, h:0.3, fontSize:10.5, bold:true, color:C.darkG });
const fcSteps = [
["Up to 20 weeks","One RMP's opinion required (amended: was 12 wks)"],
["20 – 24 weeks","Two RMPs' opinion required (special categories only)"],
["Beyond 24 weeks","Medical Board approval (substantial fetal abnormality)"],
["Any gestation","Immediate — if life-threatening to mother"],
];
fcSteps.forEach(([lbl,desc],i)=>{
const by = 2.12+i*0.72;
fcBox(s, lbl, 0.3, by, 2.8, 0.52);
s.addText(desc, { x:3.25, y:by+0.06, w:6.4, h:0.4, fontSize:9.5, color:C.black, fontFace:"Calibri", wrap:true });
if(i<fcSteps.length-1) arrow(s, 1.7, by+0.52);
});
boldBox(s,"★ RMP = Registered Medical Practitioner. Special categories (20-24 wks): rape survivors, minors, differently abled, fetal abnormality, marital status change, multi-parity.", 0.3,5.02,9.4,0.28);
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 7 — MTP ACT GROUNDS & PROVISIONS
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.offW} });
hdr(s,"MTP Act — Grounds, Consent & Key Provisions","");
ftr(s,7);
tbl(s,
["Feature","Details"],
[
["Grounds for MTP","1. Risk to life/physical/mental health of woman\n2. Fetal abnormality (substantial)\n3. Contraceptive failure (married women + unmarried — 2021 amendment)\n4. Rape / sexual assault"],
["Consent","Competent adult: self-consent only\nMinors (<18 yrs) / Mentally ill: Guardian consent + woman's consent"],
["Place of MTP","Only approved hospitals/clinics; NOT at home"],
["Confidentiality","Doctor must maintain confidentiality; no disclosure except court order"],
["Punishments","Unlawful abortion: rigorous imprisonment up to 7 years (IPC 312-316)"],
["2021 Amendment key change","Upper limit raised from 20 to 24 wks for special categories; Medical Board for >24 wks; unmarried women now included"],
],
0.3,1.1,9.4
);
boldBox(s,"IMP: Contraceptive failure ground NOW covers UNMARRIED women also (2021 amendment). Previous law: only married women.", 0.3,4.85,9.4,0.45);
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 8 — STILLBORN vs DEADBORN + LIVEBORN (Q74/169)
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.offW} });
hdr(s,"Q74 & Q169: Stillborn vs Deadborn | Signs of Liveborn Child","Critical medico-legal distinctions");
ftr(s,8);
tbl(s,
["Feature","STILLBORN","DEADBORN (Macerated)"],
[
["Definition","Born dead AFTER 28 weeks of gestation","Fetus that died IN UTERO before delivery (any gestation)"],
["Cause","Intrapartum asphyxia, cord accidents, trauma","Disease, chromosomal, infection, placental failure"],
["Appearance","Fresh; no maceration","Macerated — skin peeling, discolouration, overlapping skull bones"],
["Medico-legal","Must be registered; certificate of stillbirth issued","No birth/death registration required if <28 wks"],
["Hydrostatic test","Lungs SINK (never breathed)","Lungs SINK"],
],
0.3,1.08,9.4
);
s.addText("Signs of a LIVEBORN Child (Q169):", { x:0.3, y:3.52, w:5, h:0.3, fontSize:10.5, bold:true, color:C.darkG });
const liveSigns = [
["Respiratory","Lungs FLOAT (hydrostatic/Docimasia test) — air in lungs","★ Most imp"],
["Cord","Vital reaction around cord (redness/inflammation)",""],
["Stomach","Air/food in stomach (Breslau's second life test)",""],
["Circulation","Blood in left heart (oxygenated); separate circulation",""],
["Cry marks","Expansion of alveoli on histology",""],
["Weight of lungs","Liveborn: 1/35 of body wt. Stillborn: 1/70",""],
];
tbl(s,
["Sign","Details","Note"],
liveSigns,
0.3,3.85,9.4
);
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 9 — HYDROSTATIC / DOCIMASIA TEST (Flowchart)
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.offW} });
hdr(s,"Hydrostatic (Docimasia Pulmonaris) Test — Flowchart","Most important test for live birth");
ftr(s,9);
const steps = [
["REMOVE LUNGS","Take out both lungs intact from the body"],
["PLACE IN WATER","Put entire lung block in a container of water"],
["OBSERVE","Does it FLOAT or SINK?"],
["CUT PIECES","Cut pieces; place in water again"],
["SQUEEZE","Squeeze pieces underwater — look for air bubbles"],
];
steps.forEach(([lbl,desc],i)=>{
const by = 1.1+i*0.78;
fcBox(s,lbl,0.4,by,2.5,0.55);
s.addText(desc, { x:3.05, y:by+0.08, w:6.5, h:0.4, fontSize:9.5, color:C.black, fontFace:"Calibri", wrap:true });
if(i<steps.length-1) arrow(s,1.65,by+0.55);
});
// Branching
s.addShape(pres.ShapeType.diamond, { x:2.5, y:5.0, w:2.5, h:0.82, fill:{color:C.hlLight}, line:{color:C.hl,width:1.5} });
// left
s.addShape("line", { x:0.5, y:5.41, w:2.0, h:0, line:{color:C.mid,width:1.2} });
s.addText("SINKS →", { x:0.5, y:5.22, w:1.5, h:0.22, fontSize:8.5, bold:true, color:C.mid });
// right — will be cut off but okay for concept
s.addText("FLOATS → Liveborn (breathed air)", { x:5.15, y:5.2, w:4.5, h:0.4, fontSize:9.5, bold:true, color:C.accent });
s.addText("SINKS → Stillborn (never breathed)", { x:0.3, y:5.25, w:2.0, h:0.4, fontSize:9.5, bold:true, color:C.mid });
boldBox(s,"FLOATS = LIVEBORN | SINKS = STILLBORN / NEVER BREATHED. Caveat: putrefaction gas can cause stillborn lung to float (false positive).", 0.3,4.85,9.4,0.5);
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 10 — TYPES OF HYMEN (Q78) + TRUE vs FALSE VIRGIN (Q112)
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.offW} });
hdr(s,"Q78: Types of Hymen | Q112: True vs False Virgin","");
ftr(s,10);
s.addText("Types of Hymen:", { x:0.3, y:1.08, w:4, h:0.3, fontSize:10.5, bold:true, color:C.darkG });
tbl(s,
["Type","Description","Medico-legal Relevance"],
[
["Annular (Ring)","Circular opening in centre — MOST COMMON","Normal; no significance"],
["Septate","Two openings due to central band of tissue","Rape may be possible without rupture"],
["Cribriform","Multiple small openings","Rape possible without rupture"],
["Imperforate","No opening — complete membrane","Haematocolpos; surgically corrected"],
["Fimbriated","Fringe-like irregular edges","May look ruptured — forensic trap!"],
["Parous (Carunculae)","Tags/remnants after childbirth","Indicates past childbirth"],
],
0.3,1.42,9.4
);
s.addText("Q112: True Virgin vs False Virgin:", { x:0.3, y:3.78, w:5, h:0.3, fontSize:10.5, bold:true, color:C.darkG });
tbl(s,
["Feature","True Virgin","False Virgin"],
[
["Definition","Never had sexual intercourse","Had intercourse but hymen still intact / repaired"],
["Hymen","Intact (may have small opening)","May appear intact (septate/cribriform type) or surgically repaired"],
["Proof","Cannot be proved medically","Cannot be excluded medically"],
["Forensic point","Intact hymen ≠ virginity proof","Ruptured hymen ≠ non-virginity proof"],
],
0.3,4.1,9.4
);
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 11 — ABORTIFACIENT DRUGS (Q115)
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.offW} });
hdr(s,"Q115: Abortifacient Drugs","Drugs that cause abortion | Classification");
ftr(s,11);
box(s,"ABORTIFACIENT = Any drug/substance used to cause termination of pregnancy. Use without legal sanction = criminal abortion (IPC 312).", 0.3,1.08,9.4,0.55, C.hlLight, C.hl);
tbl(s,
["Category","Examples","Mechanism","Toxicity"],
[
["Ecbolics\n(Uterine stimulants)","Ergot (Ergometrine)\nPituitary extract (Oxytocin)\nQuinine (high dose)","Directly stimulate uterine smooth muscle contractions","Ergot: gangrene, convulsions\nOxytocin: tetanic contractions"],
["Emmenagogues\n(Indirect)","Pennyroyal oil\nSavin (Juniperus)\nCastor oil","Reflex uterine stimulation via GI/systemic irritation","Hepatotoxicity, renal damage"],
["Systemic\nPoisons","Lead, phosphorus\nArsenic","General toxicity → abortion as side effect","Multi-organ failure"],
["Medical\n(Legal — MTP)","Mifepristone (RU-486)\n+ Misoprostol (PGE1)","Mifepristone: blocks progesterone\nMisoprostol: PG-mediated contractions","Safe if used within 9 wks under supervision"],
],
0.3,1.72,9.4
);
boldBox(s,"★ LEGAL abortifacient = Mifepristone 200mg + Misoprostol 800mcg (medical MTP) — approved under MTP Act, up to 9 weeks gestation.", 0.3,4.85,9.4,0.45);
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 12 — BESTIALITY (Q149) + IMPOTENCY (Q165)
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.offW} });
hdr(s,"Q149: Bestiality | Q165: Impotency & Sterility in Males","");
ftr(s,13);
s.addText("Q149: BESTIALITY", { x:0.3, y:1.08, w:4, h:0.3, fontSize:10.5, bold:true, color:C.darkG });
box(s,"Definition: Sexual intercourse between a human and an animal.\nIPC Section 377 — 'carnal intercourse against the order of nature'\nPunishment: imprisonment for life OR up to 10 years + fine.\nSame applies to person who allows it to happen.", 0.3,1.42,9.4,0.88, C.stripe, C.mid);
s.addText("Q165: Causes of IMPOTENCY & STERILITY in Males:", { x:0.3, y:2.4, w:6, h:0.3, fontSize:10.5, bold:true, color:C.darkG });
tbl(s,
["Feature","Impotency","Sterility"],
[
["Definition","Inability to perform sexual intercourse (erection/ejaculation failure)","Inability to fertilize — sperm defect"],
["Causes — Physical","Neurological (DM neuropathy, SCI)\nVascular (arteriosclerosis)\nHormonal (hypogonadism)\nPost-surgical (prostatectomy)","Azoospermia, oligospermia\nObstructive (post-vasectomy, infection)\nVaricocele, cryptorchidism"],
["Causes — Psychological","Performance anxiety, depression, PTSD","Psychological stress → reduced sperm count"],
["Causes — Drugs/Toxic","Alcohol, antihypertensives, antidepressants","Chemotherapy, radiation, anabolic steroids"],
["Medico-legal relevance","Impotency can nullify marriage (ground for divorce / void)","Used in paternity disputes"],
],
0.3,2.75,9.4
);
boldBox(s,"IMP: Impotency = CONSUMMATION failure (relevant to marriage annulment). Sterility = FERTILITY failure (relevant to paternity).", 0.3,5.1,9.4,0.28);
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 13 — SURROGACY (Q25) + INTERSEX (Q31) + TURNER SYNDROME (Q88)
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.offW} });
hdr(s,"Q25: Surrogacy | Q31: Intersex | Q88: Turner Syndrome","Medico-legal significance");
ftr(s,14);
s.addText("SURROGACY (Q25):", { x:0.3, y:1.08, w:4, h:0.28, fontSize:10.5, bold:true, color:C.darkG });
tbl(s,
["Type","Description"],
[
["Traditional surrogacy","Surrogate's own egg + donor sperm → child genetically related to surrogate"],
["Gestational surrogacy","Commissioning couple's embryo implanted into surrogate → child NOT genetically related to surrogate"],
["Altruistic surrogacy","No payment; surrogate is a close relative — LEGAL in India (Surrogacy Regulation Act 2021)"],
["Commercial surrogacy","Payment involved — BANNED in India since 2021"],
],
0.3,1.4,9.4
);
s.addText("INTERSEX (Q31) & TURNER SYNDROME (Q88):", { x:0.3, y:3.28, w:6, h:0.28, fontSize:10.5, bold:true, color:C.darkG });
tbl(s,
["Condition","Karyotype","Features","Medico-legal"],
[
["Turner Syndrome","45,XO (monosomy X)","Short stature, webbed neck, shield chest, primary amenorrhoea, streak gonads, infertile","Age estimation: absent secondary sex characteristics; legal sex determination"],
["True Hermaphroditism","46,XX / 46,XY / mosaic","Both ovarian and testicular tissue present","Legal sex for registration, marriage, inheritance"],
["Pseudohermaphroditism","Male: 46,XY; Female: 46,XX","External genitalia of opposite sex but gonads match chromosomal sex","Forensic sex determination important"],
],
0.3,3.6,9.4
);
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 14 — KEY COMPARISONS TABLE
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.offW} });
hdr(s,"Summary: Key Comparison Tables","All important differences at a glance");
ftr(s,15);
s.addText("Natural vs Criminal Abortion — One-Line Summary:", { x:0.3, y:1.08, w:9, h:0.3, fontSize:10, bold:true, color:C.darkG });
tbl(s,["","Natural","Criminal"],[
["Cause","Spontaneous","Deliberate"],
["IPC","No crime","IPC Sec 312"],
["Signs","No injury","Instrumentation marks"],
], 0.3,1.42,9.4);
s.addText("Impotency vs Sterility — One-Line Summary:", { x:0.3, y:3.1, w:9, h:0.3, fontSize:10, bold:true, color:C.darkG });
tbl(s,["","Impotency","Sterility"],[
["Problem","Cannot perform sex","Cannot fertilize"],
["Sperm","Normal","Abnormal/absent"],
["Legal use","Marriage annulment","Paternity dispute"],
], 0.3,3.42,9.4);
boldBox(s,"Stillborn: born dead >28wks, lungs SINK. Liveborn: breathed, lungs FLOAT. Deadborn: died in utero, macerated.", 0.3,5.08,9.4,0.32);
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 15 — HIGH-YIELD POINTS & MNEMONICS
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.accent} });
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:0.15, h:5.63, fill:{color:C.hl} });
hdr(s,"HIGH-YIELD POINTS — Chapter 10","Remember for exam");
const pts = [
"Positive signs of pregnancy = 5: FHS + Fetal movement (by doctor) + USG + X-ray + Fetal ECG.",
"MTP Act 1971 (amended 2021): up to 20 wks = 1 RMP; 20-24 wks = 2 RMPs (special cats); >24 wks = Medical Board.",
"2021 MTP amendment: UNMARRIED women also covered for contraceptive failure ground.",
"Intact hymen ≠ virginity. Ruptured hymen ≠ non-virginity (septate/cribriform hymen may remain intact).",
"Hydrostatic test: Liveborn lungs FLOAT; Stillborn lungs SINK. False positive: putrefaction gas.",
"MIFEPRISTONE (anti-progesterone) + MISOPROSTOL (PGE1 analogue) = legal medical abortion up to 9 wks.",
"IPC 377 (Navtej 2018): consensual adult homosexual acts decriminalised. Bestiality still criminal.",
"Surrogacy Regulation Act 2021: Altruistic surrogacy LEGAL; Commercial surrogacy BANNED in India.",
"Turner syndrome: 45,XO — short stature, webbed neck, primary amenorrhoea, streak gonads, INFERTILE.",
"Impotency = consummation failure (marriage annulment). Sterility = fertility failure (paternity dispute).",
"IPC 312: causing miscarriage = criminal abortion. Legal exception: MTP Act.",
"Stillborn must be REGISTERED. Deadborn (macerated) <28 wks need NOT be registered.",
];
pts.forEach((p,i)=>{
const col = i%2===0 ? 0 : 1;
const row = Math.floor(i/2);
const bx = col===0 ? 0.25 : 5.15;
const by = 1.08+row*0.78;
s.addShape(pres.ShapeType.roundRect, { x:bx, y:by, w:4.65, h:0.66, fill:{color:"1A2D40"}, line:{color:C.hl,width:0.8}, rectRadius:0.07 });
s.addText(String(i+1)+".", { x:bx+0.08, y:by+0.08, w:0.3, h:0.5, fontSize:9, bold:true, color:C.hl });
s.addText(p, { x:bx+0.4, y:by+0.05, w:4.2, h:0.56, fontSize:8.5, color:C.white, wrap:true, fontFace:"Calibri" });
});
ftr(s,15);
}
// ═════════════════════════════════════════════════════════════════════════
// SLIDE 16 — END
// ═════════════════════════════════════════════════════════════════════════
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:10, h:5.63, fill:{color:C.accent} });
s.addShape(pres.ShapeType.rect, { x:0, y:0, w:0.15, h:5.63, fill:{color:C.hl} });
s.addShape("line", { x:0.4, y:3.1, w:9.2, h:0, line:{color:C.hl,width:1} });
s.addText("CHAPTER 10 COMPLETE", { x:0.4, y:1.6, w:9, h:0.65, fontSize:28, bold:true, color:C.white, align:"center" });
s.addText("Reproductive Forensics, Sexual Offences & MTP Act", { x:0.4, y:2.35, w:9, h:0.4, fontSize:14, color:C.hl, align:"center", italic:true });
s.addText("Abortion | MTP Act | Hymen | Liveborn | Surrogacy | Intersex", { x:0.4, y:2.78, w:9, h:0.3, fontSize:10, color:C.light, align:"center" });
const keys = ["MTP 2021 amendments","FLOAT = Liveborn","Intact hymen ≠ virgin","Selvi rule (Ch.9 bonus)"];
keys.forEach((k,i)=>{
const bx = 0.4+i*2.32;
s.addShape(pres.ShapeType.roundRect, { x:bx, y:3.3, w:2.12, h:0.7, fill:{color:"1A2D40"}, line:{color:C.hl,width:0.8}, rectRadius:0.07 });
s.addText("✓ "+k, { x:bx+0.08, y:3.33, w:1.96, h:0.62, fontSize:9, color:C.white, wrap:true, fontFace:"Calibri" });
});
s.addText("Forensic Medicine & Toxicology | MBBS Exam Preparation", { x:0.4, y:5.1, w:9, h:0.3, fontSize:9, color:C.light, align:"center" });
ftr(s,16);
}
pres.writeFile({ fileName:"/home/daytona/workspace/chapter10/Chapter10_Reproductive_Forensics.pptx" })
.then(()=>console.log("✅ PPT done"))
.catch(e=>{ console.error(e); process.exit(1); });
~/chapter10/chapter10_pdf.py
#!/usr/bin/env python3
"""
Chapter 10: Reproductive Forensics, Sexual Offences & MTP Act
Minimal-colour PDF — 2-colour palette (dark slate + gold accent only)
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.lib.styles import ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
import math
# ── 2-COLOUR PALETTE ──────────────────────────────────────────────────────────
DARK = colors.HexColor("#2C3E50") # dark slate — all headings/borders
GOLD = colors.HexColor("#D4AC0D") # single accent — highlights only
WHITE = colors.white
OFFWHT = colors.HexColor("#F5F5F5")
STRIPE = colors.HexColor("#E8ECF0")
MID = colors.HexColor("#5D6D7E")
LIGHT = colors.HexColor("#BDC3C7")
HLBG = colors.HexColor("#FEF9E7") # very pale gold background
PAGE_W, PAGE_H = A4
LMAR = 2*cm; RMAR = 2*cm
W = PAGE_W - LMAR - RMAR # usable width ~17 cm
# ── HELPERS ───────────────────────────────────────────────────────────────────
def sp(h=0.25): return Spacer(1, h*cm)
def hr(): return HRFlowable(width="100%", thickness=0.5, color=LIGHT, spaceAfter=4)
def P(txt, fs=10, bold=False, color=DARK, align=TA_JUSTIFY, indent=0):
return Paragraph(txt, ParagraphStyle('p', fontName='Helvetica-Bold' if bold else 'Helvetica',
fontSize=fs, leading=fs+4, textColor=color, alignment=align,
firstLineIndent=indent, spaceBefore=2, spaceAfter=2))
def B(txt, fs=10):
return Paragraph(u"\u2022 " + txt, ParagraphStyle('b', fontName='Helvetica',
fontSize=fs, leading=fs+4, textColor=DARK, leftIndent=14, spaceBefore=1, spaceAfter=1))
def SB(txt):
return Paragraph(u"\u2013 " + txt, ParagraphStyle('sb', fontName='Helvetica',
fontSize=9.5, leading=13, textColor=MID, leftIndent=24, spaceBefore=1, spaceAfter=1))
def sec(title, qnum=""):
"""Section heading bar."""
return _SectionHead(title, qnum)
def hl(txt, bold=False):
"""Gold highlight box."""
return _HL(txt, bold)
def make_table(headers, rows, col_widths=None):
if col_widths is None:
col_widths = [W / len(headers)] * len(headers)
data = [headers] + rows
ts = TableStyle([
('BACKGROUND', (0,0), (-1,0), DARK),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 9.5),
('ALIGN', (0,0), (-1,0), 'CENTER'),
('ROWBACKGROUNDS',(0,1),(-1,-1), [STRIPE, WHITE]),
('FONTNAME', (0,1), (-1,-1), 'Helvetica'),
('FONTSIZE', (0,1), (-1,-1), 9),
('GRID', (0,0), (-1,-1), 0.4, LIGHT),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING',(0,0), (-1,-1), 4),
])
t = Table(data, colWidths=col_widths)
t.setStyle(ts)
return t
class _SectionHead(Flowable):
def __init__(self, title, qnum):
Flowable.__init__(self)
self.title = title
self.qnum = qnum
self.w = W
self.h = 0.85*cm
def wrap(self, aw, ah): return self.w, self.h
def draw(self):
c = self.canv
# Background bar
c.setFillColor(DARK)
c.rect(0, 0, self.w, self.h, fill=1, stroke=0)
# Gold left stripe
c.setFillColor(GOLD)
c.rect(0, 0, 0.28*cm, self.h, fill=1, stroke=0)
# Q badge
if self.qnum:
bw = len(self.qnum)*6.5 + 10
c.setFillColor(GOLD)
c.roundRect(self.w - bw - 5, 0.12*cm, bw, 0.6*cm, 4, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 8.5)
c.setFillColor(DARK)
c.drawCentredString(self.w - bw/2 - 5, 0.25*cm, self.qnum)
# Title
c.setFont("Helvetica-Bold", 12)
c.setFillColor(WHITE)
c.drawString(0.5*cm, 0.26*cm, self.title)
class _HL(Flowable):
"""Pale gold highlight callout box."""
def __init__(self, txt, bold=False):
Flowable.__init__(self)
self.txt = txt
self.bold = bold
self.w = W
fs = 10
chars_per = int(self.w / (fs * 0.52))
lines = max(1, math.ceil(len(txt) / chars_per))
self.h = (lines*(fs+5) + 16) / 28.35 * cm
def wrap(self, aw, ah): return self.w, self.h
def draw(self):
c = self.canv
w, h = self.w, self.h
# Box
c.setFillColor(HLBG)
c.roundRect(0, 0, w, h, 6, fill=1, stroke=0)
c.setStrokeColor(GOLD)
c.setLineWidth(1.5)
c.roundRect(0, 0, w, h, 6, fill=0, stroke=1)
# Left gold bar
c.setFillColor(GOLD)
c.rect(0, 0, 0.22*cm, h, fill=1, stroke=0)
# Text
fs = 10
c.setFont("Helvetica-Bold" if self.bold else "Helvetica", fs)
c.setFillColor(DARK)
txt_x = 0.38*cm
txt_y = h - 0.45*cm
words = self.txt.split()
cur = ""
for word in words:
test = (cur + " " + word).strip()
if len(test)*fs*0.52 < (w - 0.5*cm)*28.35:
cur = test
else:
c.drawString(txt_x, txt_y, cur)
txt_y -= (fs+5)/28.35*cm
cur = word
if cur: c.drawString(txt_x, txt_y, cur)
class LinearFC(Flowable):
"""Simple top-to-bottom flowchart."""
def __init__(self, title, steps):
Flowable.__init__(self)
self.title = title
self.steps = steps
self.w = W
self.h = 0.6*cm + len(steps)*(0.7*cm + 0.45*cm) + 0.2*cm
def wrap(self, aw, ah): return self.w, self.h
def draw(self):
c = self.canv
w, h = self.w, self.h
bw = w*0.7
bx = (w - bw)/2
y = h - 0.5*cm
c.setFont("Helvetica-Bold", 11)
c.setFillColor(DARK)
c.drawCentredString(w/2, y, self.title)
y -= 0.38*cm
for i,(lbl,desc) in enumerate(self.steps):
bh = 0.65*cm
# Box
c.setFillColor(STRIPE)
c.roundRect(bx, y-bh, bw, bh, 5, fill=1, stroke=0)
c.setStrokeColor(DARK)
c.setLineWidth(0.8)
c.roundRect(bx, y-bh, bw, bh, 5, fill=0, stroke=1)
# Step number
c.setFillColor(DARK)
c.circle(bx+0.35*cm, y-bh/2, 0.24*cm, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 8)
c.setFillColor(WHITE)
c.drawCentredString(bx+0.35*cm, y-bh/2-0.09*cm, str(i+1))
# Label
c.setFont("Helvetica-Bold", 9)
c.setFillColor(DARK)
c.drawString(bx+0.72*cm, y-0.3*cm, lbl+":")
lw = len(lbl)*6.2 + bx+0.72*cm + 5
c.setFont("Helvetica", 9)
c.setFillColor(MID)
c.drawString(lw, y-0.3*cm, desc[:80])
y -= bh
if i < len(self.steps)-1:
mx = w/2
c.setStrokeColor(MID)
c.setLineWidth(1.2)
c.line(mx, y, mx, y-0.32*cm)
# arrowhead
p = c.beginPath()
p.moveTo(mx-0.1*cm, y-0.28*cm)
p.lineTo(mx+0.1*cm, y-0.28*cm)
p.lineTo(mx, y-0.43*cm)
p.close()
c.setFillColor(MID)
c.drawPath(p, fill=1, stroke=0)
y -= 0.45*cm
class BranchFC(Flowable):
"""Decision diamond with YES/NO branches."""
def __init__(self, title, question, yes_label, yes_steps, no_label, no_steps):
Flowable.__init__(self)
self.title = title
self.question = question
self.yes_label = yes_label
self.yes_steps = yes_steps
self.no_label = no_label
self.no_steps = no_steps
self.w = W
self.h = 10.5*cm
def wrap(self, aw, ah): return self.w, self.h
def draw(self):
c = self.canv
w, h = self.w, self.h
mid = w/2
# Title
c.setFont("Helvetica-Bold", 11)
c.setFillColor(DARK)
c.drawCentredString(mid, h-0.4*cm, self.title)
# Diamond
d_top = h-1.0*cm; d_mid = h-2.3*cm; d_bot = h-3.6*cm; dw = 4.0*cm
c.setFillColor(HLBG)
c.setStrokeColor(GOLD)
c.setLineWidth(1.5)
pts = [mid, d_top, mid+dw/2, d_mid, mid, d_bot, mid-dw/2, d_mid]
p = c.beginPath()
p.moveTo(pts[0], pts[1])
for k in range(2, len(pts), 2): p.lineTo(pts[k], pts[k+1])
p.close()
c.drawPath(p, fill=1, stroke=1)
# Question text
c.setFont("Helvetica-Bold", 8.5)
c.setFillColor(DARK)
qlines = []
cur = ""
for w_ in self.question.split():
test = (cur+" "+w_).strip()
if len(test) < 22: cur = test
else: qlines.append(cur); cur = w_
qlines.append(cur)
qy = d_mid + len(qlines)*0.16*cm
for ql in qlines:
c.drawCentredString(mid, qy, ql)
qy -= 0.32*cm
# NO branch (left)
c.setStrokeColor(MID); c.setLineWidth(1.2)
c.line(mid-dw/2, d_mid, 1.2*cm, d_mid)
c.line(1.2*cm, d_mid, 1.2*cm, d_bot-0.8*cm)
c.setFont("Helvetica-Bold", 9); c.setFillColor(MID)
c.drawString(mid-dw/2-1.1*cm, d_mid+0.1*cm, self.no_label)
bw2 = 3.2*cm
nb_x = 0.2*cm
nb_y = d_bot-1.0*cm
for st in self.no_steps:
c.setFillColor(STRIPE)
c.roundRect(nb_x, nb_y-0.58*cm, bw2, 0.58*cm, 4, fill=1, stroke=0)
c.setStrokeColor(DARK); c.setLineWidth(0.6)
c.roundRect(nb_x, nb_y-0.58*cm, bw2, 0.58*cm, 4, fill=0, stroke=1)
c.setFont("Helvetica", 8); c.setFillColor(DARK)
c.drawString(nb_x+0.12*cm, nb_y-0.38*cm, st[:36])
if self.no_steps.index(st)<len(self.no_steps)-1:
c.setStrokeColor(MID)
c.line(nb_x+bw2/2, nb_y-0.58*cm, nb_x+bw2/2, nb_y-0.82*cm)
nb_y -= 0.82*cm
# YES branch (right)
c.setStrokeColor(MID); c.setLineWidth(1.2)
c.line(mid+dw/2, d_mid, w-1.2*cm, d_mid)
c.line(w-1.2*cm, d_mid, w-1.2*cm, d_bot-0.8*cm)
c.setFont("Helvetica-Bold", 9); c.setFillColor(DARK)
c.drawString(mid+dw/2+0.2*cm, d_mid+0.1*cm, self.yes_label)
yb_x = w-3.4*cm
yb_y = d_bot-1.0*cm
for st in self.yes_steps:
c.setFillColor(HLBG)
c.roundRect(yb_x, yb_y-0.58*cm, bw2, 0.58*cm, 4, fill=1, stroke=0)
c.setStrokeColor(GOLD); c.setLineWidth(0.6)
c.roundRect(yb_x, yb_y-0.58*cm, bw2, 0.58*cm, 4, fill=0, stroke=1)
c.setFont("Helvetica", 8); c.setFillColor(DARK)
c.drawString(yb_x+0.12*cm, yb_y-0.38*cm, st[:36])
if self.yes_steps.index(st)<len(self.yes_steps)-1:
c.setStrokeColor(GOLD)
c.line(yb_x+bw2/2, yb_y-0.58*cm, yb_x+bw2/2, yb_y-0.82*cm)
yb_y -= 0.82*cm
class ComparisonBox(Flowable):
"""Side-by-side two-column comparison."""
def __init__(self, title, left_title, right_title, left_items, right_items):
Flowable.__init__(self)
self.title = title
self.lt = left_title; self.rt = right_title
self.left = left_items; self.right = right_items
self.w = W
rows = max(len(left_items), len(right_items))
self.h = 0.7*cm + rows*0.55*cm + 0.2*cm
def wrap(self, aw, ah): return self.w, self.h
def draw(self):
c = self.canv
w, h = self.w, self.h
cw = (w-0.15*cm)/2
# Title bar
c.setFillColor(DARK)
c.rect(0, h-0.55*cm, w, 0.55*cm, fill=1, stroke=0)
c.setFont("Helvetica-Bold", 10.5)
c.setFillColor(WHITE)
c.drawCentredString(w/2, h-0.4*cm, self.title)
# Left col
c.setFillColor(STRIPE)
c.rect(0, 0, cw, h-0.55*cm, fill=1, stroke=0)
c.setStrokeColor(DARK); c.setLineWidth(0.5)
c.rect(0, 0, cw, h-0.55*cm, fill=0, stroke=1)
c.setFont("Helvetica-Bold", 9.5); c.setFillColor(DARK)
c.drawCentredString(cw/2, h-0.85*cm, self.lt)
# Right col
rx = cw+0.15*cm
c.setFillColor(HLBG)
c.rect(rx, 0, cw, h-0.55*cm, fill=1, stroke=0)
c.setStrokeColor(GOLD); c.setLineWidth(0.5)
c.rect(rx, 0, cw, h-0.55*cm, fill=0, stroke=1)
c.setFont("Helvetica-Bold", 9.5); c.setFillColor(DARK)
c.drawCentredString(rx+cw/2, h-0.85*cm, self.rt)
c.setFont("Helvetica", 9); c.setFillColor(DARK)
y = h-1.1*cm
for item in self.left:
c.drawString(0.15*cm, y, u"\u2022 " + item)
y -= 0.55*cm
y = h-1.1*cm
for item in self.right:
c.drawString(rx+0.15*cm, y, u"\u2022 " + item)
y -= 0.55*cm
# ── PAGE CALLBACKS ─────────────────────────────────────────────────────────────
def on_page(canvas, doc):
canvas.saveState()
# Footer
canvas.setFillColor(DARK)
canvas.rect(0, 0, PAGE_W, 0.65*cm, fill=1, stroke=0)
canvas.setFont("Helvetica", 7.5)
canvas.setFillColor(LIGHT)
canvas.drawString(LMAR, 0.22*cm, "Chapter 10: Reproductive Forensics, Sexual Offences & MTP Act | Forensic Medicine")
canvas.setFillColor(GOLD)
canvas.setFont("Helvetica-Bold", 8)
canvas.drawRightString(PAGE_W-RMAR, 0.22*cm, str(doc.page))
# Top stripe
canvas.setFillColor(GOLD)
canvas.rect(0, PAGE_H-0.18*cm, PAGE_W, 0.18*cm, fill=1, stroke=0)
canvas.restoreState()
# ── BUILD ──────────────────────────────────────────────────────────────────────
def build(path):
doc = SimpleDocTemplate(path, pagesize=A4,
leftMargin=LMAR, rightMargin=RMAR,
topMargin=1.4*cm, bottomMargin=1.2*cm)
story = []
# ── COVER ──────────────────────────────────────────────────────────────────
story.append(sp(1.5))
story.append(P("FORENSIC MEDICINE & TOXICOLOGY", 11, color=MID, align=TA_CENTER))
story.append(sp(0.1))
story.append(P("CHAPTER 10", 32, bold=True, color=DARK, align=TA_CENTER))
story.append(sp(0.05))
story.append(P("Reproductive Forensics,", 22, bold=True, color=DARK, align=TA_CENTER))
story.append(P("Sexual Offences & MTP Act", 22, bold=True, color=DARK, align=TA_CENTER))
story.append(sp(0.2))
story.append(HRFlowable(width="100%", thickness=2, color=GOLD))
story.append(sp(0.15))
story.append(P("Q27 · Q39 · Q56 · Q60 · Q74 · Q78 · Q112 · Q115 · Q149 · Q165 · Q169 · Q25 · Q31 · Q88", 10, color=MID, align=TA_CENTER))
story.append(sp(0.3))
# Stat row (table)
stat_data = [["14 Questions", "Abortion (Q27/52)", "MTP Act (Q60)", "Hymen (Q78)", "Liveborn (Q169)"]]
stat_ts = TableStyle([
('BACKGROUND', (0,0),(-1,-1), DARK),
('TEXTCOLOR', (0,0),(-1,-1), WHITE),
('FONTNAME', (0,0),(-1,-1), 'Helvetica-Bold'),
('FONTSIZE', (0,0),(-1,-1), 10),
('ALIGN', (0,0),(-1,-1), 'CENTER'),
('VALIGN', (0,0),(-1,-1), 'MIDDLE'),
('BOX', (0,0),(-1,-1), 1.5, GOLD),
('INNERGRID', (0,0),(-1,-1), 0.5, MID),
('TOPPADDING', (0,0),(-1,-1), 8),
('BOTTOMPADDING',(0,0),(-1,-1), 8),
])
st = Table(stat_data, colWidths=[W/5]*5)
st.setStyle(stat_ts)
story.append(st)
story.append(PageBreak())
# ── Q27/52: ABORTION ───────────────────────────────────────────────────────
story.append(sec("Q27/52: Natural vs Criminal Abortion", "Q27/52"))
story.append(sp(0.2))
story.append(hl("ABORTION = Expulsion of products of conception BEFORE fetal viability (before 28 weeks / 500g in Indian law). After 28 wks = premature labour.", bold=True))
story.append(sp(0.2))
story.append(P("<b>Definition of Terms</b>", 10, bold=True))
story.append(B("Viable fetus: able to survive outside uterus — defined as 28 weeks gestation or 500g body weight in Indian law"))
story.append(B("Abortion = expulsion before viability"))
story.append(B("Miscarriage = lay term for abortion (used for natural/spontaneous)"))
story.append(sp(0.2))
story.append(make_table(
["Feature", "Natural (Spontaneous) Abortion", "Criminal Abortion"],
[
["Definition", "Expulsion without deliberate interference; natural causes", "Deliberately induced — unlawful termination"],
["Causes", "Chromosomal defects, uterine anomaly, infection, hormonal", "Mechanical instruments, abortifacient drugs"],
["Legal status", "NOT a crime", "CRIME — IPC Sec 312 (unless MTP Act applies)"],
["External signs", "No signs of injury or instrumentation", "Laceration, signs of instrumentation, infection"],
["PM findings", "No foreign material in uterus", "Instruments, chemical residues may be found"],
["Doctor's duty", "No mandatory reporting", "Must report; preserve evidence; inform police"],
],
col_widths=[3.8*cm, 6.5*cm, 6.5*cm]
))
story.append(sp(0.2))
story.append(hl("IMP: IPC Sec 312 = causing miscarriage — punishable up to 3 years (with woman's consent) or 7 years (without consent). MTP Act 1971 provides legal exceptions."))
story.append(sp(0.15))
story.append(P("<b>Types of Abortion (classification)</b>", 10, bold=True))
story.append(make_table(
["Type", "Description"],
[
["Threatened", "Bleeding per vaginum; os closed; fetus alive — may continue"],
["Inevitable", "Bleeding + pain + os open — cannot be prevented"],
["Incomplete", "Some products expelled; some retained"],
["Complete", "All products expelled"],
["Missed", "Fetus dead but retained in uterus for >4 weeks"],
["Septic", "Infection complicates any above type — most dangerous forensically"],
],
col_widths=[4*cm, 12.8*cm]
))
story.append(PageBreak())
# ── Q39: UNNATURAL SEXUAL OFFENCES ────────────────────────────────────────
story.append(sec("Q39: Unnatural Sexual Offences", "Q39"))
story.append(sp(0.2))
story.append(P("<b>Definition:</b> Sexual acts considered unnatural — against the order of nature. Governed primarily by IPC Section 377.", 10))
story.append(sp(0.2))
story.append(make_table(
["Offence", "IPC Section", "Description"],
[
["Sodomy / Buggery", "Sec 377", "Penile penetration of anus — male-male, male-female, or human-animal"],
["Bestiality", "Sec 377", "Sexual intercourse between human and animal"],
["Tribadism", "—", "Vulvo-vulvar friction between females"],
["Fellatio", "—", "Oral stimulation of male genitalia"],
["Cunnilingus", "—", "Oral stimulation of female genitalia"],
["Frotteurism", "—", "Rubbing against non-consenting person for sexual gratification"],
["Exhibitionism", "—", "Deliberate indecent exposure of genitalia in public"],
["Voyeurism", "—", "Deriving sexual pleasure from watching others without consent"],
],
col_widths=[4*cm, 2.5*cm, 10.3*cm]
))
story.append(sp(0.2))
story.append(hl("LEGAL UPDATE: Navtej Singh Johar vs Union of India (2018) — Supreme Court read down IPC Sec 377: CONSENSUAL HOMOSEXUAL ACTS BETWEEN ADULTS are now DECRIMINALISED. Non-consensual acts and acts with minors remain criminal."))
story.append(PageBreak())
# ── Q56: SIGNS OF PREGNANCY ───────────────────────────────────────────────
story.append(sec("Q56/68/164: Signs of Pregnancy — Confirmatory Signs", "Q56/164"))
story.append(sp(0.2))
story.append(make_table(
["Category", "Signs", "Reliability"],
[
["PRESUMPTIVE\n(Subjective)", "Amenorrhoea\nNausea/vomiting (morning sickness)\nBreast changes (Engorgement, darkening areola)\nFrequency of micturition\nQuickening: fetal movements felt by mother (16–20 wks)", "LEAST reliable — can occur in other conditions"],
["PROBABLE\n(Objective)", "Uterine enlargement\nHegar's sign (softening of lower uterine segment — 6-8 wks)\nGoodell's sign (softening of cervix — 5-6 wks)\nChadwick's sign (bluish discolouration cervix/vagina — 6-8 wks)\nBallottement (fetus bounces back on tapping — 16-20 wks)\nBraxton Hicks contractions\n+ve pregnancy test (urine beta-hCG)", "MORE reliable but NOT conclusive"],
["POSITIVE\n(CONFIRMATORY)\n★★★", "1. Fetal heart sounds (auscultation / Doppler from 10-12 wks)\n2. Fetal movements felt by EXAMINER (not by mother)\n3. Ultrasonography — fetal parts visible (from 5-6 wks)\n4. Fetal skeleton on X-ray (from 16 wks)\n5. Fetal electrocardiography (ECG)", "CONCLUSIVE — cannot be simulated or present in non-pregnant state"],
],
col_widths=[3.2*cm, 8*cm, 5.6*cm]
))
story.append(sp(0.2))
story.append(hl("★ EXAM FAVOURITE: Positive (Confirmatory) signs — ONLY 5: (1) FHS heard (2) Fetal movements felt BY DOCTOR (3) USG fetal parts (4) X-ray fetal skeleton (5) Fetal ECG. These are ABSOLUTE proof of pregnancy.", bold=True))
story.append(sp(0.2))
story.append(P("<b>Detailed Signs Table</b>", 10, bold=True))
story.append(make_table(
["Sign", "What it is", "Weeks of gestation"],
[
["Hegar's sign", "Softening + compressibility of lower uterine segment", "6–8 weeks"],
["Goodell's sign", "Softening of cervix (normally firm as nose; becomes soft as lips)", "5–6 weeks"],
["Chadwick's sign", "Bluish/violet discolouration of cervix and vaginal walls", "6–8 weeks"],
["Quickening", "First fetal movements felt BY MOTHER", "16–18 wks (primi); 18–20 wks (multi)"],
["Ballottement", "Fetus bounces back when lower uterine segment is tapped", "16–20 weeks"],
["Beta-hCG positive", "Detectable in urine/blood — MOST SENSITIVE early test", "From 8-10 days post-conception"],
],
col_widths=[3.8*cm, 7.5*cm, 5.5*cm]
))
story.append(PageBreak())
# ── Q60: MTP ACT ──────────────────────────────────────────────────────────
story.append(sec("Q60/104/152: MTP Act 1971 (Amended 2021)", "Q60/104/152"))
story.append(sp(0.2))
story.append(hl("MTP Act 1971 (Medical Termination of Pregnancy Act) — Provides LEGAL framework for termination of pregnancy under defined conditions. Overrides criminal liability under IPC Sec 312."))
story.append(sp(0.2))
# Flowchart of gestational limits
story.append(LinearFC("MTP Act — Gestational Limit Flowchart", [
["Up to 20 weeks", "Opinion of 1 RMP sufficient (earlier law: 12 weeks)"],
["20 to 24 weeks", "Opinion of 2 RMPs required — SPECIAL CATEGORIES ONLY"],
["Beyond 24 weeks", "Medical Board approval — substantial fetal abnormality only"],
["Any gestation", "IMMEDIATELY — if to save life of pregnant woman"],
]))
story.append(sp(0.25))
story.append(P("<b>Special Categories eligible for 20–24 week termination:</b>", 10, bold=True))
story.append(B("Survivors of sexual assault or rape"))
story.append(B("Minors (below 18 years of age)"))
story.append(B("Change of marital status during pregnancy (widowhood, divorce)"))
story.append(B("Women with physical / mental disability"))
story.append(B("Fetal malformation incompatible with life or causing serious disability"))
story.append(B("Multi-parity (having many children)"))
story.append(sp(0.2))
story.append(make_table(
["Feature", "Details"],
[
["Grounds for MTP", "1. Risk to life or health (physical/mental) of woman\n2. Substantial fetal abnormality\n3. Contraceptive failure (married + unmarried — 2021 amendment)\n4. Rape / sexual assault"],
["Consent required", "Competent adult: self-consent only\nMinors (<18) / Mentally ill: Guardian + woman's own consent"],
["Place", "Only government approved hospitals/clinics. NOT at home."],
["Confidentiality", "Doctor must maintain strict confidentiality; disclosure only by court order"],
["Punishment for illegal abortion", "IPC 312–316: 3–7 years RI + fine; more if death of woman results"],
["2021 Key Amendment", "Upper limit: 20→24 wks for special categories. Unmarried women NOW included. Medical Board for >24 wks."],
],
col_widths=[4.5*cm, 12.3*cm]
))
story.append(sp(0.2))
story.append(hl("MOST IMP 2021 CHANGE: Contraceptive failure ground now covers UNMARRIED women. Previously only married women were covered.", bold=True))
story.append(PageBreak())
# ── Q74 + Q169: STILLBORN / LIVEBORN ─────────────────────────────────────
story.append(sec("Q74: Stillborn vs Deadborn | Q169: Signs of Liveborn", "Q74/169"))
story.append(sp(0.2))
story.append(make_table(
["Feature", "STILLBORN", "DEADBORN (Macerated)"],
[
["Definition", "Born dead AFTER 28 weeks gestation (at or near term)", "Fetus that died IN UTERO; delivered at any gestation"],
["Appearance", "Fresh body; no maceration", "Macerated: skin peeling, overlapping skull bones, discolouration"],
["Cause", "Intrapartum asphyxia, cord accidents, trauma during delivery", "Disease, chromosomal, infection, placental failure"],
["Viability", "Was viable (>28 weeks) but born dead", "May not be viable (<28 weeks)"],
["Registration", "MUST be registered with birth/death certificate", "Not required if <28 weeks gestation"],
["Hydrostatic test", "Lungs SINK (never breathed)", "Lungs SINK"],
],
col_widths=[3.5*cm, 6.5*cm, 6.8*cm]
))
story.append(sp(0.2))
story.append(P("<b>Signs of LIVEBORN Child (Q169)</b>", 10, bold=True))
story.append(make_table(
["Sign", "Details", "Exam Importance"],
[
["Hydrostatic test\n(Docimasia pulmonaris)\n★★★", "Liveborn lungs FLOAT in water (air in alveoli)\nStillborn lungs SINK\nCut pieces also float if breathed", "MOST important test — always ask in exam"],
["Breslau's 2nd life test", "Air/food found in STOMACH (swallowed during breathing)", "Important secondary test"],
["Cord vital reaction", "Redness and inflammation (vital reaction) at cord base", "Indicates lived after birth"],
["Lung weight", "Liveborn: 1/35 of body weight\nStillborn: 1/70 of body weight", "Comparative weight ratio"],
["Histology of lungs", "Expanded alveoli on microscopy\nDilated alveolar capillaries", "Gold standard — microscopy"],
["Separate circulation", "Oxygenated blood in left heart\nForamen ovale closed", "After first breath — circulation separates"],
],
col_widths=[3.8*cm, 8.5*cm, 4.5*cm]
))
story.append(sp(0.2))
story.append(hl("HYDROSTATIC TEST CAVEAT: Putrefaction gas can cause stillborn lung to FLOAT (false positive). SQUEEZE cut pieces — if gas, no true air bubbles; if truly breathed, fine bubbles escape."))
story.append(PageBreak())
# Branching FC — Hydrostatic test
story.append(BranchFC(
"Hydrostatic (Docimasia) Test — Decision Flowchart",
"Lungs placed in water:\ndo they FLOAT?",
"YES → FLOATS",
["Liveborn (breathed air)", "Cut pieces → still float", "Squeeze → fine air bubbles"],
"NO → SINKS",
["Stillborn / Never breathed", "Check for putrefaction", "Histology to confirm"]
))
story.append(sp(0.2))
story.append(hl("FLOAT = LIVEBORN (air in alveoli) | SINK = STILLBORN. Exception: putrefaction → false positive float.", bold=True))
story.append(PageBreak())
# ── Q78: TYPES OF HYMEN ───────────────────────────────────────────────────
story.append(sec("Q78: Types of Hymen | Q112: True vs False Virgin", "Q78/112"))
story.append(sp(0.2))
story.append(P("<b>The Hymen</b> is a thin mucous membrane fold at the vaginal orifice. Its shape, size, and thickness vary considerably. Forensically important in cases of rape and virginity examination.", 10))
story.append(sp(0.15))
story.append(make_table(
["Type", "Description", "Medico-legal Relevance"],
[
["Annular (Ring)", "Central circular opening — MOST COMMON type", "Normal; sexual intercourse will rupture"],
["Septate", "Two openings due to central vertical band of tissue", "Sexual intercourse MAY occur without rupture"],
["Cribriform", "Multiple small sieve-like openings", "Penetration possible without visible rupture"],
["Imperforate", "No opening — completely closed membrane", "Haematocolpos; must be surgically incised"],
["Fimbriated (Denticular)", "Irregular fringe-like edges resembling a fern", "TRAP: may appear ruptured but is normal type"],
["Parous Introitus\n(Carunculae myrtiformes)", "Tags/remnants after childbirth — caruncles", "Indicates past vaginal delivery"],
["Lunar (Crescentic)", "Crescent-shaped; posterior portion only", "Common normal variant"],
],
col_widths=[3.8*cm, 6.5*cm, 6.5*cm]
))
story.append(sp(0.2))
story.append(hl("CRITICAL FORENSIC POINT: INTACT HYMEN does NOT prove virginity. RUPTURED HYMEN does NOT prove sexual intercourse. Septate/cribriform hymen can remain intact after penile penetration."))
story.append(sp(0.2))
story.append(P("<b>Q112: True Virgin vs False Virgin</b>", 10, bold=True))
story.append(make_table(
["Feature", "True Virgin", "False Virgin"],
[
["Definition", "Person who has NEVER had sexual intercourse", "Person who has had intercourse but hymen appears intact"],
["Hymen status", "Intact hymen (one of several types)", "Intact hymen (septate/cribriform type) OR surgically repaired"],
["Medical proof", "Cannot be conclusively proved by hymen examination alone", "Cannot be excluded; appearance may be normal"],
["Forensic significance", "Intact hymen = consistent with virginity; does not prove it", "Ruptured hymen ≠ non-virginity"],
],
col_widths=[3.8*cm, 6.5*cm, 6.5*cm]
))
story.append(PageBreak())
# ── Q115: ABORTIFACIENT DRUGS ─────────────────────────────────────────────
story.append(sec("Q115: Abortifacient Drugs", "Q115"))
story.append(sp(0.2))
story.append(P("<b>Definition:</b> An abortifacient is any drug, chemical, or agent that causes termination of pregnancy. Illegal use = criminal abortion (IPC 312).", 10))
story.append(sp(0.15))
story.append(make_table(
["Category", "Examples", "Mechanism", "Toxicity"],
[
["Ecbolics\n(Uterotonic agents)", "Ergot (Ergometrine)\nOxytocin\nQuinine (high dose)", "Directly stimulate uterine smooth muscle contractions → expulsion", "Ergot: gangrene, convulsions, ergotism\nOxytocin: tetanic contractions, fetal distress"],
["Emmenagogues\n(Indirect)", "Pennyroyal oil\nSavin (Juniperus sabina)\nAloes, castor oil", "GI/systemic irritation → reflex uterine stimulation", "Hepatotoxicity, renal damage, haemorrhage"],
["Systemic poisons\n(Accidental)", "Lead, arsenic, phosphorus\nCarbon monoxide", "General systemic toxicity causes abortion as side effect", "Multi-organ failure; may be fatal to mother"],
["LEGAL Medical\n(MTP Act)", "Mifepristone 200mg\n+ Misoprostol 800mcg", "Mifepristone blocks progesterone receptors\nMisoprostol (PGE1): uterine contractions", "Safe when used ≤9 weeks under medical supervision"],
],
col_widths=[3.5*cm, 3.8*cm, 5.2*cm, 4.3*cm]
))
story.append(sp(0.2))
story.append(hl("LEGAL ABORTIFACIENT: Mifepristone 200mg + Misoprostol 800mcg — WHO essential medicine for medical MTP up to 9 weeks (63 days). Approved under MTP Act."))
story.append(PageBreak())
# ── Q149: BESTIALITY | Q165: IMPOTENCY ───────────────────────────────────
story.append(sec("Q149: Bestiality | Q165: Impotency & Sterility", "Q149/165"))
story.append(sp(0.2))
story.append(P("<b>Q149: BESTIALITY</b>", 10, bold=True))
story.append(B("Definition: Sexual intercourse between a human being and an animal."))
story.append(B("IPC Section 377: 'Whoever voluntarily has carnal intercourse against the order of nature...'"))
story.append(B("Punishment: Imprisonment for LIFE or up to 10 years + fine."))
story.append(B("Also applies to the person who allows/facilitates the act."))
story.append(B("Post-mortem examination of animal may be required as medico-legal evidence."))
story.append(sp(0.2))
story.append(P("<b>Q165: Impotency vs Sterility in Males</b>", 10, bold=True))
story.append(make_table(
["Feature", "IMPOTENCY", "STERILITY"],
[
["Definition", "Inability to perform sexual intercourse (erectile/ejaculatory failure)", "Inability to fertilize — defect in sperm quantity/quality"],
["Mechanism", "Failure of erection, ejaculation, or penetration", "Azoospermia, oligospermia, asthenospermia, teratospermia"],
["Physical causes", "Neurological (DM neuropathy, spinal cord injury)\nVascular (arteriosclerosis, venous leak)\nHormonal (hypogonadism, hyperprolactinaemia)", "Cryptorchidism, varicocele, post-orchitis\nObstructive (post-vasectomy, infection)\nEndocrine (hypogonadotropic)"],
["Psychological causes", "Performance anxiety, depression, PTSD, relationship problems", "Stress → reduced sperm count (indirect effect)"],
["Drug causes", "Antihypertensives, antidepressants, alcohol, narcotics", "Chemotherapy, radiation, anabolic steroids"],
["Medico-legal relevance", "Ground for marriage annulment / nullity\nRelevant in consummation proof", "Relevant in paternity disputes\nChild cannot be biological offspring"],
],
col_widths=[4*cm, 6.4*cm, 6.4*cm]
))
story.append(sp(0.2))
story.append(hl("KEY DISTINCTION: IMPOTENCY = cannot perform sex (consummation failure) → marriage annulment. STERILITY = cannot fertilize (reproductive failure) → paternity dispute."))
story.append(PageBreak())
# ── Q169: SURROGACY | Q31: INTERSEX | Q88: TURNER ────────────────────────
story.append(sec("Q25: Surrogacy | Q31: Intersex | Q88: Turner Syndrome", "Q25/31/88"))
story.append(sp(0.2))
story.append(P("<b>Q25: SURROGACY</b>", 10, bold=True))
story.append(make_table(
["Type", "Description", "Legal Status in India"],
[
["Traditional Surrogacy", "Surrogate's own egg + donor sperm → child genetically related to surrogate", "Effectively banned under 2021 Act"],
["Gestational Surrogacy", "Commissioning couple's embryo implanted → child NOT genetically related to surrogate", "Altruistic form LEGAL; commercial BANNED"],
["Altruistic Surrogacy", "No financial payment; surrogate is a close relative of commissioning couple", "LEGAL — Surrogacy Regulation Act 2021"],
["Commercial Surrogacy", "Surrogacy for monetary compensation/payment", "BANNED in India since 2021"],
],
col_widths=[4*cm, 7.5*cm, 5.3*cm]
))
story.append(sp(0.15))
story.append(hl("Surrogacy Regulation Act 2021: Only ALTRUISTIC SURROGACY is legal. Close relative of intending couple. Commercial surrogacy = criminal offence."))
story.append(sp(0.2))
story.append(P("<b>Q31: INTERSEX</b>", 10, bold=True))
story.append(make_table(
["Condition", "Karyotype", "Features", "Medico-legal Relevance"],
[
["True Hermaphroditism", "46,XX / 46,XY / mosaic", "BOTH ovarian and testicular tissue present. Ambiguous external genitalia.", "Legal sex registration; marriage validity"],
["Male Pseudohermaphroditism", "46,XY", "Testes present but external genitalia appear female (e.g., Androgen Insensitivity Syndrome)", "Sex determination for legal purposes"],
["Female Pseudohermaphroditism", "46,XX", "Ovaries present but external genitalia appear male (e.g., CAH — congenital adrenal hyperplasia)", "Legal sex; early surgical correction"],
],
col_widths=[3.5*cm, 2.2*cm, 6*cm, 5.1*cm]
))
story.append(sp(0.2))
story.append(P("<b>Q88: TURNER SYNDROME (45,XO)</b>", 10, bold=True))
story.append(make_table(
["Feature", "Details"],
[
["Karyotype", "45,XO — monosomy X (loss of one sex chromosome)"],
["Incidence", "1 in 2500 live female births"],
["Features", "Short stature\nWebbed neck (pterygium colli)\nShield chest\nPrimary amenorrhoea\nStreak gonads (fibrous tissue; no functioning ovaries)\nInfertile\nCoarctation of aorta (cardiac)\nCubitus valgus (wide carrying angle)"],
["Medico-legal relevance", "Age estimation: absent secondary sex characteristics despite adult age\nLegal sex determination\nInfertility → paternity/maternity disputes\nMarriage: considered female legally"],
],
col_widths=[3.5*cm, 13.3*cm]
))
story.append(PageBreak())
# ── SUMMARY COMPARISONS ───────────────────────────────────────────────────
story.append(sec("Summary Comparisons", ""))
story.append(sp(0.2))
story.append(ComparisonBox(
"Impotency vs Sterility",
"IMPOTENCY",
"STERILITY",
["Cannot perform sex", "Erectile/ejaculatory failure", "Marriage annulment", "Sperm may be normal"],
["Cannot fertilize", "Sperm defect", "Paternity dispute", "Intercourse is possible"]
))
story.append(sp(0.2))
story.append(ComparisonBox(
"Natural Abortion vs Criminal Abortion",
"NATURAL",
"CRIMINAL",
["Spontaneous; no intervention", "Not a crime", "No signs of injury", "No reporting duty"],
["Deliberate; induced", "IPC Sec 312 crime", "Instrumentation signs", "Doctor must report"]
))
story.append(sp(0.2))
story.append(ComparisonBox(
"Stillborn vs Liveborn",
"STILLBORN",
"LIVEBORN",
["Born dead", "Lungs SINK", "No vital reaction in cord", "1/70 body weight"],
["Born alive, breathed", "Lungs FLOAT", "Vital reaction present", "1/35 body weight"]
))
story.append(PageBreak())
# ── HIGH-YIELD POINTS ─────────────────────────────────────────────────────
story.append(sec("HIGH-YIELD POINTS — Chapter 10", "★★★"))
story.append(sp(0.2))
imp_pts = [
("1", "Positive/Confirmatory signs of pregnancy = ONLY 5: FHS + Fetal movements BY DOCTOR + USG + X-ray + Fetal ECG."),
("2", "MTP Act 2021 amendment: up to 20 wks = 1 RMP; 20–24 wks = 2 RMPs (special categories); >24 wks = Medical Board."),
("3", "BIGGEST 2021 CHANGE: Contraceptive failure ground now covers UNMARRIED women (was married only before)."),
("4", "INTACT HYMEN ≠ VIRGINITY. RUPTURED HYMEN ≠ NON-VIRGINITY. Septate/cribriform hymen may be intact after intercourse."),
("5", "Hydrostatic (Docimasia) test: FLOAT = Liveborn (air in alveoli). SINK = Stillborn. Exception: putrefaction causes false float."),
("6", "MIFEPRISTONE + MISOPROSTOL = legal medical abortion up to 9 weeks (63 days) under MTP Act."),
("7", "IPC 377 Navtej (2018): consensual adult homosexual acts decriminalised. Bestiality still criminal (life imprisonment or 10 yrs)."),
("8", "Surrogacy Regulation Act 2021: ALTRUISTIC surrogacy LEGAL; COMMERCIAL surrogacy BANNED."),
("9", "Turner syndrome: 45,XO — SHORT STATURE + WEBBED NECK + PRIMARY AMENORRHOEA + STREAK GONADS + INFERTILE."),
("10","IMPOTENCY = consummation failure → marriage annulment. STERILITY = fertility failure → paternity dispute."),
("11","Stillborn: registered; born dead >28 wks. Deadborn macerated: not registered if <28 wks."),
("12","Criminal abortion (IPC 312): 3 yrs RI with woman's consent; 7 yrs without. Death of woman = higher punishment (IPC 314)."),
("13","Fimbriated hymen: irregular edges — FORENSIC TRAP; may appear ruptured but is a normal variant."),
("14","Hegar's sign = 6-8 wks. Goodell's = 5-6 wks. Chadwick's = 6-8 wks. Quickening = 16-18 wks primipara."),
]
for num, pt in imp_pts:
data = [[Paragraph(f"<b>{num}.</b>", ParagraphStyle('n', fontName='Helvetica-Bold', fontSize=10, textColor=GOLD)),
Paragraph(pt, ParagraphStyle('t', fontName='Helvetica', fontSize=9.5, leading=13, textColor=DARK))]]
t = Table(data, colWidths=[0.7*cm, W-0.7*cm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0),(-1,-1), HLBG if int(num)%2==0 else WHITE),
('BOX', (0,0),(-1,-1), 0.5, LIGHT),
('VALIGN', (0,0),(-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0),(-1,-1), 4),
('BOTTOMPADDING',(0,0),(-1,-1), 4),
('LEFTPADDING', (0,0),(-1,-1), 5),
]))
story.append(t)
story.append(sp(0.05))
doc.build(story, onFirstPage=on_page, onLaterPages=on_page)
print(f"PDF created: {path}")
if __name__ == "__main__":
build("/home/daytona/workspace/chapter10/Chapter10_Reproductive_Forensics.pdf")
cd /home/daytona/workspace/chapter10 && node chapter10_ppt.js 2>&1 & python3 cha…
cd /home/daytona/workspace/chapter10 && node chapter10_ppt.js 2>&1
cd /home/daytona/workspace/chapter10 && python3 chapter10_pdf.py 2>&1
Chapter10 Reproductive Forensics
Presentation · PPTX
Chapter10 Reproductive Forensics
PDF Document · PDF
| Slide/Section | Topic | Q No. |
|---|---|---|
| Natural vs Criminal Abortion | Definitions, types, IPC 312, table | Q27/52 |
| Unnatural Sexual Offences | IPC 377, Navtej 2018, all types | Q39 |
| Signs of Pregnancy | Presumptive / Probable / Positive — 5 confirmatory signs | Q56/68/164 |
| MTP Act 1971 + 2021 | Gestational flowchart, grounds, consent, amendments | Q60/104/152 |
| Stillborn vs Deadborn | Differences, registration rules | Q74 |
| Signs of Liveborn | Hydrostatic test flowchart + decision branching | Q169 |
| Types of Hymen | 7 types + forensic traps | Q78 |
| True vs False Virgin | Key forensic distinction | Q112 |
| Abortifacient Drugs | Ecbolics, emmenagogues, legal (Mifepristone+Misoprostol) | Q115 |
| Bestiality + Impotency | IPC 377, Impotency vs Sterility table | Q149/165 |
| Surrogacy + Intersex + Turner | 2021 Act, hermaphroditism, 45,XO features | Q25/31/88 |
| High-Yield Points | 14 numbered exam-ready points | All |
#2C3E50) and gold (#D4AC0D) — clean, print-friendly, and easy on the eyes.