HOW BOOKKEEPER FILLS THE OFFICIAL 2025 FORMS — field map specification
======================================================================

Bookkeeper prints a return by filling the official PDF forms in forms/2025/. Each template gets one
JSON map in maps/2025/<template name without .pdf>.json that says which PDF field (IRS fill-in forms)
or which page position (Connecticut forms, which have no fill-in fields) holds each line.

Keys
----
* Line amounts are keyed by the OFFICIAL LINE NUMBER exactly as printed on the form, lower-case letters,
  no "Line": "1a", "1z", "2b", "11a", "12e", "13b", "25d", "35a", "5e", "8z" ...
* When a line has several amount columns (e.g. Schedule D line 1b columns (d) (e) (g) (h); Form 8582 line 1a
  vs 1b), use "<line>.<column letter>" for columns: "1b.d", "1b.e", "1b.g", "1b.h".
* A line whose amount field sits in an inner column AND that also has a separate right-column amount (e.g.
  Form 1040 "2a" inner, "2b" right) — just use each printed line number.
* Text and check boxes that are not line amounts use the SLOT NAMES listed below. If a form has a slot that
  isn't listed, invent a short descriptive slot name and list it in "notes".
* Map EVERY fill-in field on the pages listed for your form, even ones Bookkeeper doesn't use yet.

IRS fill-in forms (AcroForm fields)
-----------------------------------
Use the FULL qualified field name as returned by pypdf `PdfReader(...).get_fields()` keys, e.g.
"topmostSubform[0].Page1[0].f1_47[0]". For check boxes give the field name AND the export value that means
"checked" (from the widget's /AP /N keys other than /Off, e.g. "/1"); radio-style groups share one name with
different export values — record each option's value.

{
  "template": "f1040.pdf",
  "lines":  {"1a": "topmostSubform[0].Page1[0]....f1_47[0]", ...},
  "text":   {"tp.first": "...", "tp.last": "...", ...},
  "checks": {"fs.single": {"field": "...", "on": "/1"}, ...},
  "rows":   {"dependents": [ {"first": "...", "last": "...", "ctc": {"field": "...", "on": "/1"}, ...}, ... ]},
  "parens_preprinted": ["7a"],          // lines where the form itself prints ( ) around the amount
  "comb_fields": {"tp.ssn": 9},          // fields with a MaxLen comb (digits only)
  "notes": "anything unusual"
}

Connecticut forms (no fill-in fields — Bookkeeper prints text at positions)
---------------------------------------------------------------------------
Coordinates are PDF points with origin at the BOTTOM-LEFT of the page (as pdftotext -bbox reports y from the
top: convert with y_pdf = page_height - y_top). For amounts give the x of the RIGHT edge where the last digit
should end (just left of the pre-printed ".00"), and the baseline y. Text slots: left x and baseline y.
Check boxes: the x/y of the box's lower-left corner and its size (Bookkeeper draws an "X").

{
  "template": "ct-1040_1225.pdf",
  "page_size": [612, 792],
  "lines":  {"1": {"page": 0, "x": 540.0, "y": 470.5, "align": "right", "size": 10}, ...},
  "text":   {"tp.first": {"page": 0, "x": 40.0, "y": 690.0, "size": 10}, ...},
  "checks": {"fs.single": {"page": 0, "x": 33.0, "y": 600.0, "w": 8, "h": 8}, ...},
  "rows":   {"withholding": [ {"fein": {...}, "wages": {...}, "withheld": {...}}, ... ]},
  "notes": "..."
}

Standard slot names
-------------------
Names / address (every form's "Name(s) shown on return" box is "names"; its SSN box is "ssn"):
  tp.first, tp.last, tp.ssn, sp.first, sp.last, sp.ssn, addr.street, addr.apt, addr.city, addr.state,
  addr.zip, addr.country, addr.province, addr.postal, names, ssn, occupation.you, occupation.spouse,
  phone, email
Form 1040 page 1:
  checks fs.single fs.mfj fs.mfs fs.hoh fs.qss, digital.yes digital.no, 12a.you 12a.spouse 12b 12c,
  12d.you65 12d.youblind 12d.sp65 12d.spblind, 6c 6d, 7b.nosd, campaign.you campaign.spouse
  text mfs_or_hoh_name (the box for the spouse's name if MFS / qualifying person's name if HOH/QSS)
  rows "dependents" (4 rows): first, last, ssn, relationship, plus whatever check boxes each row has
  (e.g. lived_with_you, student, disabled, ctc, odc) — describe them in notes
Schedule B: rows "interest" (payer, amount) and "dividends" (payer, amount); checks 7a.yes 7a.no 7b.yes 7b.no
  8.yes 8.no
Schedule C: text proprietor (= names), principal_business, code (line B), business_name, ein, biz_address,
  biz_city; checks method.cash method.accrual method.other, g.yes g.no, h (started this year),
  i.yes i.no, j.yes j.no
Schedule D: checks dispose_qof.yes dispose_qof.no, 20.yes 20.no
Schedule E (page 1, Part I): checks a.yes a.no, b.yes b.no; rows "properties" (3 rows A, B, C) with
  address, type, fair_days, personal_days, qjv (check), and amounts keyed "3", "4", "5" ... "22" for that
  column. Summary lines 23a–26 go in "lines".
Schedule SE: names, ssn; checks for church/minister boxes if any.
Form 8949: page 1 (Part I, short-term) and page 2 (Part II, long-term). checks st.A st.B st.C st.G st.H st.I
  and lt.D lt.E lt.F lt.J lt.K lt.L (use the letters printed on the boxes); rows "st_rows" and "lt_rows"
  with columns a b c d e f g h; totals "st.2.d" "st.2.e" "st.2.g" "st.2.h" and "lt.2.d" ... (line 2 of each part).
Form 8283 Section A: rows "items" (the 5 rows A–E) with donee, vehicle (check), description, date_contributed,
  date_acquired, how_acquired, basis, fmv, method — the form splits each row across two tables; put both halves
  in the same row object.
Form 8812 / 2441 / 6251 / 8582 / 8959 / 8960 / 8995 / 8995-A / 5329 / Schedules 1, 1-A, 2, 3, A: lines by
  number; names and ssn slots; Form 2441 Part I rows "providers" and Part II rows "persons" if present;
  Schedule 1-A vehicle rows "vehicles" (vin, interest) if present; Form 8995 rows "businesses"
  (name, ein, qbi) lines 1i–1v; Form 8995-A rows per column A/B/C.
CT-1040 (4 pages): lines "1"…"30" (and "18a"…"18f" withholding rows: rows "withholding" with fein, wages,
  withheld), Schedule 1 "31"…"50" incl. "36a" "48a" "48b" "48c" "48d", Schedule 2 "51"…"59",
  Schedule 3 "60"…"68", Schedule 4 "69a"…"69d" "69", Schedule 5 "70a"…"70h" "70"; header slots as above
  plus checks fs.single fs.mfj fs.mfs fs.hoh fs.qss, and any check boxes for deceased / CT-1040 EXT /
  form CT-2210 / Schedule CT-Dependent attached (describe in notes).
Schedule CT-EITC: lines "1"…"16" incl. "15a"; qualifying child rows "children" (name, ssn, dob, relationship,
  months) if present; names/ssn.

Verify before finishing
-----------------------
Fill a copy of the form with every key's own name as its value (amount fields: the line key, e.g. "12e";
text fields: the slot name), render with `pdftoppm -r 80 -png`, LOOK at every page image, and fix anything in
the wrong place. For CT, draw the key text at your coordinates on an overlay and look likewise.
