# Data sources and scope

Every number in `src/js/data.js` traces back to a specific table in **AS/NZS 3008.1.1:2017**
("Electrical installations — Selection of cables, Part 1.1"), except where noted below as an
approximation. This document is the single source of truth for what is and isn't covered —
keep it in sync whenever `data.js` changes.

Most of this document covers the **Cable Size Calculator** (`cable-size-calculator.html` /
`engine.js`) specifically, since it's by far the larger and older of the two calculators this
project hosts. The **Voltage Drop Calculator** (`voltage-drop.html` / `voltagedrop.js`) has its
own, much shorter section near the end — it reuses `data.js`'s tables directly but with different,
simpler assumptions (see "Voltage Drop Calculator" below).

## Current-carrying capacity (`CURRENT_RATING`)

| Block key | Standard table | Cable type | Insulation | Conductor | Notes |
|---|---|---|---|---|---|
| `MultiCore\|Thermoplastic` | Table 13 | Three-core and four-core | V-90 / V-90HT / V-75 (75°C class) | Copper (solid/stranded + Flexible) and Aluminium | Fully digitised, all 12 installation-method cards |
| `MultiCore\|X90` | Table 14 | Three-core and four-core | X-90 / X-HF-90 / R-EP-90 / R-HF-90 (90°C class) | Copper (solid/stranded) and Aluminium | Flexible not digitised — falls back to solid/stranded |
| `MultiCore\|110C` | Table 15 | Three-core and four-core, sheathed | X-110 / X-HF-110 / R-E-110 / R-HF-110 (110°C class) | Copper only | Aluminium not tabulated in the standard for this family. No separate unenclosed/enclosed thermal-insulation columns or combined/separate underground columns — see notes below |
| `MultiCore2C\|Thermoplastic` | Table 10 | **Two**-core sheathed | V-90 / V-90HT / V-75 | Copper (solid/stranded + Flexible) and Aluminium | Added 2026-08-23 — Table 10 is a physically separate ampacity table from Table 13, not a subset of it; "Multi-core 2C+E"/"Multi-core 2C (mains)" cabletypes previously (incorrectly) reused Table 13 |
| `MultiCore2C\|X90` | Table 11 | Two-core sheathed | X-90 / X-HF-90 / R-EP-90 / R-CPE-90 / R-HF-90 / R-CSP-90 | Copper (solid/stranded + Flexible) and Aluminium | Added 2026-08-23 |
| `MultiCore2C\|110C` | Table 12 | Two-core sheathed | R-HF-110 / R-E-110 / X-HF-110 | Copper only | Added 2026-08-23. Only one "Partially/Completely surrounded" column each (no unenclosed/enclosed split) and underground wiring enclosure has no separate Al column, matching Table 15's reduced column set |
| `SingleCore\|Thermoplastic` | Table 7 | Three single-core | V-90 / V-90HT / V-75 | Copper (solid/stranded + Flexible) and Aluminium | Includes the "one cable per enclosure" (separate duct) underground rating and a real, separately-tabulated "spaced from surface" column |
| `SingleCore\|X90` | Table 8 | Three single-core | X-90 family | Copper (solid/stranded + Flexible) and Aluminium | Same coverage as Table 7 |
| `SingleCore\|110C` | Table 9 | Three single-core | X-110 / X-HF-110 / R-E-110 / R-HF-110 | Copper only | Aluminium not tabulated in the standard for this family |

**Aluminium** is now digitised everywhere the standard tabulates it: Tables 7, 8, 13 and 14 all have
an Aluminium column, always starting at 16 mm² (Aluminium conductors aren't offered below that size
in the standard). Aluminium is **not** tabulated for the 110°C family (Tables 9, 15) or for Flexible
cores at all — both combinations return an explicit error rather than a guess.

**Not digitised:**
- Two-single-core cable types (Tables 4–6) — not exposed in the Cable type dropdown, so not needed
  yet. (Two-core sheathed, Tables 10–12, *is* now digitised — see `MultiCore2C|*` above.)
- Flexible-core ratings for anything other than `MultiCore|Thermoplastic`/`MultiCore2C|*` (and for
  Aluminium at all).

Each block covers the underlying figures for the 12 installation-method cards the dashboard shows,
drawn from AS/NZS 3008.1.1:2017 Tables 3(1)–3(4): spaced, spaced from surface, touching surface,
exposed to sun, wiring enclosure in air, partially/completely surrounded by thermal insulation
(enclosed and unenclosed), buried direct, and underground wiring enclosure (combined, and — with
real, distinct figures only for single-core cable — separate/one cable per enclosure).

**"Spaced" vs "Spaced from surface".** Single-core tables (7, 8, 9) genuinely tabulate both as
separate columns (`spaced` and `spacedSurface`) — these are real, distinct figures. Multicore tables
(13, 14, 15) only tabulate one "Spaced" column; for multicore cable, "Spaced from surface" falls back
to the "Spaced" figures as a documented approximation (see `resolveRatingArray()` in `engine.js`).

**"Underground wiring enclosure, separate"** (one cable per enclosure — each phase in its own duct)
only has real, distinct figures for single-core cable (`undOnePer` in the Table 7/8/9 blocks). For
multicore cable, which has nothing to separate, it falls back to the combined/bunched figures.

**Single-core "Partially/Completely surrounded by thermal insulation" only has one column each**
(Tables 7, 8, 9), unlike the multicore tables which split each into unenclosed/enclosed variants. The
"unenclosed" and "in wiring enclosure" UI methods reuse the same single-core figures for this reason
— not a transcription duplicate, that's what the standard actually provides for single-core cable.

**Table 15 (MultiCore 110°C) has fewer distinct columns than Tables 13/14**: one "Spaced" column (no
separate "from surface"), one "Partially surrounded" column and one "Completely surrounded" column
(no unenclosed/enclosed split — `partEncl`/`compEncl` are left `null` rather than guessed, so those
two install methods correctly show "no data" for this family), and one underground column (no
combined/separate split, falls back like other families with nothing to separate).

## Resistance (`RESISTANCE`)

Source: **Table 35** (a.c. resistance, multicore with circular conductors), columns for 45/60/75/90/
110°C conductor temperature, for both `Copper` and `Aluminium`. Table 34 (single-core) gives
near-identical values, so Table 35 is reused for both cable families rather than transcribing it
twice — verify this assumption if you need higher precision for single-core runs. Aluminium is only
tabulated in the standard from 16 mm² up and only at 45/60/75/90°C (no 110°C column) — this is not a
practical limitation here since `resistanceAt()` is only ever called at 90°C (see below).

**Corrected 2026-08-23** (previously said "resistance at 90°C regardless of operating temperature" —
that was wrong and has been fixed): per AS/NZS 3008.1.1:2017 Clause 4.4, voltage drop must use
resistance at the cable's **actual operating temperature** under the given load, not a fixed 90°C —
`opTemp = ambient + (loadCurrent/ratedCurrent)² × (maxInsulationTemp − ambient)`. The resistance is
then read from the **ceiling** tabulated column (the next tabulated temperature ≥ opTemp, never
interpolated) via `resistanceAtCeiling(size, opTemp, material)`. Confirmed against exact table/column
citations in all 4 jCalc.net reference PDFs (e.g. "Table 4.7(A), col 4, 60°C" for a 52°C op temp). The
old fixed-90°C lookup (`resistanceAt(size, 90, material)`) is kept as `R90` and used only for
loop-impedance/EFLI (fault-loop) calculations, which conventionally use worst-case (max permissible
temperature) resistance since a fault can occur after the cable has been loaded up to rating.

`resistanceAt(size, tempC, material)` picks `Copper` or `Aluminium` based on the `material` argument
— callers pass `inp.conductor` for the active core, or the earth core's own resolved material for the
earth-impedance box (see below).

## Reactance (`REACTANCE`)

**Corrected 2026-08-23** (previously only had the PVC column, used unconditionally — that was wrong
and has been fixed). Source: the **full** Table 30 (p.98), digitised directly from the user's own
AS/NZS 3008.1.1:2017 PDF — all three insulation-chemistry columns (PVC / XLPE / Elastomer) × all
three arrangement columns (Multicore-circular, Single-core Trefoil, Single-core Flat-touching).
`reactanceChemistry(insulation)` maps V-90/V-90HT/V-75 → PVC, X-90/X-HF-90/X-110/X-HF-110 → XLPE,
R-EP-90/R-HF-90/R-E-110/R-HF-110 → Elastomer. `reactanceArrayFor(cableFamily, insulation, formation)`
then picks the right array: Multi-core always uses the multicore-circular column; Single-cores uses
Trefoil or Flat-touching depending on the Formation dropdown. Table 30 does **not** vary by conductor
material — Copper and Aluminium conductors of the same size/geometry have the same reactance — so one
`REACTANCE` table is correctly used for both. The **earth conductor** for Single-cores cable always
uses the Flat-touching column regardless of the actives' own Formation selection (confirmed against
two independent reference scenarios) — physically, the earth conductor isn't part of the actives'
tight trefoil bundle.

## Earth core sizing (`EARTH_SIZE`, `EARTH_SIZE_CU_FOR_AL_ACTIVE`)

**Rebuilt from the primary source, 2026-09-06: AS/NZS 3000:2018 Table 5.1 ("MINIMUM COPPER EARTHING
CONDUCTOR SIZE"), Clause 5.3.3.1.2.** This table was previously back-solved from a 576-scenario
jCalc.net cross-check and a couple of reference screenshots — a reasonable approach when the
underlying clause wasn't available, but only ever an inference ("probably an AS/NZS 3000 clause",
per this file's own earlier wording). The user's AS/NZS 3000:2018 PDF was read directly and Table 5.1
located (it's an image-only/scanned PDF with no text layer, so this took rendering pages to images
and reading them, not a text search) — every one of the ~200 data points from the 576-scenario
cross-check, including its two extrapolated tail values, matches this table exactly.

**`EARTH_SIZE`** is Table 5.1's "With copper active conductors" column, used identically for both
`MultiCore` and `SingleCore` (the standard doesn't distinguish by cable family here). `SingleCore`
previously had no data above 185mm² at all (`null`) — a real gap, not a deliberate limit — now filled
in from the same table up to 500mm². The two smallest sizes (1mm², 1.5mm²) carry a footnote in the
standard restricting them to earth cores "incorporated in a multi-core cable or flexible cord" — kept
at the safer 2.5mm² fallback for `SingleCore`, where the earth is its own separate cable. Sizes above
500mm² need a manually-applied "≥120mm² / ≥25% of active size" floor per the table's own dagger
footnote — not modelled, since `SIZES` tops out at 500mm².

**Aluminium-active adjustment.** Single-cores and Multi-core diverge, and use different logic:
- **Single-cores**: `EARTH_SIZE_CU_FOR_AL_ACTIVE` is Table 5.1's "With aluminium active conductors"
  column — still a **Copper** earthing conductor, just paired with an Aluminium active (relevant here
  because Single-cores lets the earth conductor's material be chosen independently). This replaces an
  approximate "half the Aluminium active's CSA, rounded up" heuristic (added 2026-08-23, based on a
  single reference data point) that turned out wrong at several sizes once checked against the real
  table — e.g. a 50mm² Aluminium active gave a 6mm² Copper earth under the old heuristic; Table 5.1
  specifies 10mm². Aluminium conductors aren't tabulated (or manufactured, elsewhere in this
  calculator) below 16mm², matching Table 5.1's own blank cells there.
- **Multi-core**: the earth core is an **Aluminium** core the **same size as the active conductor**
  (1:1) — confirmed 2026-09-06 across every Aluminium active size the 576-scenario cross-check
  exercised (16mm² to 300mm², 13 distinct sizes, zero exceptions), and consistent with jCalc's own
  documented reasoning ("matches most commercial Aluminium cables"). This is handled directly in
  `computeSizing()` (`earth = size` when `conductor === "Aluminium" && cableFamily === "MultiCore"`)
  rather than via a lookup table, since Table 5.1 has **no Aluminium-earth column at all** — it only
  ever specifies Copper earth sizes, for either a Copper or an Aluminium active.

## Earth conductor material / insulation / flexibility

This behaviour was an explicit requirement, not something back-solved from a screenshot, so it's
worth stating plainly:

- **Multi-core cable** (3C+E/4C+E/4C mains): the earth core is physically inside the same sheath as
  the active conductors, so it is always the same material as `conductor` — the dashboard shows this
  as a read-only "same as active" line rather than a selectable dropdown, and `computeSizing()`
  ignores `inp.earthConductor`/`earthInsulation`/`earthFlexible` entirely for this family (it sets
  `earthMaterial = inp.conductor`, `earthInsulation = inp.insulation`, `earthFlexible = inp.flexible`
  no matter what was passed in).
- **Single-cores cable** (3x1C+E/4x1C+E/4x1C mains): each conductor, including earth, is its own
  separate cable, so the earth core's insulation, flexibility and conductor material are genuinely
  independent choices — the dashboard shows Earth insulation / Earth flexible / Earth conductor
  controls, and `computeSizing()` uses `inp.earthConductor`/`earthInsulation`/`earthFlexible` as
  supplied.
- **Earth size Auto-vs-manual is unchanged by any of this**: `earthsizeSel === "Auto"` still always
  follows the (possibly auto-selected) active size via the `EARTH_SIZE` pairing table; a manually
  picked earth size is always used exactly as picked. Only the earth core's *material* (which
  resistance table is used for the earth-impedance display box) depends on the above.
- Earth insulation/flexibility currently only affect the displayed labels and, indirectly, which
  resistance temperature column would apply if this were extended — they do not change the earth
  size lookup itself, since there is no per-insulation earth-sizing table digitised.

## Derating factors (`DERATE_*`)

- `DERATE_CIRCUITS` — Table 22, "Bunched on a surface or enclosed" row.
- `DERATE_SOILTEMP` — Table 27(2), keyed by conductor (insulation max) temperature — 75/90/110°C rows.
  Corrected 2026-09-06: previously a single row (the 90°C one) was shared by every insulation family.
- `DERATE_AIRTEMP` — Table 27(1), keyed by conductor temperature — 75/90/110°C rows. Added 2026-09-06;
  previously non-buried/non-underground installations had no ambient-air-temperature derating at all.
- `DERATE_DEPTH` — Table 28(2), Multicore column.
- `DERATE_RESISTIVITY` — Table 29, "Multicore cable in a wiring enclosure" column.

`DERATE_SOILTEMP`/`DERATE_DEPTH`/`DERATE_RESISTIVITY` only apply when the installation method is
Buried direct or one of the two Underground wiring enclosure methods, matching how the reference tool
behaves. `DERATE_AIRTEMP` applies to every OTHER installation method (spaced, touching, exposed to
sun, wiring enclosure in air, thermal-insulation-surrounded) — the two ambient-temperature factors are
mutually exclusive, never both applied to the same calculation. `DERATE_CIRCUITS` applies everywhere
except "Underground wiring enclosure, separate" (each cable already has its own enclosure, so there's
no bunching to derate for).

## Conductor temperature mode (`inp.conductorTempMode`)

Added 2026-09-06, matches jCalc's own "Conductor temperature: Calculate / Maximum" advanced option.
"Calculate" (default) is the Clause 4.4 behaviour already described above (resistance at the ceiling
column above the row's own calculated operating temperature). "Maximum" instead always reads
resistance at the insulation's own max permissible temperature (`resistanceAt(size, maxTemp,
material)`) — the more conservative option, and the behaviour this tool used unconditionally before
the 2026-08-23 Clause 4.4 fix. Only affects the resistance used for voltage drop and the displayed
"Resistance per core" — the Clause 4.4 operating-temperature figure itself is still calculated and
displayed the same way regardless of this option.

## Auto sizing and short-circuit/loop-impedance (added 2026-09-06)

Matches jCalc's own documented Auto criteria (current rating, voltage drop, fault current rating, loop
impedance — jCalc's fifth criterion, protection device thermal trip current, is not implemented; see
"Not modelled at all" below). Previously, enabling "Check short circuit rating" or "Check loop
impedance" only added an informational verdict for whichever size current-rating+voltage-drop alone
had already selected — Auto could land on a size that then failed its own short-circuit or
loop-impedance check, with no automatic correction. Now both checks are computed per candidate size
inside the Auto search itself, and a size that fails an *enabled* check is skipped. Both checks remain
fully opt-in: turning either off, or turning one on without its required inputs (fault current/duration,
or a max permissible Ze), doesn't constrain sizing at all — `computeShortCircuit`/`computeLoopImpedance`
returning `null` (or a `meetsX: null` field) for "not evaluated" is treated as passing, not failing.

## Voltage options (`VOLTAGE_OPTIONS`)

Not from the standard — these mirror the reference tool's own dropdown lists, which differ by Phase
selection: 3-phase/2-phase offer 400/415/380/690/1000 V, 1-phase offers 230/240 V, and DC offers a
completely separate domain (12/24/48/110/220 V — typical battery/solar/control-circuit voltages, not
a relabelling of the AC list). All five lists include "Other", which reveals a "Specify voltage"
field (`#voltage-other` in `cable-size-calculator.html`) used directly in place of the dropdown value.

## Rating units

A/kW/kVA/hp, matching the reference tool's dropdown. kW and hp both ask for Power factor (hp is
converted to kW at 0.746 kW/hp first, then handled identically); kVA does not, since apparent power
already accounts for it; DC ignores power factor entirely regardless of unit.

## Standard (`inp.standard`)

Added 2026-09-06. jCalc's own Cable Size Calculator documents that "2017/2025 Australian conditions"
reference a 40°C air / 25°C soil ambient, while "AS/NZS 3008.1.2:2017 New Zealand conditions"
reference 30°C air / 15°C soil — and that this affects both the ambient constant *and* the
underlying current-rating tables themselves.

`computeSizing()` resolves the selected edition and switches current rating, correction-factor,
resistance/reactance, and short-circuit datasets together. AS/NZS 3008.1.1:2025 Australian mode is
fully routed through the subset described below, including its separate AC/DC cable families.

The New Zealand option remains an ambient-only model over the Australian 2017 tables. It changes the
non-buried reference air ambient from 40°C to 30°C, and the interface suggests the 15°C soil default
used by the reference calculator. AS/NZS 3008.1.2:2017 is a separate document whose current-rating
tables are not present in this workspace, so this option must not be described as a complete New
Zealand dataset.

## AS/NZS 3008.1.1:2025

Added 2026-09-08 (Phase 1: the four 110°C tables), extended over the following two days five more
times (Phase 2 slice 1: the remaining 8 AC tables; Phase 2 slice 2: all six DC tables; Phase 2 slice 3:
the five correction-factor constants; Phase 2 slice 4: `RESISTANCE_2025`/`REACTANCE_2025`; Phase 2
slice 5, 2026-09-09: `SHORT_CIRCUIT_K_2025`/`SHORT_CIRCUIT_FINAL_TEMP_2025`, completing every table
this project's engine needs from Sections 3-5). `data.js`'s `CURRENT_RATING_2025` object now holds all
12 of Section 3's AC current-carrying-capacity tables plus all six DC current-carrying-capacity
tables, five `DERATE_*_2025` correction-factor constants sit alongside it, `RESISTANCE_2025`/
`REACTANCE_2025` cover Section 4's resistance and reactance data, and `SHORT_CIRCUIT_K_2025`/
`SHORT_CIRCUIT_FINAL_TEMP_2025` cover Section 5 — **none of this is wired into `computeSizing()`,
`voltagerise.js`, or the Standard selector yet**, kept as clearly separate, clearly cited blocks rather
than silently blended into the 2017 tables above. Selecting "2017 Australian conditions" or
"New Zealand conditions" is unaffected by any of this and still only ever reads the 2017 data.

**Why the 110°C tables first (Phase 1)**: it's the highest-value, most-referenced gap in this
project's history. `CURRENT_RATING["MultiCore|110C"]`/`["SingleCore|110C"]`/`["MultiCore2C|110C"]`
above are Copper only — confirmed against the real AS/NZS 3008.1.1:2017 PDF (Table 13/Flexible column
and Table 15 column headers read "Cu" only), not a digitisation gap. AS/NZS 3008.1.1:2025 Preface
item (c) states: "Addition of current carrying capacities for 110 °C aluminium conductor cables,
other than aerial cables and any other applications where tension is applied to the aluminium
conductors in their normal service." The remaining 8 tables (Phase 2 slice 1) complete Section 3's
Thermoplastic (75°C) and Cross-linked (90°C) coverage for all four cable configurations, matching the
column structure already confirmed by the 110°C tables. All 12 are now digitised:

| `CURRENT_RATING_2025` key | 2025 table | Cable configuration | Insulation class | 2017 equivalent |
|---|---|---|---|---|
| `SingleCore2W\|Thermoplastic` | Table 3.9 | **Two** single-core cables | Thermoplastic (75°C) | *(none)* |
| `SingleCore2W\|X90` | Table 3.10 | **Two** single-core cables | Cross-linked (90°C) | *(none)* |
| `SingleCore2W\|110C` | Table 3.11 | **Two** single-core cables | Cross-linked (110°C) | *(none)* |
| `SingleCore3W\|Thermoplastic` | Table 3.12 | **Three** single-core cables | Thermoplastic (75°C) | Table 7 |
| `SingleCore3W\|X90` | Table 3.13 | **Three** single-core cables | Cross-linked (90°C) | Table 8 |
| `SingleCore3W\|110C` | Table 3.14 | **Three** single-core cables | Cross-linked (110°C) | Table 9 |
| `MultiCore2C\|Thermoplastic` | Table 3.15 | 2-core sheathed multicore | Thermoplastic (75°C) | Table 10 |
| `MultiCore2C\|X90` | Table 3.16 | 2-core sheathed multicore | Cross-linked (90°C) | Table 11 |
| `MultiCore2C\|110C` | Table 3.17 | 2-core sheathed multicore | Cross-linked (110°C) | Table 12 |
| `MultiCore\|Thermoplastic` | Table 3.18 | 3-core/4-core sheathed multicore | Thermoplastic (75°C) | Table 13 |
| `MultiCore\|X90` | Table 3.19 | 3-core/4-core sheathed multicore | Cross-linked (90°C) | Table 14 |
| `MultiCore\|110C` | Table 3.20 | 3-core/4-core sheathed multicore | Cross-linked (110°C) | Table 15 |

(`Single-cores 2x1C+E` maps to the `SingleCore2W` keys; `Single-cores 3x1C+E`/`4x1C+E` map to
`SingleCore3W`; `Multi-core 2C+E` maps to `MultiCore2C`; `Multi-core 3C+E`/`4C+E` map to `MultiCore`.)

**DC current-carrying capacity is new in 2025 — 2017 has no DC current-rating tables at all.** Per
the Preface, DC coverage is scoped to "two single-core cables and all 2-core cables" only — no DC
equivalent of three-single-core or 3/4-core sheathed multicore exists in the standard. All six DC
tables are now digitised, keyed with a `-DC` suffix appended to the insulation family so an AC and a
DC lookup for the same cable/insulation combination never collide:

| `CURRENT_RATING_2025` key | 2025 table | Cable configuration | Insulation class |
|---|---|---|---|
| `SingleCore2W\|Thermoplastic-DC` | Table 3.21 | **Two** single-core cables | Thermoplastic (75°C) |
| `SingleCore2W\|X90-DC` | Table 3.22 | **Two** single-core cables | Cross-linked (90°C) |
| `SingleCore2W\|110C-DC` | Table 3.23 | **Two** single-core cables | Cross-linked (110°C) |
| `MultiCore2C\|Thermoplastic-DC` | Table 3.24 | 2-core sheathed multicore | Thermoplastic (75°C) |
| `MultiCore2C\|X90-DC` | Table 3.25 | 2-core sheathed multicore | Cross-linked (90°C) |
| `MultiCore2C\|110C-DC` | Table 3.26 | 2-core sheathed multicore | Cross-linked (110°C) |

**DC values are close to, but genuinely not identical to, the equivalent AC table** — at small sizes
(≤35mm² in every table checked) DC and AC figures print identically, but they diverge at larger sizes
(e.g. Table 3.21 vs Table 3.9, both Thermoplastic two-single-core: identical through 35mm², but
630mm² Touching Cu is 835A DC vs 770A AC). Column structure, captioning convention (PVC vs Metallic
conduit in air by insulation class, same rule as the AC tables), and the Aluminium-starts-at-16mm²
floor are all identical to the equivalent AC table's own convention.

**A genuine, independently-confirmed quirk in the standard's own tables**: Table 3.24 (Thermoplastic,
75°C) and Table 3.25 (Cross-linked, 90°C) print byte-for-byte identical `buried` and `undBunched`
(buried-in-PVC-conduit) columns, at every size, despite every other column genuinely differing between
the two insulation classes. Re-read independently from two separate table-page images and confirmed
identical both times before being treated as correct rather than as a suspected transcription error —
pinned explicitly in `tests/current-rating-2025-tests.js`. Table 3.26 (110°C) does *not* share this
pattern — its buried figures are genuinely its own. Separately, Table 3.26's own `spaced` and `buried`
columns happen to print the exact same Cu/Al pair (457/354) at 120mm² specifically, nowhere else in
the table — confirmed via a dedicated zoomed re-crop when the first read looked suspicious, and
pinned as a one-row coincidence, not a copy-paste artefact.

**A genuinely new distinction, not just renumbering**: 2025 is the first edition to tabulate "two
single-core cables" (a 2-wire circuit, e.g. a single-phase active+neutral run as two separate
cables) as its own table family, distinct from "three single-core cables". 2017 has no equivalent —
`engine.js`'s `SingleCore` family currently reuses Table 7/8/9 (the three-single-core figures) for
2x1C configurations too, since that was the only single-core data 2017 provides. This is flagged as
an open question for the remaining integration work, not resolved here.

**Column structure**: confirmed directly from each table's own header row (not assumed from 2017's
layout) via cropped, 300dpi re-reads. All single-core tables (3.9-3.14) use the same 10-method
column set as 2017's own single-core tables — including the single (not unenclosed/enclosed-split)
"Partially"/"Completely surrounded by thermal insulation" columns, which is why `partUnencl`/
`partEncl` (and `compUnencl`/`compEncl`) hold identical duplicated arrays here, exactly matching the
convention already established for `CURRENT_RATING["SingleCore|Thermoplastic"]` above. All multicore
tables (3.15-3.20) split thermal insulation into all four unenclosed/enclosed combinations, matching
2017's multicore convention. One real difference from 2017, **110°C-class only**: the "Enclosed"
install method is captioned **"Metallic conduit in air"**, not PVC conduit, for Tables 3.11/3.14/
3.17/3.20 — 110°C-class cable physically requires metallic conduit when enclosed, a constraint 2017's
column caption didn't state explicitly. The Thermoplastic/X-90 tables (3.9/3.10/3.12/3.13/3.15/3.16/
3.18/3.19) caption this column **"PVC conduit in air"**, same as 2017 — the `wiringAir` key name is
shared across both captions since `engine.js` only needs the install-method key, not the caption text.

**A source-PDF formatting quirk, not a data gap**: in Table 3.19 specifically, the "Partially
Enclosed" Aluminium column is printed genuinely blank (no dash) for every row below 16mm², unlike
every other below-the-floor null cell in every other table (which prints a dash). Treated identically
to every other null — Aluminium still starts at 16mm² in every table, this is just an inconsistency
in how the standard's own typesetting rendered that one column.

**Size range genuinely differs from this project's own `SIZES` constant**: 2025 tabulates down to
0.5mm² (2017/this project's `SIZES` starts at 1mm²) and, for single-core cable, up to 630mm² (2017/
this project's `SIZES` tops out at 500mm²). Rather than force these into the shared `SIZES` array —
which every 2017 table and every existing test depends on — each `CURRENT_RATING_2025` block carries
its own `sizes` array. The remaining integration work needs its own decision about whether/how to
reconcile the two ranges (most likely: `SIZES` grows to match 2025 once 2025 goes live, since the
smaller/larger sizes are real, useful data, not something to leave stranded).

**Verification**: every digitised value was independently cross-checked by an automated script
comparing `data.js` against a separately-transcribed ground-truth file (built from the same table
reads, kept in a different format so a transcription slip in one wouldn't silently match a slip in
the other) — Phase 1's four tables: 1,896 values, 0 mismatches on the final pass (an earlier pass
caught a real 4-value transcription error and a fully-missing `al` sub-block in `MultiCore|110C`).
The 8-table AC addition: 3,792 values, 0 mismatches — a second hand-verification pass (independently
re-reading a magnified crop of each table's lower rows and comparing against the first transcription)
caught and fixed a real row-shift transcription error in `MultiCore2C|X90`'s (Table 3.16) buried-in-
conduit columns before it ever reached `data.js` or the cross-check script, the same class of error
Phase 1 found. The 6-table DC addition: 6,636 values checked in total across all 18 blocks (the DC
tables' own share: 2,948), 0 mismatches — the same second-pass discipline caught an initially
misread row in Table 3.26 (see the coincidence note above), resolved with a dedicated zoomed re-crop
rather than trusting a second freehand read. This project has no text layer to parse for 2025 (unlike
2017's PDF, this one is flattened/secured — confirmed via `pymupdf`, `doc[0].get_text()` returns
`""`), so this double-transcription cross-check stands in for the Python-parser verification 2017's
own Aluminium/110°C digitisation used.

### Correction factors (Section 3)

Added 2026-09-08 (same day as the DC tables). Five new top-level constants — `DERATE_CIRCUITS_2025`,
`DERATE_SOILTEMP_2025`, `DERATE_AIRTEMP_2025`, `DERATE_DEPTH_2025`, `DERATE_RESISTIVITY_2025` — the
2025 equivalents of the 2017 `DERATE_*` constants documented earlier in this file, routed by the
selected standard in `computeSizing()`/`computeCableElectricals()`. Each picks the same representative
row/column its 2017 counterpart already uses (2017 itself only ever models one arrangement per
correction factor, not every row the standard tabulates):

| Constant | 2025 table | Row/column picked (matches the 2017 constant's own choice) | vs. 2017 |
|---|---|---|---|
| `DERATE_CIRCUITS_2025` | Table 3.33 (printed page 73) | Item 2, "Bunched on a surface or enclosed" | **identical** |
| `DERATE_SOILTEMP_2025` | Table 3.45 (printed page 85) | all three conductor-temperature rows (75/90/110°C) | 110°C row identical; 75°C/90°C rows genuinely differ |
| `DERATE_AIRTEMP_2025` | Table 3.44 (printed page 84) | all three conductor-temperature rows (75/90/110°C) | 110°C row identical; 75°C/90°C rows genuinely differ |
| `DERATE_DEPTH_2025` | Table 3.47 (printed page 86) | "Multicore" column, underground wiring enclosures | genuinely differs at several depths |
| `DERATE_RESISTIVITY_2025` | Table 3.48 (printed page 86) | "Cable in underground wiring enclosure — Multicore" column | **identical** |

**A real, confirmed pattern, not noise**: every 110°C row/value checked is byte-identical to its 2017
counterpart, while every 75°C/90°C row genuinely differs by a few hundredths at multiple points (e.g.
`DERATE_SOILTEMP_2025[75]` at 40°C soil is 0.84, vs. 2017's 0.83 at the same point). This is consistent
with the Preface's own note that 2025 changed some correction-factor calculation bases — plausibly
tied to the same "110°C-class calculations now align with X-HF-110 dimensions (2017 used R-HF-110)"
item that leaves 110°C alone while changing 75°C/90°C. Not independently confirmed against the
Preface's own wording for these specific tables — flagged as an observation, not a proven causal link.

**Table 3.33 itself tabulates six arrangements** (bunched in air; bunched on a surface/enclosed;
single-layer-on-wall-or-floor touching/spaced; single-layer-under-ceiling touching/spaced) — only the
one row 2017's own `DERATE_CIRCUITS` already uses is digitised here, matching the existing
simplification rather than expanding it. The other five rows, and the much more granular per-install-
method grouping tables (3.34-3.43 — single-core vs multicore, buried-direct vs underground-enclosure,
row-formation variants) are **not digitised** and not currently modelled by this project's `numParallel`
handling at all, 2017 or 2025.

**Verification**: read directly off 300dpi rendered page images (these tables are small — 5-21 columns,
4-6 rows each — well within confident single-pass legibility, unlike the CCC tables' dense 20-column
layout), then cross-checked against the already-tested 2017 `DERATE_*` arrays as an independent sanity
check (an unexpected match or mismatch on a value that should logically differ/agree would flag a
misread) rather than a from-scratch double-transcription pass. All five constants are pinned in
`tests/correction-factors-2025-tests.js`, including explicit pins for values that turned out identical
to 2017 and values that turned out different, so an accidental edit toward "matching 2017" gets caught.

### Section 4 (resistance and reactance)

Added 2026-09-09. Two new top-level constants — `RESISTANCE_2025` and `REACTANCE_2025` — the 2025
equivalents of `RESISTANCE`/`REACTANCE` above. They are routed through cable sizing, voltage drop and
voltage rise by the selected standard. Before transcribing, Section 4's actual table inventory was
surveyed (31 table families, 4.1-4.31, most split into (A) Copper/(B) Aluminium sub-tables covering
resistance, reactance, *and* precomputed mV/A.m voltage-drop values per cable configuration) —
consistent with every prior phase of this work, the true scope ("~53 pages") was far larger than
what this project's engine actually needs:

- **The ~50 mV/A.m voltage-drop tables (2025 Tables 4.14-4.31) are deliberately NOT digitised.** This
  engine has never used the standard's precomputed mV/A.m method (Clause 4.2) — `voltagedrop.js` and
  `voltagerise.js` both compute voltage drop/rise directly from `R`/`Xc` impedance (Clause 4.3's own
  method), the same way `computeSizing()` always has. These tables have no consumer in this codebase
  at all, 2017 or 2025.
- **Resistance is configuration-independent, confirmed rather than assumed.** 2025 tabulates
  resistance separately per cable configuration (Table 4.5 single-core, 4.7 multicore, 4.9 shaped,
  etc.) — but every value checked between Table 4.5 (single-core) and Table 4.7 (multicore) is
  identical at matching size and temperature. This matches 2017's own `RESISTANCE` object, which has
  never modelled cable configuration at all (resistance is a conductor-material property, physically
  independent of how the conductor is arranged). Only Table 4.5(A)/(B) was digitised as a result —
  transcribing 4.7, 4.9, etc. as well would just duplicate the same numbers.
- **Reactance still needs the multicore/single-core split** (it genuinely depends on conductor
  geometry, unlike resistance) — Table 4.1(A) (single-core, Trefoil/Flat touching) and Table 4.1(B)
  (multicore, Circular/Shaped conductors) together are the direct 2025 equivalent of 2017's Table 30,
  matching `REACTANCE`'s existing `multicore`/`singlecoreTrefoil`/`singlecoreFlat` shape exactly.
  "Shaped conductors" columns exist in Table 4.1(B) but aren't digitised, matching `engine.js`'s own
  documented decision that "shaped conductors aren't modelled" for 2017 either.

**A real, consistent pattern found in both reactance tables**: the PVC and XLPE columns are
byte-identical to 2017's Table 30 in *both* Table 4.1(A) and Table 4.1(B), while the **Elastomer**
column genuinely differs from 2017 in both tables (e.g. multicore Elastomer at 1mm²: 0.128 in 2025 vs
0.139 in 2017). The same divergence appearing independently in two separate tables (single-core and
multicore) rules out a one-off transcription slip — this is a real, isolated methodology change
specific to Elastomer-insulated cable reactance.

**Resistance also genuinely differs from 2017, but by *size* rather than by insulation/chemistry**:
small-to-medium sizes (≤70mm² checked) are identical to 2017's Table 34/35 at every temperature, while
larger sizes (≥95mm²) diverge by up to a few percent — e.g. 500mm² Copper at 90°C is 0.0525 Ω/km in
2025 vs 0.0544 Ω/km in 2017. 2025 also tabulates **Aluminium resistance at 110°C**, which 2017 never
had at all — consistent with the broader "2025 adds 110°C Aluminium data" theme already established in
`CURRENT_RATING_2025`'s Phase 1 work.

**Verification**: read directly off 300dpi rendered page images (large but very legible tables — 8-11
well-spaced columns, unlike the CCC tables' cramped 20-column layout), with a targeted re-crop of
Table 4.5(A)'s lower rows as a spot-check. Cross-checked against the already-tested 2017 `RESISTANCE`/
`REACTANCE` arrays, plus an inline cross-check between Table 4.5(A) and Table 4.7(A)'s own printed
values to confirm the configuration-independence claim above. Pinned in
`tests/resistance-reactance-2025-tests.js`.

**AS/NZS 3008.1.1:2025's Section 4 also introduces DC voltage-drop tables** (4.16, 4.18, 4.21, 4.23,
4.26, 4.28 — one per cable configuration/conductor material) that 2017 has no equivalent of, mirroring
the new DC current-rating tables (3.21-3.26) already digitised. Not needed here since DC voltage drop
already works via the same `R`/`Xc` impedance method (`Xc=0` for DC) once `RESISTANCE_2025` covers the
relevant conductor/temperature — not digitised separately, and not expected to ever need separate
digitisation for that reason.

**Section 4's "voltage rise" content, checked against this project's own Voltage Rise Calculator**:
see the "Checked against AS/NZS 3008.1.1:2025's Section 4" note in the Voltage Rise Calculator section
below. The calculator now records whether suitable high-export-voltage prevention is present and can
exclude exactly one user-identified consumer-mains segment from the design-limit assessment while
still reporting the complete physical voltage rise.

### Section 5 (short-circuit performance)

Added 2026-09-09. Two new top-level constants — `SHORT_CIRCUIT_K_2025` and
`SHORT_CIRCUIT_FINAL_TEMP_2025` — the 2025 equivalents of `SHORT_CIRCUIT_K`/`SHORT_CIRCUIT_FINAL_TEMP`
above, routed into `computeShortCircuit()` by the selected standard. This is the smallest of Section 3/4/5,
confirmed by survey before transcribing: Section 5 has exactly five tables total (5.1-5.5), and only
two are needed — `computeShortCircuit()` only ever reads `SHORT_CIRCUIT_K`/`SHORT_CIRCUIT_FINAL_TEMP`,
matching 2017's own scope exactly:

- **Table 5.1** (constant K for the short-circuit withstand formula `S = I√t/K`) → `SHORT_CIRCUIT_K_2025`.
  Lead/Steel columns exist in the source table but aren't digitised, matching `SHORT_CIRCUIT_K`'s own
  scope (not needed for any conductor material this calculator offers).
- **Table 5.2** (temperature limits for insulating materials in contact with conductors) →
  `SHORT_CIRCUIT_FINAL_TEMP_2025`.
- **Table 5.3** (outer sheath/bedding materials) and **Table 5.4** (conductor/metal sheath joint
  materials) are **not digitised** — they cover components this calculator's short-circuit check has
  never modelled, 2017 or 2025.
- **Table 5.5** ("Calculated short-circuit current limit") is a genuinely new, 2025-only precomputed
  reference table (size/K/duration → current limit — the short-circuit equivalent of Section 4's
  mV/A.m tables) — **not digitised** for the same reason those weren't: this engine computes
  `S = I√t/K` from first principles and has no consumer for a precomputed lookup table.

**A different kind of difference from 2017 than Section 3/4 showed**: Table 5.1's K-values are close
to but genuinely differ from 2017's Table 52 by a few tenths at *every* temperature pair checked (e.g.
Copper, 140°C final/130°C initial: 37.1 in 2025 vs 37.2 in 2017) — small, uniform differences
throughout, rather than the size-dependent (resistance) or insulation-dependent (reactance,
correction factors) patterns found elsewhere. Table 5.2, by contrast, is **byte-identical** to 2017's
Table 53 for every value checked — the only table across Sections 3-5 found so far with zero
differences anywhere, consistent with these being fixed physical material limits rather than a
calculated/rounded value.

**Verification**: read directly off a 300dpi rendered page image, then **fully re-verified** (not
just spot-checked) via two zoomed crops covering every row of both the Copper and Aluminium columns —
a higher bar than most other 2025 additions, since this data feeds a safety-relevant calculation even
though it isn't wired in yet. Pinned in `tests/short-circuit-2025-tests.js`.

**This completes the current-rating/correction-factor/resistance-reactance/short-circuit
digitisation** — every table this project's engine actually needs from Sections 3-5 is now in
`data.js`. The only remaining Phase 2 item is wiring it all together (see below).

**What's still missing** — one item now, the wiring itself, plus some open design questions that
surfaced along the way:
- Real methodology changes flagged in the 2025 Preface that could shift *existing* Copper values,
  not just add new ones: 110°C-class calculations now align with X-HF-110 dimensions (2017 used
  R-HF-110); flexible-cable dimensions now use a different standardised method; ≤10mm² direct-buried
  ratings are now calculated via IEC 60287 instead of reusing underground-enclosure figures. None of
  these are assumed to leave the digitised-so-far values unaffected — they were transcribed directly
  from the 2025 tables' own printed numbers, which already reflect whatever methodology 2025 actually
  used.
- New row-formation correction factors and expanded parallel-cable guidance (2025's informative
  Appendix C) — not modelled by this project's existing `numParallel` handling.
- Whether/how `SIZES` reconciles with 2025's wider 0.5-630mm² range (see above).
- Whether "two single-core" deserves its own `cabletype` distinct from the existing "three
  single-core" options, now that the standard itself distinguishes them.
- Wiring all of the above into `engine.js`'s Standard branching, the dropdown label, and tests, once
  everything above lands.

## Not modelled at all

- Voltage drop at non-unity power factor is only folded in for kW/hp ratings (the only units that
  ask for a power factor) — the specified cosφ/sinφ is used directly there. A/kVA/DC ratings don't
  ask for a power factor, so — corrected 2026-09-06 to match jCalc's own documented default ("Load
  power factor: Worst-case or Specified", worst-case being the default) — they use the worst-case
  value instead of assuming unity: since Rc·cosφ+Xc·sinφ is maximised at cosφ=Rc/Zc, sinφ=Xc/Zc, this
  reduces to `Vd = k×I×L×Zc/1000` (Zc=√(Rc²+Xc²)), not the old resistance-only `Vd = k×I×L×Rc/1000`.
  This was likely the single largest contributor to the systematic voltage-drop gap found in the
  576-scenario jCalc.net cross-check (see "Verification status" below).
- jCalc also exposes "Load power factor" as a user-facing toggle (Worst-case/Specified) — this tool
  hard-codes the (matching) worst-case default rather than exposing it as a selectable option.
  "Conductor temperature" (Calculate/Maximum) IS exposed, added 2026-09-06 — see above.
- Auto sizing doesn't consider a protective device's own thermal trip current (jCalc's fifth Auto
  criterion, alongside current rating/voltage drop/fault rating/loop impedance) — this tool has no
  concept of a protective device (MCB/MCCB/generic) at all, only the raw fault-current+duration inputs
  `computeShortCircuit()` already takes. **Genuinely blocked on missing source data**, checked
  2026-09-06: an MCB/MCCB's trip-time-vs-current curve (needed to know the disconnection time `t` for
  a given fault current, which is what actually drives the required earth/cable size per Clause 5.3
  of AS/NZS 3000) comes from AS/NZS 60898 (MCBs) or individual manufacturer datasheets, not from
  either AS/NZS 3008 or AS/NZS 3000 — neither is in this project's source PDFs. Adding this would mean
  either digitising a specific device family's published curve (narrow, and only correct for that
  family) or fabricating a generic one (which this project's whole approach — cite the real table, or
  say "no data" — argues against). Left undone rather than guessed at.
- Similarly, jCalc's more advanced parallel-earth-cable rules for Single-cores (combined fault-rating
  split across multiple parallel earth cables, an "ignore Table 5.1 above 120/240mm²" option, per-group
  vs per-cable earth counting) aren't implemented — this tool's `numParallel`/earth-sizing model doesn't
  yet distinguish "one earth cable per parallel group" from "N earth cables split across N groups".
  Not a missing-data problem like the MCB curves above, just a genuinely bigger feature that needs its
  own design pass before implementation.

Conduit sizing (AS/NZS 3000 Tables C10/C11/C12), short-circuit rating (Table 52/53) and loop
impedance/EFLI checks are implemented — see `computeConduitCapacity`/`computeShortCircuit`/
`computeLoopImpedance` in `engine.js`.

## Exporting results

A "Download results (CSV)" button (`downloadResultsCsv()` in `ui.js`, added 2026-09-06) exports the
last successful calculation — every input plus every result field, including short-circuit/loop-
impedance figures when those checks are enabled — as a two-column `Field,Value` CSV, using only
browser-native APIs (`Blob`/`URL.createObjectURL`/a temporary `<a download>` link). Deliberately CSV,
not a PDF or Excel report matching jCalc's own "Generate PDF Report": this project has no npm
dependencies and no build step (see README.md), and a PDF/Excel library needs either a CDN `<script>`
tag (an internet dependency this offline-capable tool doesn't otherwise have) or a vendored copy
checked into the repo — a real decision either way, made here in favour of not making it unilaterally.
If a polished report is wanted later, that decision belongs to whoever's maintaining this project.

## Verification status

**Updated 2026-08-23.** Four full reference scenarios — real jCalc.net (jcalc.net) printouts saved by
the user in `Cable Sizing/Sample results/` ("63A 240V.pdf", "63A 415V.pdf", "150A 415V.pdf",
"200A 415V.pdf"), each citing exact AS/NZS 3008 table/column numbers for every value shown — were
cross-checked end-to-end against this calculator's output and are now pinned as permanent regression
tests in `tests/tests.js` ("Scenario: 4 jCalc.net reference PDFs..."). This pass found and fixed 4 real
bugs, all now corrected in `data.js`/`engine.js` and documented in the relevant sections above:

1. Voltage drop (and the displayed "Resistance per core") used a fixed 90°C resistance instead of the
   cable's actual operating-temperature ceiling column (Clause 4.4).
2. Reactance (`REACTANCE`) only had the PVC column and ignored insulation chemistry and Formation —
   now the full Table 30 is digitised (PVC/XLPE/Elastomer × Trefoil/Flat-touching/Multicore).
3. The earth-size lookup didn't adjust for an Aluminium active conductor's lower conductance.
4. "Multi-core 2C+E"/"Multi-core 2C (mains)" cabletypes incorrectly reused the 3/4-core current-rating
   table (Table 13/14/15) instead of the two-core table (Table 10/11/12).

Two older scenarios (63A/415V default, and 320A/415V) remain pinned separately near the top of
`tests/tests.js` as hand-calculated/screenshot-derived sanity checks.

The Aluminium and 110°C additions were cross-verified two ways during digitisation: (1) a Python
parser was written against the extracted PDF text and used to re-derive every Copper array already
shipped — every value matched the previously-verified data exactly, confirming the parser's column
alignment was correct before trusting it for the new Aluminium/110°C columns; (2) `tests/tests.js`
now asserts that Aluminium requires the same size or larger than Copper for an identical load (basic
physical sanity — Aluminium has higher resistivity), and that an Aluminium earth core has higher
resistance than a Copper one at the same size.

Everything else in the data tables was transcribed carefully from the PDF but has **not** been
independently re-checked cell-by-cell against the standard. Before this tool is relied on for a
real installation, get a qualified electrical engineer to spot-check the specific combination
you're using — see the disclaimer in `src/cable-size-calculator.html`.

**Added 2026-09-06: 576-scenario jCalc.net cross-check.** The user supplied
`AS3008_Cable_Sizing_576_Scenarios.xlsx` (`Cable Sizing/Sample results/`) — every combination of
Phase/Voltage (3-phase 415V, 1-phase 230V), load current (63/100/160/300A), required voltage drop
(3/5/7%), distance (50/100/150m), cable configuration (Multi-core, Normal/Flexible), conductor
(Copper/Aluminium) and installation method (Underground wiring enclosure, Touching surface),
submitted directly to jCalc.net's own calculator. Findings:

- **Fixed**, see "Earth core sizing" above: the `EARTH_SIZE.MultiCore` (Copper) off-by-one from
  35mm² up, and the missing Aluminium Multi-core earth=active-size rule. This eliminated ~210 of the
  241 earth-size mismatches the cross-check surfaced; the remaining ~31 are downstream of the
  active-size discrepancy below, not a separate earth-sizing issue.
- **Investigated and confirmed NOT a bug**: 212 of 576 scenarios used Aluminium with either the
  110°C insulation family or a Flexible cable type. This calculator returns an explicit error for
  both (`computeSizing()` in `engine.js`), while jCalc returns a numeric result. Checked directly
  against the user's own AS/NZS 3008.1.1:2017 PDF (Table 15 for 110°C, Table 13 for Flexible): **the
  standard genuinely has no Aluminium column for either combination** — every relevant column header
  reads "Cu" only. jCalc's numbers for these combinations therefore extrapolate beyond the published
  standard; this tool's refusal is the more standards-faithful behaviour and was deliberately not
  changed to match.
- **Voltage-drop portion resolved 2026-09-06**: the "worst case" default fix above (jCalc defaults
  A/kVA/DC voltage drop to `Zc=√(Rc²+Xc²)`, not resistance-only) is almost certainly what the earlier
  investigation here was looking for and didn't find — at the time, only a *fixed power-factor value*
  (0.86, applied as `Rc·cosφ+Xc·sinφ`) had been tested and correctly ruled out, since that produces a
  *smaller* voltage drop than resistance-only, the wrong direction to explain jCalc's higher numbers.
  The worst-case-Zc default (found afterward, directly in jCalc's own Cable Size Calculator
  documentation rather than guessed at) produces a *larger* value, the right direction, and likely
  also explains some of the borderline active-size selections below (a higher computed vd% pushes
  more scenarios past their voltage-drop limit at the previously-selected size).
- **Rated-current portion, still not resolved**: re-running the comparison after the voltage-drop fix
  moved agreement (excluding the confirmed Aluminium scope gaps above) from 157/360 to 183/360 rows —
  a real improvement, confirming part of the borderline active-size selections were indeed downstream
  of the voltage-drop formula, but most of the remaining gap is a genuinely separate rated-current
  discrepancy. ~120-150 of the 576 scenarios show small (typically <10%) discrepancies in rated
  current specifically. The underlying `CURRENT_RATING` table
  values used for these rows were spot-checked cell-by-cell against the standard PDF (Tables 13/14/15)
  and matched exactly, so this isn't a transcription error in this tool's data. Most likely cause:
  jCalc's own default site conditions (soil temperature/depth/resistivity) for this scenario batch —
  noted in the workbook's own Read Me as "standard default site conditions... not part of the
  requested scope" — don't necessarily match this tool's defaults (25°C soil, 0.5m depth, 1.2
  resistivity), and a few individual jCalc cells (e.g. Table 15's 50mm² and 95mm² Underground-enclosure
  ratings) don't match
  even where every other size in the same column does. Not chased further; revisit if a
  reference scenario with jCalc's exact site-condition inputs becomes available.

## Voltage Drop Calculator (`voltage-drop.html` / `voltagedrop.js`)

Added 2026-09-06, modelled on jCalc.net's own standalone "AC and DC Voltage Drop Calculator"
(deliberately simpler than the Cable Size Calculator above, not a duplicate of it — jCalc hosts
both as separate tools, and this project now mirrors that).

**Formula**: `ΔV = k × I × L × Zc / 1000`, `Zc = √(Rc² + Xc²)`, `k = √3` for 3-phase, `2` for
1-phase AC or DC. Always worst-case power factor (Zc, not `Rc·cosφ + Xc·sinφ`) — this tool has no
"specified power factor" option at all, unlike the Cable Size Calculator's advanced toggle. Rating
unit conversion (A/kW/kVA/hp → amps) reuses `ratingToAmps()` from `engine.js` directly rather than
reimplementing it.

**Resistance (`Rc`)**: `resistanceAt(size, 75, "Copper")` from `engine.js` — a **fixed** 75°C
column, reusing `RESISTANCE.Copper` from `data.js`. Deliberately not the Cable Size Calculator's
Clause 4.4 operating-temperature calculation (`resistanceAtCeiling`) — jCalc's own citation for
this specific tool is "Table 35 -Multi-core, circular at 75°C" regardless of the actual load, and
this tool follows that. Cross-checked directly against jCalc's own worked example ("Example 2":
230VAC, 10A, 2.5mm² → `Rc = 9.01 Ω/km`) — `resistanceAt(2.5, 75, "Copper")` returns exactly `9.01`.

**Reactance (`Xc`)**: `REACTANCE.multicore.PVC` from `data.js` — the PVC/multicore column
unconditionally. This tool doesn't ask for an insulation type at all (matching jCalc's own input
set), so there's no chemistry selection like the Cable Size Calculator has — PVC matches the fixed
75°C/Table 35 assumption above (V-90's own chemistry).

**Scope, fixed and not user-selectable**: Copper only, Multi-core only, PVC/V-90 only. No
Aluminium, Single-cores, other insulation families, installation methods, or derating factors —
all genuinely out of scope for this tool (jCalc's own version doesn't expose them either), not
approximated or missing data.

**Reference rated current** (shown for information only, not used by any calculation): Table 13
(`CURRENT_RATING["MultiCore|Thermoplastic"]`), "spaced from surface" column — matches jCalc's own
citation ("Table 13... unenclosed and spaced from a surface"). Multi-core has no separately
tabulated "spaced from surface" figures (see `resolveRatingArray()` in `engine.js`), so this
resolves to the same values as the plain "Spaced" column — a pre-existing, documented
approximation inherited from the Cable Size Calculator's own data, not new to this tool.

**Not verified beyond the one worked example above** — `Rc` matches jCalc exactly, but the three
modes' end-to-end output (voltage drop % / minimum size / maximum distance) hasn't been
cross-checked against a full jCalc.net printout the way the Cable Size Calculator was (the
576-scenario cross-check). Worth doing if a reference scenario becomes available.

## Voltage Rise Calculator (`voltage-rise.html` / `voltagerise.js`)

Added 2026-09-07, modelled on jCalc.net's own standalone Voltage Rise tool for solar/inverter
installs — checks the voltage rise a reverse-flowing inverter export current causes across a cable
cascade against AS/NZS 4777.1-2024's default 2% limit (user-editable).

**Cascade model**: 2-5 generic labelled segments (not fixed named stages — real installs vary,
e.g. some have no separate distribution board) carrying one shared current throughout (a single
inverter/combined output current — no per-segment currents, no multi-inverter merging topology
modelled). Segment rises add in series: `totalRiseV = Σ segmentRiseV`.

**Per-segment configuration**: full Cable-Size-Calculator depth — cable type, conductor
(Copper/Aluminium), insulation family, formation, installation method, and the matching
ambient/derating fields (soil temperature/depth/resistivity when buried, air temperature
otherwise) — reusing exactly the same option sets and validation
(`engine.js::validateCableCombo()`) as `cable-size-calculator.html`. Unlike that tool, cable size is
**always manual** per segment — this calculator checks voltage rise for a cascade the user already
knows or is evaluating, it doesn't solve for cable size.

**Resistance**: full Clause 4.4 operating-temperature calculation per segment (not the Voltage Drop
Calculator's fixed 75°C simplification), via `engine.js::computeCableElectricals()` — the same
per-size current-rating/derating/resistance/reactance calculation `computeSizing()` uses internally,
extracted into a shared function specifically so this tool doesn't duplicate that logic (see the
"Standard" section above for what the ambient switch does and doesn't cover — it applies here
identically).

**Formula**: `ΔV = k × I × L × (Rc·cosφ + Xc·sinφ) / 1000` per segment, `k = √3` for 3-phase AC, `2`
for 1-phase AC (no DC, no 2-phase — inverters are AC output only). kW ratings ask for a power
factor and use it directly; A/kVA ratings use the worst-case `Zc = √(Rc²+Xc²)` value instead, the
same `hasSpecifiedPf` logic `engine.js` already uses for voltage drop.

**Undersized-segment handling**: if a segment's manually-chosen size can't carry the load current at
its own derating (`meetsRating: false`), this is a **warning, not a blocking error** — the
calculation still runs and reports the voltage rise. This tool checks voltage rise, not
current-carrying adequacy; the user may already know a segment is derated for other reasons.

**Not modelled**: Auto-sizing per segment; per-segment/multi-inverter current inputs; a results
export (CSV/PDF — may be added later following the Cable Size Calculator's `downloadResultsCsv()`
pattern); DC or 2-phase (120°/180°) phase options. Whether AS/NZS 4777.1-2024's 2% default should
ever change by jurisdiction (NZ vs AU) wasn't confirmed during this feature's design — it defaults
to 2% for both until/unless a source says otherwise. A segment's Cable type dropdown options are
resolved once when that segment card is created (based on the global Phase at that moment) and don't
refresh if Phase is changed afterward — unlike the Cable Size Calculator, which keeps Cable type
synced to Phase live. Not a computation bug (voltage rise doesn't depend on cabletype/Phase
compatibility, only on Phase's own k-factor), just a missing realism guard against picking a 2-core
cable type under a 3-phase Phase selection.

**Not independently cross-checked** against a jCalc.net or other reference tool's own Voltage Rise
output yet (unlike the Cable Size Calculator's 576-scenario cross-check) — the per-segment formula
and resistance/reactance lookups are the same, already-verified ones the other two calculators use,
but the full cascade-aggregation behavior itself has only been verified by hand-calculation (see
`tests/voltagerise-tests.js`). Worth a fuller cross-check if a reference scenario turns up.

**Checked against AS/NZS 3008.1.1:2025's Section 4 (2026-09-09)**: the parent Phase 2 spec flagged
"§4.1.2 Voltage rise" as a new clause worth reading before digitising Section 4 further, in case it
changed anything for this calculator. Read directly (via the second, OCR'd copy of the standard — see
the integration spec's own section on that file) — **the clause numbering assumption was wrong (there
is no §4.1.2 "Voltage rise" clause), but the substance is confirmed and reassuring**:
- Section 4 is titled "Voltage drop **and voltage rise**", but its own numbered clauses (4.1-4.8) are
  all voltage-*drop* content — no separate voltage-rise formula or methodology exists anywhere in the
  clause text.
- Appendix A's two full worked examples for voltage rise (A.11, A.12 — "Minimum conductor size to
  satisfy voltage rise considerations") both explicitly use "Method 4.2" (the same mV/A.m /
  impedance-based method this project's engine already implements via R/Xc), cascade multiple
  segments, and sum them — architecturally identical to this calculator's own design. This is
  independent confirmation the calculator's cascade-and-sum approach is correct, not a design gap.
- The 2% limit is still sourced from **AS/NZS 4777.1** (cited by name in both the worked example text
  and the standard's own reference list) — 2025 doesn't redefine or relocate this limit into
  AS/NZS 3008.1.1 itself. This calculator's own "AS/NZS 4777.1-2024, 2% default, user-editable"
  design remains correctly sourced.

Worked example A.12 explicitly
states "In this example AS/NZS 4777.1 does not apply voltage rise requirements for consideration of
voltage rise on the consumer mains" for an installation that "incorporates a means to prevent
high-export voltages" (e.g. an export limiter) — for such installations, only the *inverter circuit*
segment needs to meet the 2% limit, not the full cascade back to the point of supply. CableMetric
implements this as an explicit high-export-voltage-prevention option and requires exactly one segment
to be identified as consumer mains. The physical total always includes every segment; the assessed
total excludes only that marked segment. The user must verify that the installed control and network
requirements support applying this treatment.
