OllinDocs
Data flow & contracts

View models

Every display derivation in one place — labels, ordering, colors, and the 169-class math.

src/lib/api/view-model.ts (postflop) and preflop-view-model.ts (preflop) turn wire documents into view objects. Components render view objects and never see wire shapes — so every derivation exists exactly once.

Action colors

ACTION_COLORS in view-model.ts is the single palette for the whole product:

TokenHexUsed for
fold #3d72d9Fold
passive #3aa657Check, call
betSm #e56a4bBets < 45% pot
betLg #cc3d31Bets 45–90% pot
betXl #93261fBets ≥ 90% pot, jams, all-in

Postflop picks the bet tint from fraction_pot. Preflop tints raises by escalation level along the line — first raise betSm, 3-bet betLg, 4-bet and beyond (and all-ins) betXl — since preflop raise sizes are raise-to totals, not pot fractions.

Display order

actionDisplayOrder sorts actions for every bar, matrix cell, and summary: biggest bet leftmost, then smaller bets, then check/call, fold always at the right edge. The matrix paints cell bands in this order, so the blue fold band consistently anchors the right side of every cell.

Labels

  • actionLabel: Fold, Check, Call 1.5, Bet 28.4 (55%), Raise 4.6 (50%), All-in 100 — amounts at one decimal unless a second is significant.
  • Preflop sizes trim trailing zeros (r2.3 → "Raise 2.3", r25 → "Raise 25").
  • Line labels: limp → "Limped pot", srp/srp_btn_bb → "Single-raised pot" (with the BTN-vs-BB / SB-vs-BB qualifier preflop-side), 3bp/3bet_call → "3-bet pot", 4bp/4bet_call → "4-bet pot", 5bet_call → "5-bet pot".

The 169-class math

src/lib/api/aggregate.ts holds the combinatorics; src/lib/poker/classes.ts the grid layout:

  • comboClass maps a combo id to its class ("AhKh""AKs").
  • Class capacity: pair 6, suited 4, offsuit 12 combos; a full range is 1326.
  • buildGrid169 mirrors the server aggregation exactly (reach-weighted means) — used only for mock data; when a live document is present its server-sent grid169 is authoritative and never recomputed.
  • Class view numbers: combos = summed reach weight; weight = share of the class's live combos; rangePct = total combos ÷ 1326.

Postflop node view (toNodeView)

Derives the strategy-browser screen: per-class view strategies with perCombo drilldowns, range-wide action frequencies and combo counts (reach-weighted), the facing-bet detection for the pot-odds readout (pot odds bet/(pot+2·bet), MDF pot/(pot+bet), SPR eff/pot), and ipWeightsUniform (from meta.ip_weights_uniform, defaulting to true for tier root).

Preflop screen assembly (assemblePreflopScreen)

The preflop view model walks the line through the pack:

  1. Start at root with each seat's full range.
  2. At each step, fold the acting seat's arriving range through the strategy of the action it took (range × frequency per class) — so every seat's displayed range is the exact product of its taken-action frequencies.
  3. Track raise escalation for color assignment, accumulate breadcrumb steps, and stop at a decision node or terminal.
  4. At terminals, resolve the boundary (if heads-up) and both arriving ranges.

It also drives implied-fold navigation: clicking a later seat's action prepends the intermediate fold tokens to the line.

URL state helpers live here too: preflopHref(depth, line) and the """root" line/node_path conversion.

Formatting

src/lib/utils.ts: percentages at one decimal (16.9%), combo counts at one decimal (223.5), bb amounts as 5.0bb. The app body sets font-variant-numeric: tabular-nums so every figure aligns.

On this page