Sea State Explorer
What the Sea State Explorer computes, from which data, by what rule. Written for metocean engineers, naval architects and anyone, human or automated, who needs to understand or cite what the tool shows.
Click a point at sea, choose calendar months, and the tool reports how the sea behaved at the nearest data cell over the whole record, month by month. Everything shown is a long term statistic of a numerical reanalysis: a wave model run for decades and constrained by observations, sampled every 3 hours on a global grid. Nothing on the page is a measurement at your point, and nothing is a forecast.
What it answers, for the selected point and months:
What it does not do:
Two builders exist and write the same tile format, so the explorer runs on either. Which one a deployment uses is named in the Data sources table at the foot of the explorer, in the licence wording under it, and in the PDF's data basis line (for example "ERA5 reanalysis (ECMWF / Copernicus C3S)" or "WAVERYS wave reanalysis (Copernicus Marine) + ERA5 wind", with the period and sample count). The data point line under the location gives the cell centre, the grid spacing and the distance from your click. This page describes both builders.
tools/build_dataset_era5.py)reanalysis-era5-single-levels on a 0.5 by 0.5 degree grid, at 00, 03, 06, 09, 12, 15, 18 and 21 UTC every day.swh, the Hs used everywhere), significant height of wind waves and of total swell, mean wave period, peak wave period (pp1d), mean wave direction (mwd), and the 10 m wind components u10 and v10.tools/build_dataset_waverys.py)cmems_mod_glo_wav_my_0.2deg_PT3H-i (the MFWAM model with altimeter assimilation), 3 hourly.VHM0 (Hs), VTPK (peak period), VMDR (mean wave direction, the direction waves come from).Both builders write a download ledger (audit.jsonl: one line per source file with its SHA256, size and the samples it added) and are covered by tools/verify_dataset.py, which reconciles the ledger to the checkpoint, re-emits the tiles and requires them to be bit-identical to the deployed files, recomputes sampled cells with independent code and runs invariants over every tile. tools/validate_waves.py compares the served tile against measured buoy records where those are available.
The scatter table is its own tile set (joint/, written by tools/emit_joint_tiles.py) from the ERA5 checkpoint, aggregated over 1.0 degree blocks. It carries its own source label and period, printed in the note under the table on the explorer, and these can differ from the wave backbone's. See 3.13.
Builder tools/build_currents_cmems.py. Two products, one tile set (cur/, 5 degree tiles; a click uses the nearest cell within 25 km when the tidal solution is present, 60 km otherwise):
cmems_mod_glo_phy_anfc_merged-uv_PT1H-i), variables utide and vtide: a barotropic (depth averaged) FES-forced tidal solution on the native 1/12 degree grid. The builder fits 90 days of hourly fields starting on the date given at build time (default 1 January 2025); the window is recorded in the currents manifest as tide_window.cmems_mod_glo_phy_my_0.083deg_P1D-m), daily mean uo and vo at six depth levels: 0.494, 29.444, 77.853, 155.850, 318.127 and 643.566 m. The native 1/12 degree grid is decimated by three to 1/4 degree. Years are given at build time (builder default 2012 to 2021) and recorded in the manifest as bg_period. GLORYS excludes tides by construction, so this is the non-tidal residual (wind driven, density driven and eddy flow).Builder tools/grab_depth.py. The ETOPO 2022 Global Relief Model, 60 arc-second surface elevation grid from NOAA National Centers for Environmental Information, block-averaged (6 by 6 cells) to 0.1 degree and stored as integer metres in 10 degree tiles of 100 by 100 cells (depth/). Tiles with no sea at all are not written.
coastline.js): the world view coastline, the 1 degree land mask used by the demonstration mode, and the sea test for the asset pipeline cut (5).bathy.js, builder tools/build_bathy.py): the depth band fallback and the world-view depth contours. Deeper levels are deliberately not included.borders.js).places.js).coast/, builder tools/build_coast_tiles.py): built either from GSHHG, the Global Self-consistent Hierarchical High-resolution Shoreline database (Wessel and Smith, 1996), or from Natural Earth 1:10m land and minor islands. The tile manifest says which: 5 degree tiles at 0.0001 degree precision for GSHHG, 15 degree tiles at 0.001 degree for Natural Earth.Builder tools/build_cyclones.py. IBTrACS version 4 (release v04r01), the "since 1980" list CSV from NOAA NCEI, which merges every agency's best tracks. Wind is read from USA_WIND (1-minute sustained, the basis of the Saffir-Simpson thresholds used on the page) and only where that is absent from WMO_WIND.
NOAA Climate Prediction Center's Oceanic Niño Index (oni.ascii.txt: the 3-month running mean sea surface temperature anomaly in the Niño 3.4 region, ERSSTv5). The table is archived with each build and its SHA256 written to the ledger, so a classification can be reproduced after NOAA revises the series.
Builder tools/build_assets.py with ga_ingest.py, anp_ingest.py and fetch_intl.py. Each source is optional; a source that cannot be fetched is a log line, not a missing build. The deployed assets.json lists exactly the sources it contains, and the explorer prints each one's attribution sentence in its footer. The identifiers below are the source ids the builder writes.
| Source id | What it contributes | Provider and licence |
|---|---|---|
goget | Offshore field unit centroids (rows marked offshore only) | Global Oil & Gas Extraction Tracker, Global Energy Monitor, CC BY 4.0 |
gem-ggit | Gas pipeline routes, offshore segments only | Global Gas Infrastructure Tracker, Global Energy Monitor, CC BY 4.0 |
gem-goit | Oil and NGL pipeline routes, offshore segments only | Global Oil Infrastructure Tracker, Global Energy Monitor, CC BY 4.0 |
gem-lng | LNG terminals, one per site (floating units marked FSRU or FLNG) | Global Gas Infrastructure Tracker, Global Energy Monitor, CC BY 4.0 |
osm | Offshore platforms (man_made=offshore_platform) via Overpass | OpenStreetMap contributors, ODbL |
osm-pipelines | Submarine pipelines (man_made=pipeline with an offshore, seabed, underwater or sea location, or submarine=yes) | OpenStreetMap contributors, ODbL |
sodir-wells, sodir-facilities | Norwegian wellbores and fixed facilities | Norwegian Offshore Directorate FactPages, Norwegian Licence for Open Government Data |
bsee-platforms, bsee-wells, bsee-pipelines | Gulf of Mexico standing structures, boreholes and pipeline arcs; borehole statuses joined from the eWell raw data by API number | US BOEM / BSEE, public domain |
ga | Australian offshore wells, platforms, facilities and pipelines from Geoscience Australia's ArcGIS services (Oil_Gas_Infrastructure, NOPIMS wells), filtered to 48° S to 8° S and 95° E to 170° E; water bores dropped | Geoscience Australia, CC BY 4.0 |
anp-wells, anp-fields | Brazil: the Tabela de Poços wells table (offshore rows only) and Campos de Produção field polygons as bounding-box centre markers | ANP (Agência Nacional do Petróleo, Gás Natural e Biocombustíveis) open data |
A source is listed in the explorer footer only when it is included in the deployed data.
Notation: m is a calendar month (January to December), nm the number of valid 3-hourly samples the cell holds for that month over the whole record, T a wave height threshold in metres.
nm ≥ 0.3 × maxcells(nm), that is, when it holds at least 30 percent of the largest sample count any cell has for that calendar month. Cell-months below that (seasonal ice, partial coverage) are written as no data and every statistic for them reads "no data". The scatter tiles apply the same rule.Each builder keeps, per cell and calendar month, a histogram of Hs in 0.25 m bins from 0 to 15 m: bin k holds samples with 0.25k ≤ Hs < 0.25k + 0.25, and the top bin also takes everything from 15 m up. The thresholds are 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 6, 7, 8, 9 and 10 m, all bin edges, so the count at or above a threshold is exact:
E_m(T) = (number of samples in month m with Hs ≥ T) / n_m
stored as a rounded whole-number permille and shown as a percentage. It is the probability that a 3-hourly sample is at or above T; the page wording says "exceeds". Percentages are printed to one decimal below 10 percent, as whole numbers above, and as "<0.1%" below 0.05 percent.
The threshold table and the exceedance curve stop at 6 m unless your operational limit is higher; the data keeps all fifteen thresholds and the interpolation and extremes use them all.
Selected months are combined by weighting each month's value by its length in days, D = [31, 28.25, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], over the months that carry data:
E(T) = Σ_m D_m × E_m(T) / Σ_m D_m (m over the selected valid months)
The sample count given in the PDF's data basis is the sum of nm over those months. The same day weighting is used for the wave and wind roses, the peak period distribution, the wind mean and P90, the daily cycle and the background current statistics. Mean Hs (3.6) is the one figure weighted by sample count instead.
L (accepted range 0.25 to 15 m) is read off the combined exceedance by straight-line interpolation between the points (0 m, 100%), (T1, E(T1)), ... (T15, E(T15)). At the last threshold its own value is used; beyond it the last value is used and printed with a "<" prefix.D = E(L) × 0.3044, that is E(L)/100 × 30.44 days, printed to one decimal below 3 days.Per cell and month, meanm = Σ Hs / nm, stored to 0.1 m. The prevailing conditions line combines the selected months by sample count: Σm meanm × nm / Σm nm, printed to 0.1 m. The map shading raster is a sample-weighted mean over 2 degree blocks.
pp1d or WAVERYS VTPK, binned in one-second bins: bin b = clip(int(Tp) - 2, 0, nb - 1), so bin b holds b + 2 ≤ Tp < b + 3 seconds, bin 0 also takes anything under 2 s, and the top bin takes everything from its lower edge up. ERA5 has 14 bins (top bin 15 s and longer), WAVERYS 24 (top bin 25 s and longer). Only samples with a finite peak period are counted, so the histogram's own total is its denominator.b + 2.5 seconds. The prevailing conditions line's "typical peak period" is the day-weighted mean of those monthly values, and tile sets built before the histogram existed fall back to a chart of them.mwd or WAVERYS VMDR: the direction waves come from, in degrees clockwise from north. Wind direction is the direction the wind blows from, computed as the bearing of (-u10, -v10): atan2(-u10, -v10) in degrees, modulo 360.k = floor(direction / 30) mod 12, so sector k covers [30k, 30k + 30) degrees: sector 0 is 0 to 30 (from the north to north-east), sector 9 is 270 to 300.30k + 15 degrees, on the 16-point compass (nearest 22.5 degree point). The wording is "waves most often from the [compass point] (about [N]% of the time)"; the arrow beside it points the way the waves travel. Petals are drawn centred on the sector centre, on the page and in the PDF.sqrt(u10² + v10²), at each 3-hourly step where the wave field is finite, in a histogram of forty 1 m/s bins, the top bin taking everything from 39 m/s up.ceil(0.9 × n), so it is a whole number of m/s.b whose cumulative count reaches ceil(q × nm) for q = 0.99 and 0.999, reported as that bin's upper edge, (b + 1) × 0.25 m, rounded to 0.1 m.T is a run of consecutive 3-hourly samples with Hs < T (strictly below). Its duration is 3 hours times the number of samples.T), and is attributed to the calendar month in which it started. Run state carries across month boundaries.D hours with Hs < T a typical month holds, so a 3 day calm holds three 24 hour periods and a calm month about 30. Because tiles keep spell counts by bin rather than exact lengths, the hours inside spells of D or longer are estimated as all the hours below T that month (100 minus the interpolated exceedance at T, 3.5, times the month's hours) less the hours in shorter spells (each short bin at the mean of the 3 hourly lengths it can hold: 3, 7.5 and 16.5 hours below 24), kept between what the long bins could hold at their lower and upper edges. Each long spell then loses on average (D - 3) / 2 hours to the part that does not fill a whole period; runs cut at 240 hours divide exactly, so the top bin is charged only for the share of the month that is not calm. The result never exceeds the month's hours divided by D, and spells count in the month they started. The 240 hour cut does not change this figure, because a cut spell's hours are still counted.slot = floor((UTC hour + longitude / 15 + 1.5) / 3) mod 8. Slot s therefore covers local solar times from 3s - 1.5 to 3s + 1.5 hours and is labelled by its centre: 00:00, 03:00, ... 21:00. Solar noon is 12:00 by definition; clock time and daylight saving are not applied.(max - min) / mean < 0.06, the line says there is no meaningful daily cycle, which is the usual answer in the open ocean.δ = -23.44° × cos(2π/365 × (N + 10)) with N the day of year at mid-month, day length 2 × H / 15 hours with H = acos(-tan(lat) × tan(δ)) in degrees, sunrise and sunset symmetric about 12:00 local solar time, and polar day or night when the cosine argument leaves the range -1 to 1.k = min(floor(Hs / 0.5), 13) holds 0.5k ≤ Hs < 0.5k + 0.5 m for k = 0 to 12, and bin 13 holds 6.5 m and above. Tp bins are the 14 one-second bins of 3.7 (bin 0 also under 2 s, bin 13 15 s and longer).-89.25 + i degrees latitude and -179.75 + j degrees longitude (the south pole row is dropped). Masked cell-months contribute nothing. The page takes the block containing the wave cell.The El Niño and La Niña panel is switched off on the explorer (SHOW_ENSO = false); the data keeps being built. The rule, for the record: each calendar month is tagged from the single ONI season centred on it (DJF for January through NDJ for December) by anomaly ≥ +0.5 °C = El Niño, ≤ -0.5 °C = La Niña, else neutral, with no persistence requirement. A whole month sits in one phase. Tiles carry per-phase sample counts, mean Hs and exceedance at every threshold; cyclone tiles carry per-phase storm counts and storm-days with per-phase-year denominators. On WAVERYS the phase fields are ERA5 statistics grafted from the nearest 0.5 degree cell.
row = floor((lat - lat0) / 0.1), likewise for longitude), depth = minus the stored elevation when that is negative; a non-negative elevation (land) gives no reading.u(t) = a0 + Σ_i [ A_i cos(ω_i t) + B_i sin(ω_i t) ] (and likewise v(t)) constituent speeds, degrees per hour: M2 28.9841042 S2 30.0000000 N2 28.4397295 K1 15.0410686 O1 13.9430356 M4 57.9682084with
t in hours from the window start. K2 and P1 cannot be separated from S2 and K1 in 90 days and fold into them. A cell is used only if at least 98 percent of its hours are finite.f × amplitude. The fitted coefficients are divided by the Schureman nodal factors evaluated at the window midpoint, with N the longitude of the lunar ascending node in degrees, N = (125.0445479 - 0.0529539222 × days since 2000-01-01 12:00) mod 360:
f_M2 = 1.0004 - 0.0373 cos N + 0.0002 cos 2N f_K1 = 1.0060 + 0.1150 cos N - 0.0088 cos 2N + 0.0006 cos 3N f_O1 = 1.0089 + 0.1871 cos N - 0.0147 cos 2N + 0.0014 cos 3N f_S2 = 1 f_N2 = f_M2 f_M4 = f_M2²The node angle used is recorded in the currents manifest as
nodal_node_deg. The attribution sentence in the explorer footer states whether the deployed tiles were built with or without this correction (an earlier build of the tiles predates it).atan2(u, v), at that maximum, folded into 0 to 179 degrees.The constituents other than N2 and the constant term are reconstructed over 35 days at 10 minute steps (a full spring-neap cycle at mean tide). The peak speed of each day is taken; spring is the largest daily peak and neap the smallest. Both are depth-averaged (barotropic) rates, stored to 0.01 m/s. N2 is left out by the usual mean-springs convention and the constant term is not a tidal peak.
F = (K1 + O1) / (M2 + S2) from the constituent amplitudes (99 where the semidiurnal sum is under 0.0001 m/s; stored capped at 99). The panel reads it as: F < 0.25 "semidiurnal: it peaks roughly every 6.2 hours"; 0.25 ≤ F ≤ 1.5 "mixed, mainly semidiurnal: peaks roughly every 6 hours, alternating stronger and weaker"; 1.5 < F ≤ 3 "mixed, mainly diurnal: one strong and one weak peak most days"; F > 3 "diurnal: it peaks roughly every 12.4 hours".
F > 1.5. A run longer than half a cycle is a neap lull, not a turn of the tide.The source statistic is the depth mean. People work at the surface or at the bed, so both are shown through a power-law profile with exponent 1/7 at the site's ETOPO depth d:
surface = 8/7 × depth mean (a 1/7 profile averages to 7/8 of its surface value) bottom metre = surface × (1 / d)^(1/7)
applied to both the spring and the neap rate. The lines read "Tidal stream at the surface: typical peak about X m/s (N kn) at springs, Y m/s at neaps" and "Near the seabed (bottom metre, at ~d m depth): about ...". With no depth available the seabed line falls back to "Near the seabed expect roughly two thirds of the surface stream". The figure note on the explorer states the assumption and that measured profiles vary.
sqrt(uo² + vo²) of the GLORYS12 daily means is accumulated per calendar month in 0.025 m/s bins up to 2 m/s, for the surface level (0.494 m) and for the deepest of the six levels that is wet at that cell (the near-seabed proxy; its depth is stored per cell).ceil(0.9 × total); both are reported at the bin centre, (b + 0.5) × 0.025 m/s.The table "Through the water column" combines three components the way DNVGL-RP-C205, Environmental conditions and environmental loads, edition August 2017, describes in its section 4.1.4, Design current profiles. The clause numbers below were checked against that edition's text; only the definitions the text states are repeated here.
v_tide(z) = v_tide(0) × ((d - z) / d)^(1/7)with
z the depth below the still water level (positive downwards here; the standard's own definition list takes z positive upwards), d the water depth, and v_tide(0) = 8/7 × the spring depth-mean stream (4.5). The exponent is the "typically 1/7" of 4.1.4.3.z = -d0 to the still water level, or a slab profile, with the note that the profile giving the highest loads for the application should be applied. The tool uses the linear profile.d0 below the still water level, and defines d0 = 50 m and the exponent α, typically 1/7. Implemented as
v_wind(z) = v_wind(0) × max(0, 1 - z / 50)
v_c,wind(0) = k × U_1hour,10m with k = 0.015 to 0.03, U being the 1 hour sustained wind speed at 10 m. The tool uses k = 0.03, the top of that range, and takes the site's P90 10 m wind over the selected months (3.9) as the 1 hour wind; the builders' 3 hourly reanalysis values sit close to hourly means. The clause is written for deep water along an open coastline; the tool applies it wherever a wind statistic exists, as a screening figure.z = 0, the deepest modelled level's value at its own depth, linear between the two, and held constant below. With no deeper level the surface value is held through the column.d - 1, then "1 m above bed" at z = d - 1. With no site depth only the surface row is shown and the tidal column is surface-only.0.03 × 20 = 0.60 m/s, citing DNV-ST-N001 11.12.2.3. We have not checked this clause against the published standard; the 20 m/s figure is Thrust Maritime's own design practice. The table closes with "Climatological figures, not extreme-value design values."The same section of the standard, in 4.1.4.5 to 4.1.4.8, says that the variation of current over depth depends on the local oceanographic climate, the vertical density distribution and the flow into or out of the area, may vary from season to season, that deep water profiles may be complex with current direction changing 180 degrees with depth, that long term measured profiles can be parametrised with empirical orthogonal functions, and that conditions close to the sea bed are the subject of DNVGL-RP-F105. The tool does none of that; its column is a screening picture from climatological statistics.
assets.json.(round(lat × 50), round(lon × 50)). The first well in a cell is kept; later ones in the same cell are collapsed into it and donate any water depth, year, operator or status the survivor lacks. Multi-wellbore pads and a registry's per-phase duplicate rows collapse to one marker by design."In service only" is on by default and applies to wells only. A well is hidden when its status matches abandon, plug, p&a, paa, junk, dry, cancel, wildcat, apprais, explor, soil, stratigraphic; otherwise it is shown when the status matches produc, inject, develop, operat, online, in service, active, completed, suspend, shut, drill. A well with no usable status is hidden by this filter; untick it to see everything. The other filters are type, a water depth range (assets with no known depth are hidden while a range is set) and free text over status, operator and name; a count states how many assets match.
Names are missing from some registers. Records without one carry a placeholder ("Unnamed platform", "Unnamed well", "Unnamed unit"), and the pipelines from Geoscience Australia and BSEE currently carry "Pipeline" for every line because the published layers we use do not include pipeline names. GOGET names are trimmed of their bracketed country and "Oil and Gas Field" suffix so the hover shows type and country separately.
The explorer's terms line reads: "Free to use for individual planning reference, and free to cite: Thrust Maritime, Sea State Explorer, the location and the date you read it, with a link to the result. Automated bulk extraction of the tool's data tiles is not permitted; the underlying open datasets are available from the original providers credited below, and the methodology page states every source and derivation."
A citation therefore carries four things: the publisher, the tool, the location as shown on the page, and the date, plus the link to the result. For example:
Thrust Maritime, Sea State Explorer, [location as shown on the page], read [date], [link copied with "Copy link to this result"]
If the underlying dataset matters to your reader, add the source and period from the PDF's data basis or the Data sources table (for example "WAVERYS wave reanalysis (Copernicus Marine) + ERA5 wind, 1980-2023, 3 hourly") and the provider's own attribution sentence from section 8. The PDF summary carries the same link under "Interactive version of this page" and lists every source in its Sources section.
Every result has a URL that reproduces it. "Copy link to this result" writes the state into the URL fragment, and the address bar updates in place as you change anything:
https://seastate.thrustm.com/#loc=25.00,-90.00&m=5,6,7&h=1.5&wt=1.5&wd=48 loc latitude,longitude in decimal degrees (WGS84), two decimals m selected months, 1 to 12, comma separated (omitted when all twelve are on) h operational limit in metres (omitted at the default of 2 m) wt weather window threshold in metres wd weather window minimum duration in hours
m and h are written only when they differ from the defaults; wt and wd are written whenever the tile set carries weather windows. The query form ?loc=... with the same keys is accepted on read. An inbound link centres the map on the point, selects it and applies the months, limit and window pickers; editing the fragment in an open tab re-applies it. Because the state rides the fragment, links work on the static host, inside the embedding page and in the PDF.
Weather windows decide when a lift can go. Thrust Maritime provides specialist lifting solutions for subsea operations. This tool is the screening step; a project-specific metocean study, extreme value analysis and vessel response work are what comes next.
The sentences below are the ones the site carries in its data manifests and prints in the explorer footer and the PDF. The footer lists exactly the layers a deployment contains; this page lists every sentence a build can produce.
ERA5 (Copernicus Climate Change Service, ECMWF), licence CC BY 4.0. "Contains modified Copernicus Climate Change Service information [period]. ERA5 hourly data on single levels (significant height of combined wind waves and swell, peak wave period, mean wave direction, 10 m wind). Hersbach, H. et al. (2023), ERA5 hourly data on single levels from 1940 to present, doi:10.24381/cds.adbb2d47. Neither the European Commission nor ECMWF is responsible for any use of this information."
WAVERYS (Copernicus Marine Service, Mercator Ocean), free including commercial use with credit. "Generated using E.U. Copernicus Marine Service Information: WAVERYS global wave reanalysis [period], 3 hourly significant wave height, peak period and direction. Wind statistics from the ERA5 reanalysis (Copernicus C3S) on its 0.5 degree grid [span]. Neither the European Commission nor ECMWF nor Mercator Ocean is responsible for any use of this information." Product: Global Ocean Waves Reanalysis WAVERYS, doi:10.48670/moi-00022.
Hs against Tp tables. "ERA5 reanalysis (ECMWF / Copernicus C3S)", with the joint set's own period, under the ERA5 sentence above.
Currents and tides (Copernicus Marine Service). "Generated using E.U. Copernicus Marine Service Information: Global Ocean Physics Reanalysis GLORYS12 (background currents, tides excluded) and the Global Ocean hourly merged surface currents (barotropic tidal streams). Tidal statistics are harmonic estimates from six constituents (M2 S2 N2 K1 O1 M4) with nodal factors applied for the fit window; spring and neap rates are the largest and smallest daily peak of a mean-tide reconstruction (N2 excluded); slack windows average turn-bounded runs only; tidal stream statistics are the mean over the water column." The FES tide model itself is licence restricted for commercial use, which is why the tides come through the Copernicus Marine product.
ETOPO 2022 (NOAA NCEI), public domain. "Water depths: ETOPO 2022 Global Relief Model, NOAA National Centers for Environmental Information (public domain)."
Natural Earth, public domain. "Depth contours and depth bands: Natural Earth 1:10m bathymetry (public domain)." The world-view coastline, country borders and place names are Natural Earth 1:50m and 1:10m data, also public domain.
GSHHG, GNU LGPL v3. Where the zoomed-in coast tiles are the GSHHG build: Wessel, P., and W. H. F. Smith, A Global Self-consistent, Hierarchical, High-resolution Shoreline Database, J. Geophys. Res., 101, 8741-8743, 1996. GSHHG is distributed under the GNU Lesser General Public License v3 (soest.hawaii.edu/pwessel/gshhg).
IBTrACS (NOAA NCEI), public domain. "Tropical cyclone exposure: IBTrACS v04 best tracks (NOAA NCEI, public domain), tropical-storm strength and above, satellite era (1980 on). Storm counts and storm-days are long-term averages by calendar month within fixed great-circle rings of the point."
NOAA Climate Prediction Center. Oceanic Niño Index (ERSSTv5), used for the ENSO phase tagging.
OpenStreetMap, ODbL. "Platform locations: OpenStreetMap contributors (ODbL, openstreetmap.org/copyright)."
Global Energy Monitor, CC BY 4.0. "Field locations: Global Oil & Gas Extraction Tracker, Global Energy Monitor (CC BY 4.0). Positions are indicative unit centroids." "Gas pipeline routes: Global Gas Infrastructure Tracker, Global Energy Monitor (CC BY 4.0). Offshore segments only." "Oil/NGL pipeline routes: Global Oil Infrastructure Tracker, Global Energy Monitor (CC BY 4.0). Offshore segments only." "LNG terminals: Global Gas Infrastructure Tracker, Global Energy Monitor (CC BY 4.0)."
Norwegian Offshore Directorate, NLOD. "Norwegian wellbores and facilities: Norwegian Offshore Directorate FactPages (Norwegian Licence for Open Government Data)."
US BOEM / BSEE, public domain. "Gulf of Mexico structures and boreholes: US BOEM/BSEE (public domain)."
Geoscience Australia, CC BY 4.0. "Australian offshore wells and infrastructure: Geoscience Australia (CC BY 4.0)."
ANP Brazil, open data. "Brazil well and field data: ANP (Agencia Nacional do Petroleo, Gas Natural e Biocombustiveis) open data. Positions are indicative."
Standards referenced. DNVGL-RP-C205, Environmental conditions and environmental loads, edition August 2017, section 4.1 (clauses 4.1.3.3 and 4.1.4.1 to 4.1.4.8 as described in 4.7). DNV-ST-N001 11.12.2.3 is cited for the 20 m/s figure from Thrust Maritime's own calculation practice and is not checked against the text.
Software. The PDF summary is built in the browser with pdf-lib (MIT licence), vendored unmodified. The site itself is static files: no tile servers, no tracking, no backend.
tools/stamp_build.py: it is written into the page as window.TM_BUILD and appended as ?v= to every script, stylesheet and data request, so a cited page can be tied to the exact code and data it served. View the explorer's page source to read it.tools/verify_dataset.py writes the engineering sign-off report for a build: ledger reconciled, deployed tiles bit-identical to a fresh re-emit, sampled cells recomputed independently, invariants passed over every tile.