# `PhoenixLiveGantt`
[🔗](https://github.com/mdon/phoenix_live_gantt/blob/v0.4.0/lib/phoenix_live_gantt.ex#L1)

Waterfall (Gantt) view — horizontal bars on a date-range axis.

Each item is rendered as a row with a horizontal bar whose left edge
corresponds to its start date and width corresponds to its duration.
Optionally draws SVG connector lines between dependent items using
orthogonal (right-angle) routing — the industry-standard approach for
Gantt dependency arrows.

## Features

- Multi-zoom: `:day`, `:week`, `:month` granularity
- Today marker (vertical line)
- Non-working day shading via `day_markers`
- Progress indicator (fill percentage via `extra.progress_pct`)
- Milestones (zero-duration items rendered as diamonds)
- Orthogonal dependency connectors with arrow heads
- Configurable bar labels — inside / outside / fit / watermark (`label_position`)
- Sticky sidebar label column on horizontal scroll
- Grouping via `extra.group` field
- Custom item rendering via `:item` slot

## Data mapping

Waterfall uses the standard `PhoenixLiveGantt.Task` struct:

| Waterfall concept | Event field |
|-------------------|------------|
| Task name         | `title` |
| Start date        | `start` (Date) |
| End date          | `end` (Date, exclusive) |
| Duration          | Computed from start/end |
| Status/color      | `color`, `status` |
| Progress          | `extra.progress_pct` (0–100) |
| Group/phase       | `extra.group` or `category` |
| Assignee          | `extra.assignee` |
| Milestone         | When start == end (zero duration) |

Connectors are passed separately as a list of
`%{from: event_id, to: event_id}` maps.

## Coordinate system

Everything is pixel-based against a fixed content width
(`total_days × day_width_px + 2 × axis_pad`, where `axis_pad` is a fixed
16px margin on each side that gives edge connectors room — see
`axis_pad_px/0`). This keeps bar positions, grid columns, today marker, and
connector arrows aligned no matter the flex context.

# `axis_pad_px`

```elixir
@spec axis_pad_px() :: non_neg_integer()
```

The fixed horizontal margin (px) reserved on EACH side of the time axis so a
connector exiting/entering a task at the very edge of the window has room to
draw instead of clipping. The natural content width is
`total_days × day_width_px + 2 × axis_pad_px()`. A consumer computing a
fit-to-width `day_width_px` from a measured viewport should subtract
`2 × axis_pad_px()` first.

# `default_day_width_px`

```elixir
@spec default_day_width_px(atom()) :: pos_integer()
```

The default pixels-per-day for a zoom level — `:hour` 720, `:day` 40,
`:week` 24, `:month` 8. Use it as the floor when computing a fit-to-width
`day_width_px` override, so fitting only ever *widens* (and a long chart still
scrolls at its natural density).

# `gantt`

Renders a Gantt / waterfall chart — horizontal task bars on a time axis with
orthogonal dependency connectors, milestones, sub-projects, and a built-in
popover.

Pass a list of `PhoenixLiveGantt.Task` structs as `events` and a `Date.Range` as
`date_range`; everything else is optional. Each attribute below documents its
own default and behavior. The smallest useful call:

    <PhoenixLiveGantt.gantt events={@tasks} date_range={@range} />

Note: no stylesheet ships — your app's Tailwind must scan this library as a
content source (see the README), and the JS hooks (`priv/static/assets/
phoenix_live_gantt.js`) must be registered for the popover / scroll-to-today.

## Attributes

* `events` (`:list`) - Defaults to `[]`.
* `date_range` (`Date.Range`) (required) - The visible date axis. At `:week` / `:month` column granularity the axis is snapped OUTWARD to whole-week (Mon–Sun) / whole-month boundaries so columns are complete and boundary-aligned — pass a tight, task-fitted range and the chart rounds it out to full weeks/months on its own (bars keep their true dates within the widened axis). Finer granularities use the range as-is. NOTE: the granularity is resolved from the pixel density, so a `day_width_px` override (not the named `zoom`) decides whether snapping applies — a density in the week/month band snaps. Ignored in favor of `window_start`/`window_end` when a positive sub-day window is supplied.
* `window_start` (`NaiveDateTime`) - Optional sub-day positioning origin. When `window_start`/`window_end` are both `NaiveDateTime`s, the window becomes the axis: it drives the start/end instants, the columns, event partition (in-window vs the `← N earlier / N later →` edge counts), and the today marker — instead of `date_range`'s midnight-to-midnight span. Useful at `:hour`/`:min15`/`:min5` zoom to begin ~1 column before the first task rather than at midnight (a wall of empty pre-task columns). Snap `window_start` to a column-slot boundary so labels land on round clock times. `date_range` remains required as the base axis and is used whenever the window is absent or non-positive, so keep it covering the same span. Defaults to `nil`.
* `window_end` (`NaiveDateTime`) - Sub-day positioning end instant. See `window_start`. Defaults to `nil`.
* `zoom` (`:atom`) - Defaults to `:week`.
* `connectors` (`:list`) - Defaults to `[]`.
* `day_markers` (`:list`) - Non-working / highlighted day ranges, shaded in the grid. Each is a `%{start_date: Date.t(), end_date: Date.t() | nil, available: boolean()}` (an `end_date` of `nil` means a single day; `available: false` shades it as non-working). Defaults to `[]`.
* `day_width_px` (`:integer`) - Override the per-zoom pixels-per-day. The natural content width is `total_days * day_width_px + 2 * axis_pad_px()` (the pad reserves room for edge connectors); that is the scroll `min-width`. The chart is responsive and fills wider containers on its own (horizontal coords are percentages), so use this only to tune density / the scroll threshold. `nil` uses the zoom default. Defaults to `nil`.
* `min_bar_px` (`:integer`) - Minimum rendered width (px) for a non-milestone bar. Default `0` — bars reflect their TRUE duration, so a task too short to show at the current zoom is a hairline (or vanishes) until you zoom in. Set e.g. `4` to floor every bar to a visible/clickable sliver at the cost of overstating very short tasks' spans (connectors still attach to the rendered edge). A zero-DURATION task is always a milestone diamond regardless of this value. Defaults to `0`.
* `today` (`:any`) - Today's date (a `Date`), or a `DateTime`/`NaiveDateTime` for a precise 'now' line — recommended at `:hour` zoom, where the marker lands at the exact time and the current-hour column highlights. Defaults to `Date.utc_today()`. Defaults to `nil`.
* `row_height` (`:string`) - Height of each task row, as a CSS length. Drives the chart's vertical density. Defaults to `"2.5rem"`.
* `label_width` (`:string`) - Width of the sticky sidebar label column (the task-name column), as a CSS length. Defaults to `"14rem"`.
* `on_event_click` (`:any`) - phx-click event name fired when a bar/milestone is clicked (requires `enable_hooks`). The handler receives the event id under the `"event-id"` param key (hyphen). Defaults to `nil`.
* `expanded` (`:any`) - Which sub-projects are expanded (children visible). A `MapSet` or list of expanded event ids, `:all` to expand everything, or `nil` for all collapsed. Collapsed parents' children are hidden and connectors retarget to the visible ancestor. Defaults to `nil`.
* `on_toggle_expand` (`:any`) - phx-click event name fired when a sub-project chevron is toggled. The handler receives the event id under the `"event-id"` param key (hyphen). Update your `expanded` set in response — see `PhoenixLiveGantt.toggle_expanded/2`. Defaults to `nil`.
* `show_progress` (`:boolean`) - Defaults to `true`.
* `show_today` (`:boolean`) - Defaults to `true`.
* `label_position` (`:atom`) - Where each bar's default title renders. `:none` — no bar label (lean on the sidebar; bars stay clean). `:inside` — overlaid on the bar, clipped or spilling per `label_overflow` (a short bar may show a stub). `:outside` — in the empty track beside the bar, never clipped (best when bars are short). `:fit` — overlaid on the bar but HIDDEN on bars too narrow to show at least `label_fit_ratio` of the label, so you get the label on the bars that fit it and a clean bar (no stub) on the ones that don't. The fit test is a pure-CSS container query against the bar's RENDERED width, so it tracks the responsive fill at every zoom with no JavaScript. `:watermark` — like `:outside` (one copy in the empty track beside the bar, after the bar then flipping to before near the right edge), but rendered big, heavy and italic as a soft annotation (tune the softness with `label_watermark_opacity`). Rendered as a sibling overlay in every mode, so the bar's `overflow-hidden` never clips an `:outside`/`:visible` label. Defaults to `:inside`. Must be one of `:none`, `:inside`, `:outside`, `:fit`, or `:watermark`.
* `label_side` (`:atom`) - Which side / alignment the label takes. For `:outside`: `:right` = just past the bar's end, `:left` = just before its start, `:auto` = after the bar but flips to before when it would run past the right edge. For `:inside`/`:fit`: text alignment within the bar (`:right` hugs the end, `:left`/`:auto` the start). Defaults to `:auto`. Must be one of `:auto`, `:left`, or `:right`.
* `label_overflow` (`:atom`) - How an `:inside` label handles a bar too narrow for it: `:truncate` clips with an ellipsis (…), `:clip` clips hard (no ellipsis), `:visible` lets the text spill past the bar's edge (not clipped). No effect for `:outside` (never clipped), `:fit` (always truncates the shown ones), or `:none`. Defaults to `:truncate`. Must be one of `:truncate`, `:clip`, or `:visible`.
* `label_fit_ratio` (`:float`) - For `label_position: :fit`, the minimum fraction of the label that must fit within the bar's RENDERED width for the label to show at all (0.5 = half, 1.0 = only when it fully fits). Bars narrower than that hide the label entirely instead of showing a clipped stub. Evaluated in the browser via a container query, so it stays correct under the responsive fill at every zoom. The label's width is estimated from its character count, so the threshold is approximate. Defaults to `0.5`.
* `label_watermark_opacity` (`:float`) - For `label_position: :watermark`, the opacity of the big italic label beside the bar (0–1). Soft by default so it reads as a quiet annotation rather than a loud title. Defaults to `0.5`.
* `show_today_edge` (`:boolean`) - Show the floating directional `← Today` / `Today →` pill when today is off-screen. Independent of `show_today` (which controls the in-range today line), so you can keep the line but drop the off-screen hint. Defaults to `true`.
* `show_connectors` (`:boolean`) - Defaults to `true`.
* `tiny_bar_px` (`:integer`) - When a bar renders narrower than this many SCREEN pixels, a small fixed-size down-triangle marker appears at the task's start to signal a too-small-to-see task. The decision is pure CSS — a container query against the bar's rendered width — so it's server-emitted, correct against the responsive fill + zoom, instant on first paint, and re-resolves on resize with no JavaScript. (Clicking the marker opens the same popover, which does need `enable_hooks`.) Set `0` to disable. Bars themselves stay at their true width — see `min_bar_px`. Assumes a uniform value across charts sharing a page. Defaults to `5`.
* `avoid_collisions` (`:boolean`) - When true, connector trunks are shifted to avoid crossing unrelated bars. Turn off for very large Gantts or when you prefer strict bus alignment. Defaults to `true`.
* `label_background` (`:atom`) - How connector labels render. :halo (default) paints each glyph with a base-100 outline so the line shows between letters. :rect draws a solid base-100 rectangle behind the text — stronger contrast over bars but can leave visible gaps in the line around narrow words. Defaults to `:halo`. Must be one of `:halo`, or `:rect`.
* `connector_color_class` (`:string`) - Defaults to `"text-base-content/50"`.
* `connector_stroke_width` (`:float`) - Defaults to `1.5`.
* `connector_opacity` (`:float`) - Defaults to `1.0`.
* `connector_dasharray` (`:string`) - Defaults to `"none"`.
* `critical_color_class` (`:string`) - Defaults to `"text-primary"`.
* `critical_stroke_width` (`:float`) - Defaults to `2.25`.
* `invalid_color_class` (`:string`) - Defaults to `"text-error"`.
* `invalid_stroke_width` (`:float`) - Defaults to `2.0`.
* `invalid_dasharray` (`:string`) - Defaults to `"4 3"`.
* `connector_elbow_px` (`:integer`) - Defaults to `10`.
* `connector_bar_clearance_px` (`:integer`) - Defaults to `10`.
* `bus_split_offset_pct` (`:integer`) - Used by `bus_attach_mode={:type_zoned}`. When a bar side has both incoming and outgoing arrows, this is the % offset from the bar's top edge for outgoing attachment (incoming mirrors). Default 40 → 40%/60% split. Set to 50 to disable the split. Defaults to `40`.
* `bus_attach_mode` (`:atom`) - How arrow endpoints attach to a bar edge when multiple arrows touch it:
    * `:smart` (default) — each arrow's attach y depends on the OTHER end's row.
      Outgoing arrows going DOWN attach to the bar bottom; outgoing arrows going UP
      attach to the bar top. Incoming arrows from ABOVE land on the upper-middle of
      the bar; from BELOW land on the lower-middle. Up to 4 designated y positions
      per side. If only one of these positions is in use → collapses to bar center.
    * `:type_zoned` — outgoing always at top, incoming always at bottom (regardless
      of direction). Uses `bus_split_offset_pct`.
    * `:center` — disable splits entirely; everything attaches at the bar center.
  Per-task override: set `extra.bus_attach_mode` on an event to one of these atoms.

  Defaults to `:smart`. Must be one of `:smart`, `:type_zoned`, or `:center`.
* `bus_attach_inner_pct` (`:integer`) - Smart mode only. % offset from bar edge for both attach positions. Default 40 → split at 40%/60% of bar height. Smart mode picks one for outgoing (by majority outgoing direction) and the opposite for incoming. Defaults to `40`.
* `bus_stagger_outgoing_px` (`:integer`) - Stagger trunk x by this many px per lane for arrows in the SAME outgoing bus (multiple outgoing from one source on one side). Default 0 = merged (single trunk). Set to 3-5 to fan out each outgoing arrow into its own visible lane. Per-task override via `extra.bus_stagger_outgoing_px`. Defaults to `0`.
* `bus_stagger_incoming_px` (`:integer`) - Stagger trunk x by this many px per lane for arrows in the SAME incoming bus (multiple incoming to one target on one side). Default 0 = merged. Per-task override via `extra.bus_stagger_incoming_px`. Defaults to `0`.
* `bus_stagger_corner_clearance_px` (`:integer`) - When stagger is active and a bar side has multiple arrows, lanes are distributed evenly across the bar's FLAT region (excluding rounded corners) so no arrow emerges from a corner. This sets the corner radius to avoid; default 4 matches Tailwind's `rounded` (4px) on the default `bar_class`. Set to 0 if your bar isn't rounded. Defaults to `4`.
* `main_header_class` (`:string`) - Defaults to `"flex sticky top-0 z-20"`.
* `label_header_class` (`:string`) - Defaults to `"sticky left-0 z-20 flex-shrink-0 bg-base-100 border-r border-base-content/10 border-b-2 border-b-base-content/15 px-3 py-2 font-semibold text-sm text-base-content"`.
* `column_header_class` (`:string`) - Defaults to `"text-xs text-center py-2 border-r border-base-content/5 font-medium flex-shrink-0"`.
* `column_header_today_class` (`:string`) - Defaults to `"bg-primary/10 font-bold text-primary"`.
* `column_divider_class` (`:string`) - Defaults to `"border-r border-base-content/5 h-full flex-shrink-0"`.
* `non_working_class` (`:string`) - Defaults to `"bg-base-content/[0.04]"`.
* `row_class` (`:string`) - Defaults to `"relative border-b border-base-content/5 hover:bg-base-content/[0.02]"`.
* `label_col_class` (`:string`) - Defaults to `"sticky left-0 flex-shrink-0 bg-base-100 border-r border-base-content/10"`.
* `label_row_class` (`:string`) - Defaults to `"flex items-center px-3 border-b border-base-content/5 overflow-hidden cursor-pointer hover:bg-base-content/[0.02]"`.
* `group_header_class` (`:string`) - Defaults to `"flex items-center bg-base-200/50 border-b border-base-content/10 px-3"`.
* `group_header_text_class` (`:string`) - Defaults to `"text-xs font-bold uppercase tracking-wider text-base-content/60 truncate"`.
* `group_spacer_class` (`:string`) - Defaults to `"bg-base-200/50 border-b border-base-content/10 relative"`.
* `bar_class` (`:string`) - Defaults to `"absolute top-1 bottom-1 rounded cursor-pointer overflow-hidden flex items-center z-10"`.
* `bar_subproject_class` (`:string`) - Defaults to `"ring-1 ring-base-content/30 ring-offset-0 [background-image:repeating-linear-gradient(135deg,transparent_0_6px,rgba(0,0,0,0.08)_6px_7px)]"`.
* `subproject_frame_color` (`:any`) - Defaults to `["color-mix(in oklab, var(--color-warning) 15%, transparent)", "color-mix(in oklab, var(--color-info) 15%, transparent)", "color-mix(in oklab, var(--color-success) 15%, transparent)", "color-mix(in oklab, var(--color-secondary) 15%, transparent)"]`.
* `bar_background_class` (`:string`) - Defaults to `"absolute inset-0 rounded"`.
* `bar_default_color_class` (`:string`) - Defaults to `"bg-primary"`.
* `bar_title_class` (`:string`) - Defaults to `"text-xs font-medium"`.
* `bar_title_cancelled_class` (`:string`) - Defaults to `"line-through"`.
* `progress_class` (`:string`) - Defaults to `"absolute inset-y-0 left-0 rounded-l"`.
* `progress_complete_radius_class` (`:string`) - Defaults to `"rounded-r"`.
* `progress_incomplete_class` (`:string`) - Defaults to `"bg-base-content/20"`.
* `progress_complete_class` (`:string`) - Defaults to `"bg-success/40"`.
* `milestone_class` (`:string`) - Defaults to `"absolute top-1/2 z-40 cursor-pointer w-4 h-4 border-2"`.
* `milestone_default_color_class` (`:string`) - Defaults to `"bg-primary"`.
* `milestone_status_cancelled_class` (`:string`) - Defaults to `"opacity-50"`.
* `status_tentative_class` (`:string`) - Defaults to `"opacity-60"`.
* `status_cancelled_class` (`:string`) - Defaults to `"opacity-40"`.
* `status_pending_approval_class` (`:string`) - Defaults to `"animate-pulse"`.
* `status_no_show_class` (`:string`) - Defaults to `nil`.
* `status_blocked_class` (`:string`) - Defaults to `"opacity-60 grayscale"`.
* `bar_popover_class` (`:string`) - Defaults to `"absolute z-[60] max-w-md rounded-md shadow-lg border-2 border-base-content overflow-hidden hidden"`.
* `bar_popover_title_class` (`:string`) - Defaults to `"flex items-center px-2 text-xs font-medium whitespace-normal break-words leading-tight"`.
* `bar_popover_subtitle_class` (`:string`) - Defaults to `"px-2 pb-1 text-[0.65rem] opacity-80 leading-tight"`.
* `bar_popover_actions_class` (`:string`) - Defaults to `"flex gap-1 px-2 py-2"`.
* `bar_action_button_class` (`:string`) - Defaults to `"relative inline-flex items-center justify-center w-7 h-7 rounded hover:bg-base-content/15 cursor-pointer"`.
* `bar_action_disabled_class` (`:string`) - Defaults to `"opacity-50 cursor-not-allowed pointer-events-none"`.
* `label_popover_class` (`:string`) - Defaults to `"absolute left-2 right-2 z-[60] rounded-md shadow-lg border-2 border-base-content overflow-hidden hidden"`.
* `badge_class` (`:string`) - Defaults to `"absolute z-50 inline-flex items-center justify-center px-1 min-w-[1rem] h-4 text-[0.55rem] font-bold rounded-full ring-1 ring-base-100 leading-none pointer-events-none"`.
* `badge_default_color_class` (`:string`) - Defaults to `"bg-error"`.
* `today_marker_line_class` (`:string`) - Defaults to `"absolute top-0 w-0.5 bg-error z-30 pointer-events-none"`.
* `today_marker_badge_class` (`:string`) - Defaults to `"absolute -translate-x-1/2 z-10 bg-error text-error-content text-[0.6rem] leading-none px-1.5 py-0.5 rounded font-bold whitespace-nowrap pointer-events-none"`.
* `translations` (`:map`) - Overrides for the chart's own CHROME strings — toolbar buttons, the Today label, prev/next, edge counts, popover/expand labels, and short month names. Shape: `%{labels: %{atom => String.t()}, month_names_short: %{1..12 => String.t()}}`; anything omitted falls back to the English default. See `PhoenixLiveGantt.Utils.I18n` for the full key list. This does NOT translate task content (titles, assignees, action tooltips) — you pass those already-localized in each `PhoenixLiveGantt.Task`, so they work with any backend (gettext, Cldr, a JSONB multilang column, …). Defaults to `%{}`.
* `class` (`:string`) - Defaults to `""`.
* `dir` (`:atom`) - Defaults to `:ltr`.
* `id` (`:string`) - Stable DOM id. Required when `show_header` is true OR `auto_scroll_today` is on, so JS dispatches target the right gantt instance when multiple are on the page. Defaults to `nil`.
* `show_header` (`:boolean`) - Defaults to `false`.
* `show_zoom_switcher` (`:boolean`) - Defaults to `true`.
* `show_today_button` (`:boolean`) - Defaults to `true`.
* `show_navigation` (`:boolean`) - Defaults to `true`.
* `zooms` (`:list`) - Defaults to `[:day, :week, :month]`.
* `on_zoom_change` (`:any`) - Defaults to `nil`.
* `on_navigate` (`:any`) - Defaults to `nil`.
* `on_scroll_today` (`:any`) - Defaults to `nil`.
* `toolbar_class` (`:string`) - Defaults to `"lg-toolbar flex items-center justify-between gap-3 px-3 py-2 border-b border-base-content/15 bg-base-100"`.
* `show_edge_indicators` (`:boolean`) - Defaults to `true`.
* `on_show_earlier` (`:any`) - Defaults to `nil`.
* `on_show_later` (`:any`) - Defaults to `nil`.
* `on_show_today` (`:any`) - phx-click event for the off-screen Today hint (shown when `today` is outside `date_range`). Wire it to widen the range / jump to today; if nil the hint is informational only. Requires `show_today`. Defaults to `nil`.
* `edge_indicator_class` (`:string`) - Defaults to `"lg-edge px-2 py-1 rounded-full bg-base-200/95 border border-base-content/10 text-[0.65rem] font-medium text-base-content/70 shadow-sm hover:bg-base-200 transition-colors"`.
* `enable_hooks` (`:boolean`) - When true, attaches BOTH JS hooks: `LgAutoScroll` on the container (auto-scroll + today button) and `LgBarPopover` on every bar/milestone/label (the click popover + dependency-tree highlight). Requires the PhoenixLiveGantt JS bundle (`priv/static/assets/phoenix_live_gantt.js`, registered as `window.PhoenixLiveGanttHooks`). Leave false if you don't ship the bundle — otherwise the browser logs an "unknown hook" error per element. Defaults to `false`.
* `auto_scroll_today` (`:boolean`) - On mount, scroll the timeline so today is horizontally centered (if today is in range and hooks are enabled). Defaults to `true`.
## Slots

* `item`
* `label`
* `toolbar_start` - Extra content rendered at the left of the toolbar, after the today/nav buttons.
* `toolbar_end` - Extra content rendered at the right of the toolbar, after the zoom switcher.

# `scroll_to_start`

```elixir
@spec scroll_to_start(Phoenix.LiveView.JS.t(), String.t()) :: Phoenix.LiveView.JS.t()
```

A `Phoenix.LiveView.JS` command that scrolls a chart's timeline back to its
start (leftmost column). Pair it with a "home"/"fit" button whose server
handler refits the window — the server can't move the scroll, and the built-in
scroll-to-today only fires when the today marker is in view, so a refit that
doesn't include today would otherwise leave the timeline scrolled to a stale
spot. Requires `enable_hooks` + the matching `id` (the `LgAutoScroll` hook
listens for the dispatched `lg:scroll-start`).

    <button phx-click={
      JS.push("fit_project") |> PhoenixLiveGantt.scroll_to_start("project-gantt-#{@id}")
    }>Project</button>

Composes with an existing `JS` command (e.g. a `JS.push/2`); pass it as the
first argument, or omit it to start a fresh command.

# `toggle_expanded`

```elixir
@spec toggle_expanded(MapSet.t() | list() | nil, term()) :: MapSet.t()
```

Toggles an id in an `expanded` set — convenience for `on_toggle_expand`
handlers so consumers don't re-write the member?/put/delete boilerplate.

Normalizes the first argument to a `MapSet` (accepts a `MapSet`, a list, or
`nil`) and returns a `MapSet`. The id should be the value delivered to your
handler under the `"event-id"` param key.

    def handle_event("toggle_subproject", %{"event-id" => id}, socket) do
      {:noreply, update(socket, :expanded, &PhoenixLiveGantt.toggle_expanded(&1, id))}
    end

---

*Consult [api-reference.md](api-reference.md) for complete listing*
