Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.appliedaifoundation.org/llms.txt

Use this file to discover all available pages before exploring further.

The EU ETS engine in src/lib/utils/portClassifier.ts and src/lib/services/VoyageSegmentService.ts produces per-leg covered CO₂ figures used everywhere in the app — fleet ETS dashboard, vessel detail voyages table, EU ETS report.

Port classification

A port is classified EU/EEA if its UN/LOCODE country code (the first two letters) matches one of these 30 codes:
EU members:
AT BE BG HR CY CZ DK EE FI FR DE GR HU IE IT
LV LT LU MT NL PL PT RO SK SI ES SE

EEA members (non-EU):
IS LI NO
Anything else is non-EU.

Voyage type from leg endpoints

DepartureArrivalVoyage type
EU/EEAEU/EEAINTRA_EU
Non-EUEU/EEAINTO_EU
EU/EEANon-EUOUT_OF_EU
Non-EUNon-EUNON_EU

Coverage factors

Applied only to emissions at sea during the leg:
Voyage typeSea coverage
INTRA_EU100%
INTO_EU50%
OUT_OF_EU50%
NON_EU0%

Port emissions: per-record classification

Emissions while at port are not tied to the voyage type. They’re classified by the actual port LOCODE on each record:
  • EU port → 100% covered
  • Non-EU port → 0% covered
This matters for multi-port voyages. Example: a voyage Rotterdam → Hamburg → Le Havre → Singapore has three intra-EU legs (100%) followed by an out-of-EU leg (50%). Time spent at the Hamburg and Le Havre intermediate stops is 100% covered; time at Singapore is 0%.

Phase-in factor by year

YearPhase-in
2023 and earlier0%
202440%
202570%
2026 onwards100%

Final formula

Covered CO₂ (per leg) = (Sea CO₂ × Sea Coverage) + (EU-Port CO₂ × 1.0)
ETS Emissions          = Σ Covered CO₂ (across legs) × Phase-In Factor
ETS Cost (€)           = ETS Emissions × EUA Price
EUA price defaults to €75/tonne unless overridden via DEFAULT_EUA_PRICE.

Voyage segmentation (BOSP-based)

The extractVoyageLegs() function walks consumption records chronologically and creates a new leg whenever it encounters a BOSP (Beginning of Sea Passage) event. Records before the first BOSP are buffered and attached to the first leg. This means:
  • A voyage with 4 BOSP events produces 4 legs
  • Repeated voyage numbers (e.g. 99W, 99E, 99W) are split into segments (99W-1, 99E-1, 99W-2)
  • Coverage is applied per leg, not per voyage

Implementation

  • src/lib/utils/portClassifier.tsisEUPort, determineVoyageType, getETSCoverageFactor, getETSPhaseInFactor, extractVoyageLegs, calculateLegsETSEmissions
  • src/lib/services/VoyageSegmentService.ts — orchestration layer used across pages and reports

Reference