# 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 (2017)** is digitised everywhere the 2017 standard tabulates it: Tables 7, 8, 13 and 14
all have an Aluminium column, always starting at 16 mm². The 2017 edition does not tabulate Aluminium
for the 110°C family and does not provide a general flexible-Aluminium table. Flexible Aluminium is
therefore edition-scoped to the 2025 Australian selection.

**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.)
- Separate 2017 flexible-core ratings for anything other than `MultiCore|Thermoplastic` and
  `MultiCore2C|*`. The 2025 edition does not need separate flexible arrays because its CCC tables
  expressly apply to both rigid and flexible conductors.

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`. This is the 2017 table for
**multi-core** cable only; 2017 single-core cable reads Table 34 (next section). 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).

### 2017 single-core cable (`RESISTANCE_SINGLECORE`)

Added 2026-10-24. Until then 2017 single-core cable reused Table 35 on the assumption that Table 34
was "near-identical". It is the same up to about 120 mm² and then runs about 1% lower (copper
240 mm² at 75°C: 0.0948 in Table 34, 0.0955 in Table 35; 500 mm² at 75°C: 0.0506 against 0.0525), so
single-core runs at 240 mm² and above were slightly conservative. jCalc.net cites "Table 34" for 2017
single-core cable and uses its values.

- Source: AS/NZS 3008.1.1:2017 Table 34 (p.102, PDF page 104), read from the PDF's text layer. Own
  size list, 1 to 630 mm² (the sizing sizes stay 1 to 500 mm²); copper 45/60/75/80/90/110°C,
  aluminium 45/60/75/80/90°C (from 16 mm², no 110°C).
- **The 80°C column is sparse**: filled in only for copper 6, 10, 16 and 25 mm² and aluminium 16 to
  150 mm² ("—" elsewhere, stored as `null`). `resistanceAt()` and `resistanceAtCeiling()` therefore
  skip a column that has no value for the size and read the next one up, which is what jCalc does
  (16 mm² X-90 at 78 °C reads 1.42 at 80°C; 185 mm² X-90 at 78 °C reads 0.129 at 90°C).
- Cross-check: the table agrees with 2025 Table 4.5(A)/(B) cell for cell except the 2025 table's fully
  populated 80°C column and copper at 110°C from 300 mm² (0.0846 against 0.0849 at 300 mm²).
- `resistanceSourceFor()` returns it for the `SingleCore` family on the 2017 and New Zealand datasets;
  `resistanceTableName()` cites "Table 34". Flexible single-core cable still reads Table 37.
- Verified against jCalc on 128 scenarios (2017 AU, 3-phase 400 V, single-cores 3x1C+E, trefoil,
  underground wiring enclosure, copper and aluminium, V-90 and X-90, every size 1 to 500 mm² at a light
  and a 90% load): live and earth resistance, rated current and maximum distance all match.
- **Earth core temperature cap** (same change): the earth core's resistance column is the live cable's
  operating temperature held at the *earth* insulation's own maximum (`earthMaxTemp` in the result),
  not the live cores' maximum. Live V-90 with an X-90 earth, overloaded, reads 75°C live and 90°C
  earth; live X-110 with a V-90 earth reads 110°C live and 75°C earth. Only differs from before when
  the earth insulation differs from the live insulation (single-core cable).

**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)`. Two refinements added 2026-10-24
to match jCalc.net: the temperature is **rounded to a whole degree** first (75.04 °C reads the 75 °C
column, not 90 °C), and the lookup temperature is **capped at the insulation's maximum** (an
overloaded 1 mm² cable on 63 A computes over 1,000 °C but reads the 75 °C column for V-90; the
returned `opTemp` itself is not capped). Rounding makes results marginally less strict at column
boundaries than the previous unrounded rule. 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).

### Flexible cables (`RESISTANCE_FLEXIBLE`, `RESISTANCE_FLEXIBLE_2025`)

Added 2026-10-24. Flexible cords and flexible cables with **copper** conductors have their own, higher
a.c. resistance tables, so ticking "Flexible cable" now reads them instead of the rigid values:

| Edition | Table | Covers | Columns |
|---|---|---|---|
| 2017 | Table 37 (PDF p.105) | single-core to 630 mm², multicore to 500 mm² | 45/60/75/90/110°C |
| 2025 | Table 4.10(A) single-core (PDF p.119), Table 4.10(B) multicore (PDF p.120) | single-core to 630 mm², multicore to 500 mm² | 25/30/45/60/75/90/110°C |

Every value was read off the rendered page image. At 75°C the flexible values run about 5 to 7% above
the rigid ones at 16 to 95 mm² (25 mm²: 0.949 against 0.884 Ω/km). Rules:

- `resistanceSourceFor(dataset, cableFamily, flexible, material)` picks the table: single-core cable
  uses the single-core flexible table, every multi-core type uses the multicore one.
- The standard publishes **no flexible aluminium table**, so aluminium keeps the rigid values (flexible
  aluminium ratings exist for 2025 only; see the rating notes above).
- The earth core follows its own flexibility: a single-core earth core reads the single-core flexible
  table when "Earth flexible" is ticked; a multi-core earth core follows the active cores.
- The flexible 2025 tables include 25 and 30°C columns, and so do the rigid 2025 tables (Table 4.5
  also has an 80 °C column; Table 4.7 does not). Both rigid tables gained those columns on
  2026-10-24, so a lightly loaded cable now reads the 25 or 30°C column like the standard.
- Results and reports name the table actually used via `resistanceTableName()`.
- jCalc.net cross-check (576 saved scenarios): flexible copper voltage drop was 3.9% low on average
  before this change and is now within 0.3%; chosen cable size matches in 564 of 568 comparable
  scenarios (it was 554).

## 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. The 2025 selector routes these datasets through
`computeSizing()` and `voltagerise.js` without blending them into the 2017 tables. Selecting "2017
Australian conditions" or "New Zealand conditions" is unaffected and continues to read 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`.)

**Rigid and flexible conductors use the same 2025 CCC matrix.** The 2025 Preface says the flexible
and non-flexible Copper CCCs were amalgamated, Clause 3.3.2.2 directs flexible installation wiring
to Tables 3.9-3.20, and Note 1 beneath those tables states that each table applies to cables with
rigid or flexible conductors. The engine therefore applies a flexibility factor of exactly `1.00`
and selects the table's material-specific `Cu` or `Al` column directly. Reverse-engineering the old
2017 Copper flexible columns produces ratios close to one but no stable multiplier; those legacy
ratios are not used to alter the exact 2025 Aluminium values.

The 2025 Aluminium Cross-linked 90°C matrices are Tables 3.10, 3.13, 3.16 and 3.19. Aluminium 110°C
matrices are Tables 3.11, 3.14, 3.17 and 3.20. All begin at 16 mm². The APEC flexible-Aluminium
product is treated as 110°C in the product workflow, so its CCC comes from the matching 110°C table
for the selected single-core/multicore configuration and installation method.

**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 NOT configuration-independent (corrected 2026-10-24).** 2025 tabulates
  resistance separately per cable configuration: Table 4.5 single-core, 4.7 multicore circular, 4.9
  multicore shaped. An earlier version of this note claimed 4.5 and 4.7 are identical and digitised
  only 4.5; that rested on a mis-read spot-check (the "4.7" value quoted for 500 mm² at 90 °C was
  really the 4.5 figure). Read in full, they agree at small sizes but differ from about 50 mm² up
  (copper 240 mm² at 75 °C: 0.0948 in 4.5(A), 0.0955 in 4.7(A); 500 mm² at 90 °C: 0.0525 and 0.0544).
  Both are now digitised: `RESISTANCE_2025` (Table 4.5, single-core) and `RESISTANCE_2025_MULTICORE`
  (Table 4.7, multicore circular), and `resistanceSourceFor()` picks by cable family. Table 4.7(A)
  matches 2017's Table 35 at 75 °C for every copper size; they differ only at 110 °C for large sizes.
  Table 4.9 (shaped conductors) is not digitised, matching the reactance simplification.
- **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.
- **Flexible-cable reactance uses the dedicated 2025 Tables 4.2(A)/(B).** Table 4.2(A) supplies
  single-core Trefoil and Flat-touching PVC/XLPE/Elastomer values from 0.5–630 mm²; Table 4.2(B)
  supplies multicore circular-conductor values from 0.5–500 mm². Reactance is independent of
  conductor material, so these exact arrays apply to both Copper and Aluminium. `engine.js` selects
  them whenever the Flexible option is on; this is separate from current carrying capacity, whose
  2025 tables explicitly use one common rigid/flexible matrix (factor 1.00).

**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. Pinned in `tests/resistance-reactance-2025-tests.js`. Table 4.5's 25/30/80 °C
columns and the whole of Table 4.7(A)/(B) were added 2026-10-24 from the rendered pages (2025 PDF
printed pp.102-103 and 106-107) and are pinned in `tests/rigid-resistance-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

- **Load power factor** (Worst case or Specified) IS exposed, added 2026-10-24, matching jCalc's own
  toggle. The default is **Worst case for every load unit, including kW and hp**: 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 resistance-only `Vd = k×I×L×Rc/1000`. "Specified" uses the entered power
  factor in `Rc·cosφ + Xc·sinφ` for any load unit (A, kVA, kW, hp). kW and hp always use the power
  factor to find the load current, in either mode. DC has no power factor and ignores the setting.
  (Before 2026-10-24 kW and hp used the specified power factor automatically and there was no switch,
  so the same kW load could select a smaller cable than on jCalc; with matching modes the two agree.)
  The engine reads `inp.pfMode` (`"Specified"` or anything else for worst case).
  "Conductor temperature" (Calculate/Maximum) is also 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", resistanceSourceFor(dataset, "MultiCore", false, "Copper"))`
from `engine.js` — a **fixed** 75°C column of the multicore copper table (2017 Table 35, 2025
Table 4.7(A); `RESISTANCE.Copper` / `RESISTANCE_2025_MULTICORE.Copper` in `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.

**Results layout (changed 2026-10-24)**: all three modes now show the same breakdown, like jCalc:
cable size, resistance, reactance, impedance, the drop in volts and percent, and the voltage at load,
plus a collapsed "Show calculation steps" section with the working (impedance, then the drop formula
with the numbers, or the maximum-distance formula `L = ΔVmax × 1000 / (k × I × Zc)`). The engine
returns `Rc`, `Xc`, `Zc`, `vdropV`, `vdropPct` and `voltageAtLoad` in every mode; at the maximum
distance the drop is, by definition, the allowed limit. The steps use the `.steps`/`.stepsrow`
classes so printed reports leave them out.

**Allowable voltage drop** (Minimum size and Maximum distance modes): the list runs 1 to 5% in 0.5%
steps plus 7%, and "Other" accepts any value from 0.01 to 100%. The Cable Size Calculator has the same
list (1 to 5%) and "Other" field.

**Verified against jCalc.net (2026-10-13, 20 scenarios in 2017 mode)**: voltage drop %, volts,
`Rc`, `Xc`, `Zc`, minimum size and maximum distance agree in all 20 (one 0.01% rounding case). Two
known differences: DC here uses resistance only while jCalc adds the small a.c. reactance (agrees to
0.01%), and the 1-phase/DC "reference rated current" here comes from the two-core table while jCalc
appears to show the three-core figure. The page's resistance and reactance are identical in 2017
and 2025 mode at every size (verified 2026-10-24), so it gives the same drop in both editions.

## 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**: 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). The **Conductor
temperature** choice decides which temperature the resistance is read at:

- **Maximum (default since 2026-10-24)**: each segment's resistance is read at its insulation's
  maximum permissible temperature (75°C for V-90, 90°C for X-90, 110°C for X-110). This matches
  jCalc.net's Voltage Rise calculator, which reads its 75°C column, and is the conservative choice.
- **Calculate**: the Clause 4.4 operating-temperature calculation per segment (the original design,
  spec decision 5). It reads a cooler column (typically 26 to 60°C), so the rise is lower, by about 2
  to 22% against jCalc on the scenarios tested. It could pass a circuit jCalc fails (415 V, 30 kW,
  25/35/25 mm² copper at 47/78/31 m: 1.88% against jCalc's 2.1% on a 2% limit).

jCalc.net cross-check after the change (7 comparable scenarios): totals within 0.15 percentage points
in every case, and the 47/78/31 m circuit now fails at 2.08%, as on jCalc. jCalc adds each segment's
percentage after rounding it to 0.1%, so its totals can differ from the true sum by up to about 0.1%.

**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). The **Load power factor** choice
works as on the Cable Size Calculator: Worst case (default, every rating unit) uses
`Zc = √(Rc²+Xc²)`; Specified uses the entered power factor. A kW rating always uses the power
factor to find the inverter current.

**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.
