Compare commits

..
Author SHA1 Message Date
kamilkrzywda d7f352adcf Merge pull request 'v0.60.0 — Fiord default map style (#118)' (#136) from feat/fiord-default-style into master
CI / build + unit + e2e (push) Successful in 13m51s
2026-09-23 10:58:14 +02:00
kamilkrzywda 2b5c8541d7 v0.63.0: retune map overlay colors for the Fiord default (ISS-118) — brighten airport dot fill rose-600→rose-500 and hovered-route highlight red-500→red-400, the two elements below 3:1 on Fiord's dark slate/navy palette; all other overlay colors audited ≥3.3:1 and left untouched
CI / build + unit + e2e (pull_request) Successful in 13m55s
2026-09-23 08:43:41 +00:00
kamilkrzywda 673365f49c Merge pull request 'v0.62.0 — Fixed 24x world clock (#135)' (#138) from feat/fixed-world-clock into master
CI / build + unit + e2e (push) Successful in 17m9s
2026-09-23 10:24:07 +02:00
kamilkrzywda bb4e3b96f3 v0.62.0: fixed 24x world clock — frozen when fully grounded (#135)
CI / build + unit + e2e (pull_request) Successful in 14m3s
2026-09-23 08:09:29 +00:00
kamilkrzywda e970f95036 Merge pull request 'v0.61.0 — Special remote airports (#97)' (#137) from feat/special-airports into master
CI / build + unit + e2e (push) Successful in 16m38s
2026-09-23 09:42:12 +02:00
kamilkrzywda 03731b938e Special remote airports + isRemote curation (ISS-097, v0.61.0)
CI / build + unit + e2e (pull_request) Successful in 15m31s
2026-09-23 07:14:35 +00:00
kamilkrzywda 1d9e9ade58 Merge pull request 'v0.59.0 — SSE frames drop terminal package history (#133)' (#134) from feat/sse-payload into master
CI / build + unit + e2e (push) Successful in 14m9s
2026-09-23 08:06:44 +02:00
kamilkrzywda 6a819b8d5a v0.59.0: SSE frames drop terminal package history (sseFrame projection) — ~597 KB → ~10 KB per frame (#133)
CI / build + unit + e2e (pull_request) Successful in 17m7s
2026-09-23 05:49:17 +00:00
kamilkrzywda c5413aff65 Merge pull request 'v0.58.0 — plane markers no longer teleport across the antimeridian (#124)' (#132) from feat/antimeridian-markers into master
CI / build + unit + e2e (push) Successful in 16m47s
2026-09-23 07:32:39 +02:00
22 changed files with 743 additions and 159 deletions
+16
View File
@@ -1,5 +1,21 @@
# Changelog # Changelog
## v0.63.0 — 2026-09-23 08:43
- **Overlay colors retuned for the Fiord default (ISS-118).** The first half of this issue landed in v0.4.0 (`DEFAULT_STYLE_ID = 'fiord'` + top-bar switcher, e2e already pins `toHaveValue('fiord')`); this completes the second half — auditing every color drawn on the map against Fiord's actual palette. Key finding: OpenFreeMap's Fiord is a DARK cool-toned basemap (land #45516E slate, water #38435C navy — verified byte-identical between the self-hosted `public/styles/fiord.json` and `tiles.openfreemap.org/styles/fiord`), not a light one. WCAG contrast audit of all nine overlay colors against both base surfaces: seven already read fine (≥ 3.3:1 on land AND water) and are untouched — amber flying leg #f59e0b, gold dotted queue line #d4a017 (ISS-098 picked it for light+dark), sky-blue grounded plane + hover halo #38bdf8, green flying plane #22c55e, yellow hover ring/trace #facc15, green target ring #4ade80. Two were weak and got brightened one step within the same hue family: airport dot fill rose-600 #e11d48 (1.68:1 on slate land — the weakest element on the map) → rose-500 #f43f5e (2.15:1), and the hovered-route highlight red-500 #ef4444 (2.10:1, below the 3:1 graphical-object bar for an emphasis layer) → red-400 #f87171 (2.86:1 on land / 3.57:1 on water). White strokes and all other paint values unchanged; no new constants — both colors are single-use inline paint values, matching the existing style of this file.
- **Tests.** No test changes needed: `components/map.test.ts` pins only #d4a017 (untouched), e2e specs query rendered features by id/layer rather than color, and `lib/mapStyles.test.ts` already pins `DEFAULT_STYLE_ID = 'fiord'`.
## v0.62.0 — 2026-09-23 07:36
- **Fixed 24x world clock (#135).** Finalized the closed issue #117 spec: the world clock runs at the fixed `WORLD_TIME_SCALE = 24` while any plane is flying or in repair, and stays FROZEN when the whole fleet is grounded — replacing v0.56.0's idle slowdown (`IDLE_WORLD_TIME_SCALE = WORLD_TIME_SCALE / 24`, ISS-128). **Production rate is now exactly 24x regardless of legacy stored values:** `tickOnce` in `lib/sim/engine.ts` computes `advanceMs = advance ? min(elapsed, MAX_TICK_ELAPSED_MS) × scale : 0` where `scale = FLIGHT_TEST_HOOKS === '1' ? sim.timeScale : WORLD_TIME_SCALE` — pre-v0.52.0 saves hold `timeScale: 1000` (the old UI ladder), which is why the live instance still ran at ×1000; only deployments with the env var set honor the stored override written by `POST /api/test/set-timescale` (range [1, 100_000], kept for tests). A frozen tick skips expiry/delivery/repair/spawn entirely and only updates `lastRealTickMs`, so resuming activity never fast-forwards the frozen span. The client mirror (`advanceSimClock` in `lib/useSimClock.ts`) holds its anchor value while grounded, so polls re-anchor without any jump. Removed: `IDLE_WORLD_TIME_SCALE` from `lib/worldClock.ts`, and — **separate finding** — `FLIGHT_TEST_HOOKS: "1"` from the production `docker-compose.yml`: it enabled the `/api/test/*` hooks in prod AND (pre-gate) made the live instance honor its stale stored 1000; e2e runs only in CI against `docker-compose.ci.yml`, which sets the var itself. Unchanged on purpose: the ~1 s background tick (started at boot), the test hook endpoint, and the inert legacy columns `paused`/`lastSelectedTimeScale` (nothing reads them; no migration — per #117 saves reset when multiplayer ships). The OpenAPI description of `/api/state` ("while no plane is flying or in repair the clock stays frozen") now matches the code.
- **Tests.** Unit: `lib/sim/engine.test.ts` — both rate branches pinned: with `FLIGHT_TEST_HOOKS=1` stubbed (the file's default, like CI) stored overrides are honored; a new production test unsets the var and proves a legacy stored `timeScale: 1000` still advances at exactly ×24. Grounded-fleet tests pin a FROZEN clock (no idle creep, resume-without-catch-up after takeoff, raised timeScale ignored while grounded); describe renamed to "grounded fleet freezes the world clock (#135)" and pins `WORLD_TIME_SCALE = 24`. `lib/useSimClock.test.ts` — the grounded case asserts staying exactly at the anchor value. E2E: `e2e/sim.spec.ts`'s idle test becomes an exact freeze (delta === 0 after ~2.5 s of idleness); `e2e/state.spec.ts`'s restart test tightens from bounded delta to EXACT clock equality across `docker compose restart`; `e2e/right-pane.spec.ts` verifies the frozen clock, then asserts the abandon-penalty preview matches the server exactly (zero drift under a frozen clock — replaces the DRIFT_MS slope tolerance); `e2e/events.spec.ts` relaxes strict clock advance between SSE frames to non-decreasing (a grounded fleet pushes identical-clockMs frames; advance itself is pinned in sim.spec.ts). The activateWorld/deactivateWorld wrappers are unchanged — a repairing plane still means full scale.
## v0.61.0 — 2026-09-23 07:12
- **Special remote airports (ISS-097).** The world dataset was curated to `large_airport` only, so genuinely empty regions — Antarctica, the high Arctic, Alaska, northern Canada and far islands — had no markers at all. New pure function `isRemote(airports, icao)` in `lib/airports.ts` (reusing the existing `haversineKm` from `lib/geo.ts`): an airport is remote when no other member of the given list lies within `REMOTE_RADIUS_KM = 1000`. The curation in `scripts/build-world-airports.mjs` now runs over ALL fixed-wing rows: every large_airport (unchanged clustering) plus every non-large row that is remote against the kept set; same-station twins (two strips <40 km apart at one base) collapse via the same greedy 40 km clustering. `data/airports_world.csv` grows from 1119 → **1483 rows** (+364 remote airports), including Rothera (EGAR), Halley (EGAH) and Showa skiway (AT25) in Antarctica; Grise Fiord (CYGZ), Alert (CYLT), Ny-Ålesund (ENAS — Svalbard's only marker within 1000 km of a large airport) and Wrangel Island (UHMZ) in the Arctic; Bethel (PABR) and other Alaska strips; Canadian-Arctic smalls; and far islands such as Easter (SCIP), Canton (PCIS), Henderson/Pago Pago (PMDY) and Ascension (FHAW). The only change to a pre-existing row is an upstream `home_link` refresh on CYLW. New airports become contract origins/destinations and map markers unchanged — the most isolated airport in the new set (Easter Island) has its nearest neighbour 2599 km away, well under the 9000 km job cap, so every origin stays flyable; `filterWorldAirports` already accepts small/medium/seaplane types, so no runtime change was needed.
- **Tests.** Unit +4 in `lib/airports.test.ts`: a synthetic radius boundary (equator pair at ~945 km vs ~1052 km), real coordinates (Frankfurt↔Amsterdam is not remote; McMurdo vs Christchurch is), an unknown ICAO returning false, and the committed-dataset curation invariant — every non-large row has no large airport within 1000 km and at least one non-large row exists.
## v0.59.0 — 2026-09-23 05:48
- **SSE frames no longer carry package history (ISS-133).** Measured on the live instance first: each `/api/events` frame was compact JSON at ~597 KB, pushed once per real second regardless of time scale (the background tick is a fixed 1 s interval; ×1000 just advances the clock further per frame) — and 99.8 % of it was `packages`: 1,521 rows because terminal packages are never deleted from the DB (expired 564, delivered 528, ignored 386, abandoned 31), while only 12 were `open`. No component ever reads a package with a terminal status — the market list renders `open`, and on-board cargo is `loaded`/`expired` (`LeftPane`, `cargoWeightFor`) — so the history was pure re-sent weight. New `sseFrame(snapshot)` in `lib/game/state.ts` projects a snapshot down to the client-rendered statuses (`SSE_PACKAGE_STATUSES = open|loaded|expired`); both SSE paths use it — the broadcast in `lib/sim/engine.ts` and the initial frame in `app/api/events/route.ts`, so a connect never costs one full-history frame. Live payload drops ~597 KB → ~10 KB per frame (≈ 60×), bounded forever by fleet/market size instead of growing with play time. `/api/state` and action responses keep the FULL package set unchanged, so every e2e oracle that asserts `delivered`/`abandoned` transitions via state lookups still works; the polling fallback stays a strict superset of what SSE pushes. Deliberately NOT done: hash-skip broadcasts (the snapshot's `clockMs` advances on every tick even while idle — `advanceMs = min(elapsed, 2000 ms) × scale ≥ 1 s` — so no two frames are ever equal), throttling (already exactly 1 Hz), and a diff/patch engine.
- **Tests.** Unit +3 in new `lib/game/state.test.ts`: the projection keeps exactly open/loaded/expired (order preserved, terminal rows dropped), passes account/simState/planes through untouched without mutating its input, and pins the status set itself. E2E: `e2e/events.spec.ts` now records every package status seen in any frame plus the largest frame — asserts no terminal status ever appears and frames stay under 200 KB (a full-history regression at ~597 KB fails loudly).
## v0.58.0 — 2026-09-22 21:27 ## v0.58.0 — 2026-09-22 21:27
- **Plane markers no longer teleport across the antimeridian (ISS-124).** The follow-up to ISS-120's known limitation: a plane mid-crossing still used the snapshot's wrapped lat/lon (`positionAt` wraps every longitude into [−180, 180]), so its marker jumped +179.x → −179.x between polls — a visible 360° teleport on the map while its route line stayed continuous. `planesGeoJson` in `lib/mapData.ts` now takes the airport index (`airportsByIcao`, same parameter shape as `routesGeoJson`) and re-expresses each FLYING plane's longitude against its departure airport — the same anchor `greatCircleArc` keeps for its first sample — via a new module-private `unwrapLon(lon, prev)` (the ±360 shift until |Δlon| ≤ 180 that `unwrapLons`'s loop body already used; `unwrapLons` now calls it). The unwrap applies only when BOTH leg endpoints exist in the index, mirroring `routesGeoJson`'s guard exactly: a marker is unwrapped if and only if its line is drawn. Grounded planes, repairing planes and flying planes with a missing endpoint keep their raw wrapped position (unchanged behavior); non-crossing legs are byte-identical (no |Δlon| > 180 → the shift never fires). `components/Map.tsx` passes `airportsIndexRef.current ?? new Map()` at both call sites (`applyDynamic` and the source bootstrap in `ensureLayers`) — planes draw immediately at their wrapped position until the airport index loads, then unwrap. - **Plane markers no longer teleport across the antimeridian (ISS-124).** The follow-up to ISS-120's known limitation: a plane mid-crossing still used the snapshot's wrapped lat/lon (`positionAt` wraps every longitude into [−180, 180]), so its marker jumped +179.x → −179.x between polls — a visible 360° teleport on the map while its route line stayed continuous. `planesGeoJson` in `lib/mapData.ts` now takes the airport index (`airportsByIcao`, same parameter shape as `routesGeoJson`) and re-expresses each FLYING plane's longitude against its departure airport — the same anchor `greatCircleArc` keeps for its first sample — via a new module-private `unwrapLon(lon, prev)` (the ±360 shift until |Δlon| ≤ 180 that `unwrapLons`'s loop body already used; `unwrapLons` now calls it). The unwrap applies only when BOTH leg endpoints exist in the index, mirroring `routesGeoJson`'s guard exactly: a marker is unwrapped if and only if its line is drawn. Grounded planes, repairing planes and flying planes with a missing endpoint keep their raw wrapped position (unchanged behavior); non-crossing legs are byte-identical (no |Δlon| > 180 → the shift never fires). `components/Map.tsx` passes `airportsIndexRef.current ?? new Map()` at both call sites (`applyDynamic` and the source bootstrap in `ensureLayers`) — planes draw immediately at their wrapped position until the airport index loads, then unwrap.
- **Tests.** Unit +6 in `lib/mapData.test.ts` (new "antimeridian marker unwrap" block on the real NZAA/NFTF pair): eastward crossing unwraps a mid-leg −179.5 to +180.5 against the origin's +174.8, westward (reversed pair) unwraps below −180, and — the key invariant — every sample of `greatCircleArc(NZAA→NFTF)` fed back as a WRAPPED snapshot position comes out exactly on that arc's own sample, so marker and line agree frame to frame; grounded planes keep their raw coordinate, a flying plane with a missing endpoint stays wrapped (no line drawn either), and non-crossing legs are untouched. E2E +1 in `e2e/map-interactions.spec.ts`: the starter is relocated to Auckland via a fewest-legs chain over `/api/airports` (each hop ≤ 3400 km — within the ATR72's guaranteed range even in worst-case headwind; the tank is topped for free with the `set-fuel` hook before every dispatch so auto-refuel costs nothing), then a hook-created NZAA → NFTF package is loaded and flown at scale 1000 while the marker's longitude is sampled from the planes source every ~500 ms (real time) until the server reports landing — no two consecutive samples may differ by ≥ 180° (the teleport), some sample must sit on the east world copy (lon > 180, proving the crossing was actually traversed unwrapped rather than skipped), and the sampled span must exceed 4°. The plane chains back home afterwards so the other specs start from the canonical state. - **Tests.** Unit +6 in `lib/mapData.test.ts` (new "antimeridian marker unwrap" block on the real NZAA/NFTF pair): eastward crossing unwraps a mid-leg −179.5 to +180.5 against the origin's +174.8, westward (reversed pair) unwraps below −180, and — the key invariant — every sample of `greatCircleArc(NZAA→NFTF)` fed back as a WRAPPED snapshot position comes out exactly on that arc's own sample, so marker and line agree frame to frame; grounded planes keep their raw coordinate, a flying plane with a missing endpoint stays wrapped (no line drawn either), and non-crossing legs are untouched. E2E +1 in `e2e/map-interactions.spec.ts`: the starter is relocated to Auckland via a fewest-legs chain over `/api/airports` (each hop ≤ 3400 km — within the ATR72's guaranteed range even in worst-case headwind; the tank is topped for free with the `set-fuel` hook before every dispatch so auto-refuel costs nothing), then a hook-created NZAA → NFTF package is loaded and flown at scale 1000 while the marker's longitude is sampled from the planes source every ~500 ms (real time) until the server reports landing — no two consecutive samples may differ by ≥ 180° (the teleport), some sample must sit on the east world copy (lon > 180, proving the crossing was actually traversed unwrapped rather than skipped), and the sampled span must exceed 4°. The plane chains back home afterwards so the other specs start from the canonical state.
+7 -5
View File
@@ -1,9 +1,11 @@
import { getStateSnapshot } from '@/lib/game/state'; import { getStateSnapshot, sseFrame } from '@/lib/game/state';
import { subscribe } from '@/lib/sse'; import { subscribe } from '@/lib/sse';
// ISS-129 (v0.57.0): Server-Sent Events feed of full state snapshots — the current snapshot on // ISS-129 (v0.57.0): Server-Sent Events feed of state snapshots — the current snapshot on connect,
// connect, then one after every sim tick (broadcast from lib/sim/engine.ts). One-way push; player // then one after every sim tick (broadcast from lib/sim/engine.ts). One-way push; player actions
// actions stay REST POSTs. Heartbeats keep idle proxies from dropping the connection. // stay REST POSTs. Heartbeats keep idle proxies from dropping the connection. ISS-133 (v0.59.0):
// frames carry the sseFrame projection (terminal package history dropped) — same shape as the
// pushed frames, so a connect never costs one full-history frame.
const encoder = new TextEncoder(); const encoder = new TextEncoder();
const HEARTBEAT_MS = 15_000; const HEARTBEAT_MS = 15_000;
@@ -39,7 +41,7 @@ export async function GET() {
// same as above // same as above
} }
}, HEARTBEAT_MS); }, HEARTBEAT_MS);
controller.enqueue(encoder.encode(`data: ${JSON.stringify(snapshot)}\n\n`)); controller.enqueue(encoder.encode(`data: ${JSON.stringify(sseFrame(snapshot))}\n\n`));
}) })
.catch(() => { .catch(() => {
cleanup(); cleanup();
+2 -2
View File
@@ -360,7 +360,7 @@ export default function FlightMap({ state, hovered, applySnapshot }: MapProps) {
source: AIRPORTS_SOURCE_ID, source: AIRPORTS_SOURCE_ID,
paint: { paint: {
'circle-radius': 5, // ISS-010 (v0.18.0): bigger — the r=3 dots were hard to click 'circle-radius': 5, // ISS-010 (v0.18.0): bigger — the r=3 dots were hard to click
'circle-color': '#e11d48', 'circle-color': '#f43f5e', // ISS-118 (v0.60.0): rose-500 — old #e11d48 (rose-600) was tuned for light tiles; 1.7:1 on Fiord's dark slate land
'circle-stroke-width': 1.5, 'circle-stroke-width': 1.5,
'circle-stroke-color': '#ffffff', 'circle-stroke-color': '#ffffff',
}, },
@@ -462,7 +462,7 @@ export default function FlightMap({ state, hovered, applySnapshot }: MapProps) {
source: ROUTES_SOURCE_ID, source: ROUTES_SOURCE_ID,
filter: ['==', ['get', 'planeId'], ''], filter: ['==', ['get', 'planeId'], ''],
paint: { paint: {
'line-color': '#ef4444', // red — distinct from the amber routes-legs line 'line-color': '#f87171', // ISS-118 (v0.60.0): red-400 — old #ef4444 sat at 2.1:1 on Fiord's dark slate; brighter so the hover emphasis reads, still distinct from the amber routes-legs line
'line-width': 6, 'line-width': 6,
}, },
}); });
+365 -1
View File
@@ -11,7 +11,7 @@
"610368","CA-1292","large_airport","YEG","50.341652","-106.699219","2373","NA","CA","CA-AB","Edmonton","yes","","","","","","","" "610368","CA-1292","large_airport","YEG","50.341652","-106.699219","2373","NA","CA","CA-AB","Edmonton","yes","","","","","","",""
"1763","CYHM","large_airport","John C. Munro Hamilton International Airport","43.171308","-79.929416","780","NA","CA","CA-ON","Hamilton","yes","CYHM","YHM","CYHM","","https://www.flyhi.ca/","https://en.wikipedia.org/wiki/Hamilton/John_C._Munro_International_Airport","Mount Hope Airport" "1763","CYHM","large_airport","John C. Munro Hamilton International Airport","43.171308","-79.929416","780","NA","CA","CA-ON","Hamilton","yes","CYHM","YHM","CYHM","","https://www.flyhi.ca/","https://en.wikipedia.org/wiki/Hamilton/John_C._Munro_International_Airport","Mount Hope Airport"
"1770","CYHZ","large_airport","Halifax / Stanfield International Airport","44.8807983398","-63.5085983276","477","NA","CA","CA-NS","Halifax","yes","CYHZ","YHZ","CYHZ","","http://www.hiaa.ca/","https://en.wikipedia.org/wiki/Halifax_International_Airport","Robert L. Stanfield International Airport" "1770","CYHZ","large_airport","Halifax / Stanfield International Airport","44.8807983398","-63.5085983276","477","NA","CA","CA-NS","Halifax","yes","CYHZ","YHZ","CYHZ","","http://www.hiaa.ca/","https://en.wikipedia.org/wiki/Halifax_International_Airport","Robert L. Stanfield International Airport"
"1808","CYLW","large_airport","Kelowna International Airport","49.9561","-119.377998","1421","NA","CA","CA-BC","Kelowna","yes","CYLW","YLW","CYLW","","http://www.kelowna.ca/CM/Page68.aspx","https://en.wikipedia.org/wiki/Kelowna_International_Airport","Kelowna, Okanagan" "1808","CYLW","large_airport","Kelowna International Airport","49.9561","-119.377998","1421","NA","CA","CA-BC","Kelowna","yes","CYLW","YLW","CYLW","","https://ylw.kelowna.ca/","https://en.wikipedia.org/wiki/Kelowna_International_Airport","Kelowna, Okanagan"
"1840","CYOW","large_airport","Ottawa Macdonald-Cartier International Airport","45.322498","-75.669197","374","NA","CA","CA-ON","Ottawa","yes","CYOW","YOW","CYOW","YOW","https://yow.ca/","https://en.wikipedia.org/wiki/Ottawa_Macdonald%E2%80%93Cartier_International_Airport","Uplands, UUP, CUUP" "1840","CYOW","large_airport","Ottawa Macdonald-Cartier International Airport","45.322498","-75.669197","374","NA","CA","CA-ON","Ottawa","yes","CYOW","YOW","CYOW","YOW","https://yow.ca/","https://en.wikipedia.org/wiki/Ottawa_Macdonald%E2%80%93Cartier_International_Airport","Uplands, UUP, CUUP"
"1864","CYQB","large_airport","Quebec Jean Lesage International Airport","46.7911","-71.393303","244","NA","CA","CA-QC","Quebec","yes","CYQB","YQB","CYQB","YQB","http://www.aeroportdequebec.com/","https://en.wikipedia.org/wiki/Qu%C3%A9bec/Jean_Lesage_International_Airport","Quebec City" "1864","CYQB","large_airport","Quebec Jean Lesage International Airport","46.7911","-71.393303","244","NA","CA","CA-QC","Quebec","yes","CYQB","YQB","CYQB","YQB","http://www.aeroportdequebec.com/","https://en.wikipedia.org/wiki/Qu%C3%A9bec/Jean_Lesage_International_Airport","Quebec City"
"1867","CYQG","large_airport","Windsor International Airport","42.2756","-82.955597","622","NA","CA","CA-ON","Windsor","yes","CYQG","YQG","CYQG","","https://flyyqg.ca/","https://en.wikipedia.org/wiki/Windsor_Airport","" "1867","CYQG","large_airport","Windsor International Airport","42.2756","-82.955597","622","NA","CA","CA-ON","Windsor","yes","CYQG","YQG","CYQG","","https://flyyqg.ca/","https://en.wikipedia.org/wiki/Windsor_Airport",""
@@ -1118,3 +1118,367 @@
"27241","ZYQQ","large_airport","Qiqihar Sanjiazi Airport","47.229969","123.914179","477","AS","CN","CN-23","Qiqihar","yes","ZYQQ","NDG","ZYQQ","","","https://en.wikipedia.org/wiki/Qiqihar_Airport","齐齐哈尔, 齐齐哈尔三家子机场" "27241","ZYQQ","large_airport","Qiqihar Sanjiazi Airport","47.229969","123.914179","477","AS","CN","CN-23","Qiqihar","yes","ZYQQ","NDG","ZYQQ","","","https://en.wikipedia.org/wiki/Qiqihar_Airport","齐齐哈尔, 齐齐哈尔三家子机场"
"27242","ZYTL","large_airport","Dalian Zhoushuizi International Airport","38.965719","121.538477","107","AS","CN","CN-21","Dalian (Ganjingzi)","yes","ZYTL","DLC","ZYTL","","https://dlairport.com","https://en.wikipedia.org/wiki/Dalian_Zhoushuizi_International_Airport","Dalian Air Base" "27242","ZYTL","large_airport","Dalian Zhoushuizi International Airport","38.965719","121.538477","107","AS","CN","CN-21","Dalian (Ganjingzi)","yes","ZYTL","DLC","ZYTL","","https://dlairport.com","https://en.wikipedia.org/wiki/Dalian_Zhoushuizi_International_Airport","Dalian Air Base"
"27243","ZYTX","large_airport","Shenyang Taoxian International Airport","41.6398","123.483668","198","AS","CN","CN-21","Shenyang","yes","ZYTX","SHE","ZYTX","","","https://en.wikipedia.org/wiki/Shenyang_Taoxian_International_Airport","沈阳, 沈阳桃仙国际机场" "27243","ZYTX","large_airport","Shenyang Taoxian International Airport","41.6398","123.483668","198","AS","CN","CN-21","Shenyang","yes","ZYTX","SHE","ZYTX","","","https://en.wikipedia.org/wiki/Shenyang_Taoxian_International_Airport","沈阳, 沈阳桃仙国际机场"
"16155","AK62","seaplane_base","Naukati Bay Seaplane Base","55.849602","-133.227994","","NA","US","US-AK","Tuxekan Island","yes","","NKI","AK62","AK62","","https://en.wikipedia.org/wiki/Naukati_Bay_Seaplane_Base","62A, Nichin Cove Seaplane Base, WNC"
"8159","19P","seaplane_base","Port Protection Seaplane Base","56.3288","-133.610001","","NA","US","US-AK","Port Protection","yes","","PPV","19P","19P","","https://en.wikipedia.org/wiki/Port_Protection_Seaplane_Base","AK19"
"9296","2AK8","small_airport","Icy Cape Air Force Station Airport","70.293545","-161.907151","48","NA","US","US-AK","Icy Cape","no","","","2AK8","2AK8","","",""
"9902","2Z1","seaplane_base","Entrance Island Seaplane Base","57.412201","-133.43848","0","NA","US","US-AK","Entrance Island","no","","HBH","","","","","2Z1"
"5398","PAPG","medium_airport","Petersburg James A Johnson Airport","56.80170059","-132.9450073","111","NA","US","US-AK","Petersburg","yes","PAPG","PSG","PAPG","PSG","","https://en.wikipedia.org/wiki/Petersburg_James_A._Johnson_Airport",""
"5421","PAWG","medium_airport","Wrangell Airport","56.48429871","-132.3699951","49","NA","US","US-AK","Wrangell","yes","PAWG","WRG","PAWG","WRG","","https://en.wikipedia.org/wiki/Wrangell_Airport",""
"19240","KAE","seaplane_base","Kake Seaplane Base","56.973","-133.945999","","NA","US","US-AK","Kake","yes","","KAE","","KAE","","https://en.wikipedia.org/wiki/Kake_Seaplane_Base",""
"14860","PABU","small_airport","Bullen Point Short Range Radar Station Airport","70.170999","-146.844897","18","NA","US","US-AK","Kaktovik","no","","","PABU","8AK7","","https://en.wikipedia.org/wiki/Bullen_Point_Short_Range_Radar_Site",""
"307366","EGAR","small_airport","Rothera Research Station","-67.5675","-68.127403","9","AN","AQ","AQ-U-A","Rothera Research Station","no","EGAR","","EGAR","","http://www.antarctica.ac.uk/living_and_working/research_stations/rothera/","https://en.wikipedia.org/wiki/Rothera_Research_Station",""
"5405","PASC","medium_airport","Deadhorse Airport","70.19470215","-148.4649963","65","NA","US","US-AK","Deadhorse","yes","PASC","SCC","PASC","SCC","","https://en.wikipedia.org/wiki/Deadhorse_Airport",""
"5401","PAQT","medium_airport","Nuiqsut Airport","70.209999","-151.005998","38","NA","US","US-AK","Nuiqsut","yes","PAQT","NUI","PAQT","AQT","","https://en.wikipedia.org/wiki/Nuiqsut_Airport","10AK"
"312361","ANZ","small_airport","Angus Downs Airport","-25.0325","132.2748","1724","OC","AU","AU-NT","Angus Downs Station","no","","ANZ","YADN","","","",""
"39579","AQ-0001","small_airport","Novolazarevskaya Station","-70.8461","11.8472","390","AN","AQ","AQ-U-A","Queen Maud Land","no","","","AT17","","","https://en.wikipedia.org/wiki/Novolazarevskaya_Station",""
"42221","AQ-0002","small_airport","Troll Airfield","-71.95714","2.45257","4167","AN","AQ","AQ-U-A","Troll Station","no","","","ENOE","AT27","","https://en.wikipedia.org/wiki/Troll_airfield",""
"336951","AQBC","medium_airport","Boulder Clay Runway","-74.739373","164.03539","672","AN","AQ","AQ-U-A","Zucchelli Station","no","","","AQBC","","","https://en.wikipedia.org/wiki/Zucchelli_Station",""
"345862","AQ-0011","small_airport","Wolfs Fang Runway","-71.545026","8.798389","3707","AN","AQ","AQ-U-A","","no","","","","","https://white-desert.com/about-us/wolfsfang-runway-logistics/","https://en.wikipedia.org/wiki/Wolfs_Fang_Runway","AT98, Henrickson Nunatak, Queen Maud Land"
"5054","NZSP","medium_airport","Amundsen–Scott South Pole Station Airport","-90","-1","9300","AN","AQ","AQ-U-A","Amundsen-Scott South Pole Station","no","NZSP","","NZSP","","","https://en.wikipedia.org/wiki/Amundsen-Scott_South_Pole_Station",""
"603000","AQ-0016","medium_airport","Grandfather Skiway","-77.530242","-31.827393","","AN","AQ","AQ-U-A","Antartica","no","","","","","","",""
"336953","AT03","medium_airport","Concordia Skyway","-75.103278","123.35825","10725","AN","AQ","AQ-U-A","Concordia Station","no","","","AT03","","","https://en.wikipedia.org/wiki/Concordia_Station",""
"330063","AT25","small_airport","Showa Station Skiway","-69.006167","39.59","95","AN","AQ","AQ-U-A","Showa Station","no","","","AT25","","","https://en.wikipedia.org/wiki/Showa_Station_(Antarctica)","Syowa Station"
"336959","AT28","medium_airport","Vostok Skiway","-78.466139","106.84825","11447","AN","AQ","AQ-U-A","Vostok Station","no","","","AT28","","","https://en.wikipedia.org/wiki/Vostok_Station",""
"333856","AU-0112","small_airport","Aileron Airstrip","-22.652908","133.347244","2186","OC","AU","AU-NT","Anmatjere","no","","","YALR","","","",""
"351706","AU-0272","small_airport","Planet Downs OS","-25.872662","141.116788","","OC","AU","AU-QLD","Planet downs OS","no","","","","","","",""
"352795","AU-0345","small_airport","Hamilton Downs Airstrip","-23.507335","133.260577","","OC","AU","AU-NT","Burt Plain","no","","","","","","",""
"27846","YNPB","small_airport","Napperby Airport","-22.5312","132.7632","2135","OC","AU","AU-NT","Napperby","no","","NPP","YNPB","","","",""
"27793","YMNY","small_airport","Morney Airport","-25.358299255371094","141.43299865722656","104","OC","AU","AU-QLD","","no","YMNY","OXY","YMNY","","","",""
"507903","AU-0571","small_airport","Lake MacKay Airstrip","-23.670782","129.976158","","OC","AU","AU-NT","Lake MacKay","no","","","","","","",""
"508151","AU-0586","small_airport","homestead","-23.317075","138.587637","","OC","AU","AU-NT","Sturt QLD 4829","no","","","","","","",""
"38379","YHBY","small_airport","Henbury Airport","-24.584","133.236","","OC","AU","AU-NT","Ghan","no","YHBY","HRY","YHBY","","","",""
"31745","AU-KGR","small_airport","Kulgera Airport","-25.8428","133.292007","","OC","AU","AU-NT","Ghan","no","","KGR","","","","",""
"44051","BGDH","small_airport","Danmarkshavn Landing Strip","76.76667","-18.666668","","NA","GL","GL-NE","Danmarkshavn","no","","","BGDH","","","",""
"299843","BGMI","small_airport","Station Nord Landing Strip","81.601292","-16.679306","35","NA","GL","GL-NE","Station Nord","no","","","BGMI","","","https://en.wikipedia.org/wiki/Nord,_Greenland",""
"32004","BGQQ","medium_airport","Qaanaaq Airport","77.488602","-69.388702","51","NA","GL","GL-AV","Qaanaaq","yes","BGQQ","NAQ","BGQQ","","","https://en.wikipedia.org/wiki/Qaanaaq_Airport","Mittarfik Qaanaaq, Thule"
"116","BGTL","medium_airport","Pituffik Space Base","76.53063","-68.700541","251","NA","GL","GL-AV","Pituffik","no","BGTL","THU","BGTL","","","https://en.wikipedia.org/wiki/Pituffik_Space_Base","Thule Air Base"
"874","CEM3","small_airport","Whatì Airport","63.131699","-117.246002","882","NA","CA","CA-NT","Whatì","yes","","YLE","CEM3","CEM3","","https://en.wikipedia.org/wiki/What%C3%AC_Airport","EM3, Lac la Martre, Wha Ti"
"299911","CA-0504","small_airport","Mary River Aerodrome","71.324167","-79.356944","584","NA","CA","CA-NU","Mary River","no","","YMV","","CMR2","","https://en.wikipedia.org/wiki/Mary_River_Aerodrome",""
"316098","CA-0551","seaplane_base","Cameron Bay Water Aerodrome","66.06","-117.89","512","NA","CA","CA-NT","Cameron Bay","no","","","","EA7","","",""
"316114","CA-0554","seaplane_base","Clarence Lagoon Water Aerodrome","69.62","-140.81","0","NA","CA","CA-YT","","no","","","","EC7","","",""
"316197","CA-0556","seaplane_base","Boffa Lake Water Aerodrome","69.637","-116.196","338","NA","CA","CA-NU","","no","","","","EX6","","",""
"342506","CA-0737","small_airport","Seal River Airstrip","59.154598","-94.785554","20","NA","CA","CA-MB","Churchill","no","","","","","","",""
"342507","CA-0738","small_airport","Nester One Airstrip","58.6529","-93.19061","26","NA","CA","CA-MB","Churchill","no","","","","","","",""
"723","CBU2","small_airport","Eddontenajon / Iskut Village Airport","57.847994155","-129.983968735","3100","NA","CA","CA-BC","Eddontenajon","no","","","CBU2","CBU2","","https://en.wikipedia.org/wiki/Eddontenajon/Iskut_Village_Airport","BU2"
"349351","CA-0771","small_airport","Arctic Watch Lodge Airport","74.065757","-93.785965","","NA","CA","CA-NU","Somerset Island","no","","","CRW4","RW4","","https://en.wikipedia.org/wiki/Arctic_Watch_Lodge_Aerodrome",""
"430490","CA-0815","small_airport","Nuskenford Airstrip","69.863861","-126.843167","","NA","CA","CA-NT","Nuskenford","no","","","","","","",""
"524817","CA-0924","seaplane_base","Herschel Island Water Aerodrome","69.572","-138.93","0","NA","CA","CA-YT","Herschel","no","","","","EG8","","",""
"595702","CA-1179","small_airport","Cassiar Aerodrome","59.277137","-129.805044","3618","NA","CA","CA-BC","Cassiar","no","","","","AU9","","",""
"606385","CA-1249","small_airport","Fort Conger Airstrip","81.754925","-64.824958","15","NA","CA","CA-NU","Qikiqtaaluk Region","no","","","","CA1249","","","FCON"
"606387","CA-1250","small_airport","Lake Hazen Airstrip","81.823025","-71.360321","10","NA","CA","CA-NU","Qikiqtaaluk Region","no","","","","CA1250","","","LHAZ"
"606493","CA-1251","small_airport","McGill Arctic Research Station (MARS)","79.41596","-90.761018","","NA","CA","CA-NU","Axel Heiberg Island","no","","","","","","",""
"607046","CA-1252","small_airport","Ward Hunt Island Airport","83.091029","-74.138317","","NA","CA","CA-NU","Qikiqtaaluk Region","no","","","","CA1252","","https://en.wikipedia.org/wiki/Ward_Hunt_Island",""
"609524","CA-1259","small_airport","Bathurst Inlet Airport","66.836865","-108.011278","36","NA","CA","CA-NU","Bathurst Inlet/Qingaut","no","","","","","","","ᕿᙵᐅᓐ"
"28437","CAH9","seaplane_base","Telegraph Creek Seaplane Base","57.9071","-131.18946","1129","NA","CA","CA-BC","Telegraph Creek","no","","","CAH9","CAH9","","https://en.wikipedia.org/wiki/Telegraph_Creek_Water_Aerodrome","AH9"
"665","CBC2","small_airport","Ford Bay Airport","66.0374984741211","-124.71499633789062","673","NA","CA","CA-NT","Ford Bay","no","","","CBC2","CBC2","","https://en.wikipedia.org/wiki/Ford_Bay_Airport","BC2"
"672","CBD6","small_airport","Nahanni Butte Airport","61.029701232910156","-123.38899993896484","600","NA","CA","CA-NT","Nahanni Butte","no","","","CBD6","CBD6","","https://en.wikipedia.org/wiki/Nahanni_Butte_Airport","BD6"
"686","CBH4","small_airport","Prairie Creek Airport","61.564701080322266","-124.81500244140625","2950","NA","CA","CA-NT","Prairie Creek","no","","","CBH4","CBH4","","https://en.wikipedia.org/wiki/Prairie_Creek_Airport","BH4"
"736","CBX5","small_airport","Tungsten (Cantung) Airport","61.956901550293","-128.20300292969","3500","NA","CA","CA-NT","Tungsten","no","","TNS","CBX5","CBX5","","https://en.wikipedia.org/wiki/Tungsten_(Cantung)_Airport","BX5"
"814","CDK2","small_airport","Diavik Airport","64.5113983154","-110.289001465","1413","NA","CA","CA-NT","Diavik","no","","DVK","CDK2","CDK2","","https://en.wikipedia.org/wiki/Diavik_Airport","DK2"
"43879","CDL7","small_airport","Doris Lake","68.1252746582","-106.585281372","50","NA","CA","CA-NU","Hope Bay","no","","JOJ","","CDL7","","https://en.wikipedia.org/wiki/Doris_Lake_Aerodrome",""
"1802","CYLK","small_airport","Lutselk'e Airport","62.417823","-110.682793","596","NA","CA","CA-NT","Lutselk'e","yes","CYLK","YSG","CYLK","","","https://en.wikipedia.org/wiki/Lutselk'e_Airport","YLK, EL3, Snowdrift Airport"
"314953","CYVL","small_airport","Tommy Kochon Airport","67.02015","-126.128364","870","NA","CA","CA-NT","Colville Lake","yes","CYVL","YCK","CYVL","","","https://en.wikipedia.org/wiki/Colville_Lake/Tommy_Kochon_Aerodrome",""
"925","CFA7","small_airport","Taltheilei Narrows Airport","62.5980987549","-111.542999268","570","NA","CA","CA-NT","Taltheilei Narrows","no","","GSL","CFA7","CFA7","","https://en.wikipedia.org/wiki/Taltheilei_Narrows_Airport","FA7"
"1726","CYEV","medium_airport","Inuvik Mike Zubko Airport","68.30419921880001","-133.483001709","224","NA","CA","CA-NT","Inuvik","yes","CYEV","YEV","CYEV","","","https://en.wikipedia.org/wiki/Inuvik_(Mike_Zubko)_Airport",""
"1868","CYQH","medium_airport","Watson Lake Airport","60.116839","-128.821993","2255","NA","CA","CA-YT","Watson Lake","yes","CYQH","YQH","CYQH","","","https://en.wikipedia.org/wiki/Watson_Lake_Airport",""
"1948","CYWJ","small_airport","Déline Airport","65.211098","-123.435997","703","NA","CA","CA-NT","Déline","yes","CYWJ","YWJ","CYWJ","","","https://en.wikipedia.org/wiki/Deline_Airport","Délı̨nę, Fort Franklin"
"1993","CYZF","medium_airport","Yellowknife International Airport","62.462799","-114.440002","675","NA","CA","CA-NT","Yellowknife","yes","CYZF","YZF","CYZF","","https://www.inf.gov.nt.ca/en/services/airports/yellowknife-airport","https://en.wikipedia.org/wiki/Yellowknife_Airport",""
"28331","CEP9","seaplane_base","Namushka Lodge Seaplane Base","62.416698","-113.349998","670","NA","CA","CA-NT","","no","","","CEP9","CEP9","","https://en.wikipedia.org/wiki/Namushka_Lodge_Water_Aerodrome","EP9"
"1786","CYKD","small_airport","Aklavik/Freddie Carmichael Airport","68.223297","-135.00599","23","NA","CA","CA-NT","Aklavik","yes","CYKD","LAK","CYKD","","","https://en.wikipedia.org/wiki/Aklavik_Airport","YKD"
"28159","CES6","seaplane_base","Arctic Red River Seaplane Base","67.449997","-133.75","20","NA","CA","CA-NT","","no","","","","ES6","","https://en.wikipedia.org/wiki/Arctic_Red_River_Water_Aerodrome",""
"944","CFF4","small_airport","Great Bear Lake Airport","66.703053","-119.716816","562","NA","CA","CA-NT","Great Bear Lake","no","","DAS","CFF4","CFF4","","https://en.wikipedia.org/wiki/Great_Bear_Lake_Airport","FF4"
"1737","CYFS","medium_airport","Fort Simpson Airport","61.76020050048828","-121.23699951171875","555","NA","CA","CA-NT","Fort Simpson","yes","CYFS","YFS","CYFS","","","https://en.wikipedia.org/wiki/Fort_Simpson_Airport",""
"901","CET9","small_airport","Jean Marie River Airport","61.522449","-120.625334","470","NA","CA","CA-NT","Jean Marie River","no","","","CET9","CET9","","https://en.wikipedia.org/wiki/Jean_Marie_River_Airport","ET9"
"1940","CYVQ","medium_airport","Norman Wells Airport","65.28160095214844","-126.7979965209961","238","NA","CA","CA-NT","Norman Wells","yes","CYVQ","YVQ","CYVQ","","","https://en.wikipedia.org/wiki/Norman_Wells_Airport",""
"909","CEV9","small_airport","Snare River Airport","63.4333","-116.174963","700","NA","CA","CA-NT","Snare River","no","","","CEV9","CEV9","","https://en.wikipedia.org/wiki/Snare_River_Airport","EV9"
"1843","CYPC","small_airport","Paulatuk (Nora Aliqatchialuk Ruben) Airport","69.360838","-124.07547","15","NA","CA","CA-NT","Paulatuk","yes","CYPC","YPC","CYPC","","","https://en.wikipedia.org/wiki/Paulatuk_Airport",""
"933","CFC4","small_airport","Macmillan Pass Airport","63.181098938","-130.20199585","3810","NA","CA","CA-YT","Macmillan Pass","no","","XMP","CFC4","CFC4","","https://en.wikipedia.org/wiki/Macmillian_Pass_Airport","FC4"
"996","CFT3","small_airport","Finlayson Lake Airport","61.6913986206","-130.774002075","3094","NA","CA","CA-YT","Finlayson Lake","no","","","CFT3","CFT3","","https://en.wikipedia.org/wiki/Finlayson_Lake_Airport","FT3"
"997","CFT5","small_airport","Hyland Airport","61.52389907836914","-128.2689971923828","3000","NA","CA","CA-YT","Hyland","no","","","CFT5","CFT5","","https://en.wikipedia.org/wiki/Hyland_Airport","FT5"
"28459","CFV5","seaplane_base","Virginia Falls Seaplane Base","61.607575","-125.756272","1702","NA","CA","CA-NT","","no","","","CFV5","CFV5","","https://en.wikipedia.org/wiki/Virginia_Falls_Water_Aerodrome",""
"1021","CFY5","small_airport","Pine Lake","60.10309982299805","-130.9340057373047","3250","NA","CA","CA-YT","Pine Lake","no","","","CFY5","CFY5","","https://en.wikipedia.org/wiki/Daughney_Aerodrome","FY5"
"44373","CGK2","small_airport","Gahcho Kue","63.435198","-109.144812","1371","NA","CA","CA-NT","Kennedy Lake","no","","GHK","CGK2","CGK2","","https://en.wikipedia.org/wiki/Gahcho_Kue_Aerodrome","De Beers Canada"
"308297","CGR3","small_airport","George Lake Aerodrome","65.928056","-107.462222","1150","NA","CA","CA-NU","","no","","","CGR3","CGR3","","https://en.wikipedia.org/wiki/George_Lake_Aerodrome",""
"308296","CGS2","small_airport","Goose Lake Aerodrome","65.552778","-106.433611","907","NA","CA","CA-NU","","no","","","CGS2","CGS2","","https://en.wikipedia.org/wiki/Goose_Lake_Aerodrome",""
"308295","CHC5","small_airport","Hayes Camp Aerodrome","66.661012","-91.55346","780","NA","CA","CA-NU","","no","","","CHC5","CHC5","","https://en.wikipedia.org/wiki/Hayes_Camp_Aerodrome",""
"1685","CYCB","medium_airport","Cambridge Bay Airport","69.1081008911","-105.138000488","90","NA","CA","CA-NU","Cambridge Bay","yes","CYCB","YCB","CYCB","","","https://en.wikipedia.org/wiki/Cambridge_Bay_Airport",""
"1674","CYBK","medium_airport","Baker Lake Airport","64.29889678960001","-96.077796936","59","NA","CA","CA-NU","Baker Lake","yes","CYBK","YBK","CYBK","","","https://en.wikipedia.org/wiki/Baker_Lake_Airport",""
"28228","CJN8","seaplane_base","Fort Reliance Seaplane Base","62.7","-109.167","514","NA","CA","CA-NT","Fort Reliance","no","","YFL","CJN8","CJN8","","https://en.wikipedia.org/wiki/Fort_Reliance_Water_Aerodrome","JN8"
"1111","CJQ6","small_airport","Tanquary Fiord Airport","81.409422","-76.867901","50","NA","CA","CA-NU","Tanquary Fiord","no","","","CJQ6","CJQ6","","https://en.wikipedia.org/wiki/Tanquary_Fiord_Airport","JQ6"
"299180","CMB2","small_airport","Meadowbank Airport","65.0246615457","-96.06865882870001","475","NA","CA","CA-NU","Agnico-Eagle Meadowbank Gold Mine","no","","","CMB2","CMB2","","https://en.wikipedia.org/wiki/Meadowbank_Aerodrome",""
"1308","CNH2","small_airport","Natuashish Airport","55.913898","-61.184399","30","NA","CA","CA-NL","Natuashish","yes","","YNP","CNH2","CNH2","","https://en.wikipedia.org/wiki/Natuashish_Airport","NH2"
"1486","CRE2","small_airport","Edzo Airport","62.766701","-116.084","587","NA","CA","CA-NT","Rae-Edzo","no","","","CRE2","CRE2","","https://en.wikipedia.org/wiki/Rae/Edzo_Airport","RE2"
"1718","CYEK","small_airport","Arviat Airport","61.0942","-94.070801","32","NA","CA","CA-NU","Arviat","yes","CYEK","YEK","CYEK","","","https://en.wikipedia.org/wiki/Arviat_Airport",""
"1531","CSK6","small_airport","Snap Lake Airport","63.593601","-110.905998","1557","NA","CA","CA-NT","Snap Lake Mine","no","","YNX","","","","https://en.wikipedia.org/wiki/Snap_Lake_Airport","CSK6"
"316099","CTM7","small_airport","Tundra Mine/Salamita Mine Aerodrome","64.0725","-111.158","1445","NA","CA","CA-NT","Tundra and Salamita Mines","no","","","CTM7","CTM7","","https://en.wikipedia.org/wiki/Tundra_Mine/Salamita_Mine_Aerodrome",""
"1608","CTP9","small_airport","Donaldson Airport","61.662201","-73.321404","1902","NA","CA","CA-QC","Kattiniq","no","","YAU","CTP9","CTP9","","https://en.wikipedia.org/wiki/Kattiniq/Donaldson_Airport",""
"1712","CYDP","small_airport","Nain Airport","56.550778","-61.682224","22","NA","CA","CA-NL","Nain","yes","CYDP","YDP","CYDP","","","https://en.wikipedia.org/wiki/Nain_Airport",""
"300457","CWJC","small_airport","Ennadai Lake Airport","61.1333333333","-100.9","1021","NA","CA","CA-NU","Ennadai","no","","","CWJC","","","",""
"46596","CYAB","small_airport","Arctic Bay Airport","73.006101","-85.04616","72","NA","CA","CA-NU","Arctic Bay","yes","CYAB","YAB","CYAB","","","https://en.wikipedia.org/wiki/Arctic_Bay_Airport","CJX7"
"1659","CYAS","small_airport","Kangirsuk Airport","60.027199","-69.999199","403","NA","CA","CA-QC","Kangirsuk","yes","CYAS","YKG","CYAS","","","https://en.wikipedia.org/wiki/Kangirsuk_Airport","YAS"
"1668","CYBB","small_airport","Kugaaruk Airport","68.535711","-89.805508","56","NA","CA","CA-NU","Kugaaruk","yes","CYBB","YBB","CYBB","","","https://en.wikipedia.org/wiki/Kugaaruk_Airport","YBB, Pelly Bay Townsite Airport"
"1693","CYCO","small_airport","Kugluktuk Airport","67.816408","-115.14307","74","NA","CA","CA-NU","Kugluktuk","yes","CYCO","YCO","CYCO","","","https://en.wikipedia.org/wiki/Kugluktuk_Airport","Copper Mine Airport"
"1697","CYCS","small_airport","Chesterfield Inlet Airport","63.346901","-90.731102","32","NA","CA","CA-NU","Chesterfield Inlet","yes","CYCS","YCS","CYCS","","","https://en.wikipedia.org/wiki/Chesterfield_Inlet_Airport",""
"353838","CYD2","seaplane_base","Yellow Dog Lodge Seaplane Base","62.890556","-113.867778","725","NA","CA","CA-NT","Graham Lake","no","","","CYD2","CYD2","https://yellowdoglodge.ca/","https://en.wikipedia.org/wiki/Graham_Lake_(Yellow_Dog_Lodge)_Water_Aerodrome",""
"1708","CYDL","small_airport","Dease Lake Airport","58.422199","-130.031998","2600","NA","CA","CA-BC","Dease Lake","yes","CYDL","YDL","CYDL","","","https://en.wikipedia.org/wiki/Dease_Lake_Airport","YDL"
"1725","CYEU","small_airport","Eureka Airport","79.9946975708","-85.814201355","256","NA","CA","CA-NU","Eureka","no","CYEU","YEU","CYEU","","","https://en.wikipedia.org/wiki/Eureka_Aerodrome","YEU"
"1742","CYGH","small_airport","Fort Good Hope Airport","66.240658","-128.647757","268","NA","CA","CA-NT","Fort Good Hope","yes","CYGH","YGH","CYGH","","","https://en.wikipedia.org/wiki/Fort_Good_Hope_Airport",""
"1750","CYGT","small_airport","Igloolik Airport","69.3647","-81.816101","174","NA","CA","CA-NU","Igloolik","yes","CYGT","YGT","CYGT","","","https://en.wikipedia.org/wiki/Igloolik_Airport",""
"1752","CYGW","medium_airport","Kuujjuarapik Airport","55.281898498535156","-77.76529693603516","34","NA","CA","CA-QC","Kuujjuarapik","yes","CYGW","YGW","CYGW","","","https://en.wikipedia.org/wiki/Kuujjuarapik_Airport",""
"1754","CYGZ","small_airport","Grise Fiord Airport","76.425823","-82.908583","146","NA","CA","CA-NU","Grise Fiord","yes","CYGZ","YGZ","CYGZ","","","https://en.wikipedia.org/wiki/Grise_Fiord_Airport",""
"1761","CYHI","small_airport","Ulukhaktok Holman Airport","70.762802","-117.806","117","NA","CA","CA-NT","Ulukhaktok","yes","CYHI","YHI","CYHI","","","https://en.wikipedia.org/wiki/Ulukhaktok/Holman_Airport",""
"1762","CYHK","small_airport","Gjoa Haven Airport","68.635597","-95.849701","152","NA","CA","CA-NU","Gjoa Haven","yes","CYHK","YHK","CYHK","","","https://en.wikipedia.org/wiki/Gjoa_Haven_Airport",""
"1765","CYHO","small_airport","Hopedale Airport","55.448757","-60.228124","39","NA","CA","CA-NL","Hopedale","yes","CYHO","YHO","CYHO","","","https://en.wikipedia.org/wiki/Hopedale_Airport","CC5"
"1774","CYIK","small_airport","Ivujivik Airport","62.417301","-77.925301","126","NA","CA","CA-QC","Ivujivik","yes","CYIK","YIK","CYIK","","","https://en.wikipedia.org/wiki/Ivujivik_Airport",""
"1775","CYIO","small_airport","Pond Inlet Airport","72.689494","-77.968941","181","NA","CA","CA-NU","Pond Inlet","yes","CYIO","YIO","CYIO","","","https://en.wikipedia.org/wiki/Pond_Inlet_Airport",""
"1788","CYKG","small_airport","Kangiqsujuaq (Wakeham Bay) Airport","61.5886","-71.929398","501","NA","CA","CA-QC","Kangiqsujuaq","yes","CYKG","YWB","CYKG","","","https://en.wikipedia.org/wiki/Kangiqsujuaq_(Wakeham_Bay)_Airport",""
"1791","CYKO","small_airport","Akulivik Airport","60.8186","-78.148598","75","NA","CA","CA-QC","Akulivik","yes","CYKO","AKV","CYKO","","","https://en.wikipedia.org/wiki/Akulivik_Airport","YKO"
"1796","CYLA","small_airport","Aupaluk Airport","59.2967","-69.599701","119","NA","CA","CA-QC","Aupaluk","yes","CYLA","YPJ","CYLA","","","https://en.wikipedia.org/wiki/Aupaluk_Airport","YLA"
"1806","CYLT","medium_airport","Alert Airport","82.517263","-62.283037","100","NA","CA","CA-NU","Alert","no","CYLT","YLT","CYLT","","","https://en.wikipedia.org/wiki/Alert_Airport","YLT"
"1818","CYMU","small_airport","Umiujaq Airport","56.536098","-76.518303","250","NA","CA","CA-QC","Umiujaq","yes","CYMU","YUD","CYMU","","","https://en.wikipedia.org/wiki/Umiujaq_Airport","YMU"
"1847","CYPH","small_airport","Inukjuak Airport","58.471901","-78.076897","83","NA","CA","CA-QC","Inukjuak","yes","CYPH","YPH","CYPH","","","https://en.wikipedia.org/wiki/Inukjuak_Airport",""
"1860","CYPX","medium_airport","Puvirnituq Airport","60.050598","-77.286903","74","NA","CA","CA-QC","Puvirnituq","yes","CYPX","YPX","CYPX","","","https://en.wikipedia.org/wiki/Puvirnituq_Airport",""
"1884","CYRA","small_airport","Rae Lakes Airport","64.116096","-117.309998","723","NA","CA","CA-NT","Gamètì","yes","CYRA","YRA","CYRA","","","https://en.wikipedia.org/wiki/Gam%C3%A8t%C3%AC/Rae_Lakes_Airport",""
"1885","CYRB","medium_airport","Resolute Bay Airport","74.7169036865","-94.9693984985","215","NA","CA","CA-NU","Resolute Bay","yes","CYRB","YRB","CYRB","","","https://en.wikipedia.org/wiki/Resolute_Bay_Airport",""
"1895","CYRT","medium_airport","Rankin Inlet Airport","62.8114013672","-92.1157989502","94","NA","CA","CA-NU","Rankin Inlet","yes","CYRT","YRT","CYRT","","","https://en.wikipedia.org/wiki/Rankin_Inlet_Airport",""
"1905","CYSK","small_airport","Sanikiluaq Airport","56.536891","-79.250221","104","NA","CA","CA-NU","Sanikiluaq","yes","CYSK","YSK","CYSK","","","https://en.wikipedia.org/wiki/Sanikiluaq_Airport",""
"1915","CYSY","small_airport","Sachs Harbour (David Nasogaluak Jr. Saaryuaq) Airport","71.993896","-125.242996","282","NA","CA","CA-NT","Sachs Harbour","yes","CYSY","YSY","CYSY","","","https://en.wikipedia.org/wiki/Sachs_Harbour_Airport",""
"1918","CYTE","small_airport","Cape Dorset Airport","64.230003","-76.526703","164","NA","CA","CA-NU","Kinngait","yes","CYTE","YTE","CYTE","","","https://en.wikipedia.org/wiki/Cape_Dorset_Airport",""
"1923","CYTQ","small_airport","Tasiujaq Airport","58.667801","-69.955803","122","NA","CA","CA-QC","Tasiujaq","yes","CYTQ","YTQ","CYTQ","","","https://en.wikipedia.org/wiki/Tasiujaq_Airport",""
"1927","CYUB","small_airport","Tuktoyaktuk / James Gruben Airport","69.433296","-133.026001","15","NA","CA","CA-NT","Tuktoyaktuk","no","CYUB","YUB","CYUB","","","https://en.wikipedia.org/wiki/Tuktoyaktuk/James_Gruben_Airport",""
"1929","CYUT","small_airport","Naujaat Airport","66.521024","-86.225166","80","NA","CA","CA-NU","Repulse Bay","yes","CYUT","YUT","CYUT","","","https://en.wikipedia.org/wiki/Repulse_Bay_Airport","Repulse Bay Airport"
"1930","CYUX","medium_airport","Hall Beach Airport","68.7761","-81.2425","30","NA","CA","CA-NU","Sanirajak","yes","CYUX","YUX","CYUX","","","https://en.wikipedia.org/wiki/Hall_Beach_Airport",""
"1939","CYVP","medium_airport","Kuujjuaq Airport","58.096099853515625","-68.4269027709961","129","NA","CA","CA-QC","Kuujjuaq","yes","CYVP","YVP","CYVP","","","https://en.wikipedia.org/wiki/Kuujjuaq_Airport",""
"954","CYWE","small_airport","Wekweètì Airport","64.190804","-114.077002","1208","NA","CA","CA-NT","Wekweètì","yes","CYWE","YFJ","CYWE","CFJ7","","https://en.wikipedia.org/wiki/Wekwe%C3%A8t%C3%AC_Airport","Wekweti, Snare Lake"
"1954","CYWY","medium_airport","Wrigley Airport","63.20940017700195","-123.43699645996094","489","NA","CA","CA-NT","Wrigley","no","CYWY","YWY","CYWY","","","https://en.wikipedia.org/wiki/Wrigley_Airport",""
"1962","CYXN","small_airport","Whale Cove Airport","62.240002","-92.598099","40","NA","CA","CA-NU","Whale Cove","yes","CYXN","YXN","CYXN","","","https://en.wikipedia.org/wiki/Whale_Cove_Airport",""
"1978","CYYH","small_airport","Taloyoak Airport","69.5467","-93.576698","92","NA","CA","CA-NU","Taloyoak","yes","CYYH","YYH","CYYH","","","https://en.wikipedia.org/wiki/Taloyoak_Airport","Spence Bay"
"1984","CYYQ","medium_airport","Churchill Airport","58.739200592041016","-94.06500244140625","94","NA","CA","CA-MB","Churchill","yes","CYYQ","YYQ","CYYQ","","","https://en.wikipedia.org/wiki/Churchill_Airport",""
"1994","CYZG","small_airport","Salluit Airport","62.179401","-75.667198","743","NA","CA","CA-QC","Salluit","yes","CYZG","YZG","CYZG","","","https://en.wikipedia.org/wiki/Salluit_Airport",""
"1998","CYZS","medium_airport","Coral Harbour Airport","64.1932983398","-83.3593978882","210","NA","CA","CA-NU","Coral Harbour","yes","CYZS","YZS","CYZS","","","https://en.wikipedia.org/wiki/Coral_Harbour_Airport",""
"2017","CZFM","small_airport","Fort Mcpherson Airport","67.406993","-134.860182","116","NA","CA","CA-NT","Fort Mcpherson","yes","CZFM","ZFM","CZFM","","","https://en.wikipedia.org/wiki/Fort_McPherson_Airport",""
"2018","CZFN","small_airport","Tulita Airport","64.909496","-125.570297","332","NA","CA","CA-NT","Tulita","yes","CZFN","ZFN","CZFN","","","https://en.wikipedia.org/wiki/Tulita_Airport","Fort Norman"
"307365","EGAH","small_airport","Halley Research Station","-75.567406","-25.516435","103","AN","AQ","AQ-U-A","Halley Research Station","no","EGAH","","EGAH","","","https://en.wikipedia.org/wiki/Halley_Research_Station","Halley, Antarctica, British Antarctic Survey"
"324046","EGAT","small_airport","Sky Blu Airstrip","-74.849722","-71.566666","4740","AN","AQ","AQ-U-A","Sky Blu","no","EGAT","","EGAT","","https://www.bas.ac.uk/polar-operations/sites-and-facilities/facility/rothera/sky-blu/","https://en.wikipedia.org/wiki/Sky_Blu",""
"31004","ENAS","small_airport","Ny-Ålesund Airport, Hamnerabben","78.927498","11.8743","50","EU","NO","NO-21","Ny-Ålesund","no","","","ENAS","","","https://en.wikipedia.org/wiki/Ny-%C3%85lesund_Airport,_Hamnerabben","Brøggerhalvøya Airport"
"2877","FHAW","medium_airport","RAF Ascension Island","-7.970179","-14.392744","278","AF","SH","SH-AC","Cat Hill","yes","FHAW","ASI","FHAW","","https://www.raf.mod.uk/our-organisation/stations/ascension-island-base/","https://en.wikipedia.org/wiki/RAF_Ascension_Island","Wideawake Airfield, Ascension Island Auxiliary Field"
"318444","FHSH","medium_airport","Saint Helena International Airport","-15.958898","-5.646066","1017","AF","SH","SH-SH","Jamestown","yes","FHSH","HLE","FHSH","","http://sthelenaairport.com/","https://en.m.wikipedia.org/wiki/Saint_Helena_Airport#",""
"44073","GL-0006","small_airport","Summit Ice Landing Strip","72.616669","-38.5","10523","NA","GL","GL-NE","Summit Camp","no","","","","","","https://en.wikipedia.org/wiki/Summit_Camp","SUMUD"
"44064","GL-0003","small_airport","NorthGRIP Airport","75.099998","-42.316666","","NA","GL","GL-NE","NorthGRIP","no","","","","","","","GIRPA, North Greenland Ice Core Project"
"505046","GL-0014","small_airport","EastGRIP Airport","75.63","-35.99","","NA","GL","GL-NE","EastGRIP","no","","","","","","","East Greenland Ice-Core Project"
"4582","HL56","medium_airport","Matan al-Sarra Air Base","21.6877","21.8309","1769","AF","LY","LY-KF","","no","","","HL56","HL56","","https://en.wikipedia.org/wiki/Maaten_al-Sarra_Air_Base",""
"19520","KCN","seaplane_base","Chernofski Harbor Seaplane Base","53.402899","-167.520272","","NA","US","US-AK","Chernofski Harbor","no","","KCN","KCN","KCN","","http://wikimapia.org/6966644/Port-of-Chernofski-Harbor",""
"26910","YBIE","medium_airport","Bedourie Airport","-24.3461","139.460007","300","OC","AU","AU-QLD","Bedourie","yes","YBIE","BEU","YBIE","","","https://en.wikipedia.org/wiki/Bedourie_Airport",""
"308030","PAUT","small_airport","Akutan Airport","54.14459","-165.604332","133","NA","US","US-AK","Akutan","yes","PAUT","KQA","PAUT","7AK","https://web.archive.org/web/20100410064944/http://dot.alaska.gov/creg/akutan/assets/Akun_ALP_Sheet-Set-1-9.pdf","https://en.wikipedia.org/wiki/Akutan_Airport","Akun Airport"
"31907","NCMH","small_airport","Manihiki Island Airport","-10.38091","-160.999424","11","OC","CK","CK-U-A","Manihiki Island","yes","NCMH","MHX","NCMH","","","https://en.wikipedia.org/wiki/Manihiki_Island_Airport","Humphrey Island, Te Fuinga o Niva"
"32184","NCPY","small_airport","Tongareva Airport","-9.01437","-158.03241","8","OC","CK","CK-U-A","Penrhyn Island","no","NCPY","PYE","NCPY","","","https://en.wikipedia.org/wiki/Tongareva_Airport",""
"4986","NTGE","medium_airport","Reao Airport","-18.46652","-136.43855","12","OC","PF","PF-U-A","Reao","no","NTGE","REA","NTGE","","","https://en.wikipedia.org/wiki/Reao_Airport",""
"4989","NTGJ","medium_airport","Totegegie Airport","-23.07990074157715","-134.88999938964844","7","OC","PF","PF-U-A","","yes","NTGJ","GMR","NTGJ","","","https://en.wikipedia.org/wiki/Totegegie_Airport",""
"32456","NTGO","small_airport","Tatakoto Airport","-17.355226","-138.44734","12","OC","PF","PF-U-A","Tatakoto","yes","NTGO","TKV","NTGO","","","https://en.wikipedia.org/wiki/Tatakoto_Airport",""
"4992","NTGP","small_airport","Puka Puka Airport","-14.80955","-138.812621","5","OC","PF","PF-U-A","","yes","NTGP","PKP","NTGP","","","https://en.wikipedia.org/wiki/Puka-Puka_Airport",""
"32177","NTGQ","small_airport","Pukaruha Airport","-18.295726","-137.016291","5","OC","PF","PF-U-A","Pukaruha","no","NTGQ","PUK","NTGQ","","","https://en.wikipedia.org/wiki/Pukarua_Airport",""
"44636","NTGS","small_airport","Marutea Airport","-21.482194900512695","-135.63705444335938","10","OC","PF","PF-U-A","Auorotini","no","","","NTGS","","","https://en.wikipedia.org/wiki/Marutea_Sud",""
"32055","NTGW","small_airport","Nukutavake Airport","-19.284613","-138.768367","17","OC","PF","PF-U-A","Nukutavake","no","NTGW","NUK","NTGW","","","https://en.wikipedia.org/wiki/Nukutavake_Airport",""
"4996","NTGY","small_airport","Tureia Airport","-20.784262","-138.56796","12","OC","PF","PF-U-A","Tureia","no","NTGY","ZTA","NTGY","","","https://en.wikipedia.org/wiki/Tureia_Airport",""
"31128","NTKH","small_airport","Fakahina Airport","-15.992259","-140.164246","3","OC","PF","PF-U-A","Fakahina","yes","NTKH","FHZ","NTKH","","","https://en.wikipedia.org/wiki/Fakahina_Airfield",""
"5001","NTMD","medium_airport","Nuku Hiva Airport","-8.7956","-140.229004","220","OC","PF","PF-U-A","Nuku Hiva","yes","NTMD","NHV","NTMD","","","https://en.wikipedia.org/wiki/Nuku_Hiva_Airport",""
"5002","NTMN","medium_airport","Hiva Oa-Atuona Airport","-9.76879024506","-139.011001587","1481","OC","PF","PF-U-A","Hiva Oa Island","yes","NTMN","AUQ","NTMN","","","https://en.wikipedia.org/wiki/Atuona_Airport","HIX"
"32499","NTMP","small_airport","Ua Pou Airport","-9.35167","-140.078003","16","OC","PF","PF-U-A","Ua Pou","yes","NTMP","UAP","NTMP","","","https://en.wikipedia.org/wiki/Ua_Pou_Airport",""
"32497","NTMU","small_airport","Ua Huka Airport","-8.936228","-139.554062","160","OC","PF","PF-U-A","Ua Huka","yes","NTMU","UAH","NTMU","","","https://en.wikipedia.org/wiki/Ua_Huka_Airport",""
"32053","NTTX","small_airport","Moruroa Airport","-21.80978","-138.813385","7","OC","PF","PF-TG","Moruroa Atoll","no","NTTX","UOA","NTTX","","","","Mururoa, Mururura, Aopuni"
"32573","NTUV","small_airport","Vahitahi Airport","-18.780697","-138.85568","9","OC","PF","PF-U-A","Vahitahi","no","NTUV","VHZ","NTUV","","","https://en.wikipedia.org/wiki/Vahitahi_Airport",""
"11","NZ12","small_airport","Palmer Station Airport","-64.774582","-64.035907","149","AN","AQ","AQ-U-A","Palmer Station","no","","","NZ0B","NZ0B","","https://en.wikipedia.org/wiki/Palmer_Station",""
"340683","NZFX","small_airport","Phoenix Airfield","-77.956389","166.766667","18","AN","AQ","AQ-U-A","McMurdo Station","no","","","NZFX","","","https://en.wikipedia.org/wiki/Phoenix_Airfield",""
"16190","PAAK","small_airport","Atka Airport","52.220299","-174.205994","57","NA","US","US-AK","Atka","yes","PAAK","AKB","PAAK","AKA","","https://en.wikipedia.org/wiki/Atka_Airport","40A"
"5354","PADU","medium_airport","Tom Madsen (Dutch Harbor) Airport","53.89881","-166.544996","22","NA","US","US-AK","Unalaska","yes","PADU","DUT","PADU","DUT","","https://en.wikipedia.org/wiki/Unalaska_Airport","Dutch Harbor, Unalaska"
"16094","PAAP","seaplane_base","Port Alexander Seaplane Base","56.246799","-134.647995","","NA","US","US-AK","Port Alexander","yes","PAAP","PTD","PAAP","AHP","","https://en.wikipedia.org/wiki/Port_Alexander_Seaplane_Base","AK15"
"5337","PABA","medium_airport","Barter Island Long Range Radar Station Airport","70.134003","-143.582001","2","NA","US","US-AK","Barter Island","yes","PABA","BTI","PABA","BTI","","https://en.wikipedia.org/wiki/Barter_Island_LRRS_Airport",""
"5342","PABR","medium_airport","Wiley Post Will Rogers Memorial Airport","71.285402","-156.766008","44","NA","US","US-AK","Utqiaġvik","yes","PABR","BRW","PABR","BRW","","https://en.wikipedia.org/wiki/Wiley_Post-Will_Rogers_Memorial_Airport","Barrow"
"9088","PACS","small_airport","Cape Sarichef Airport","54.583934","-164.905727","291","NA","US","US-AK","Cape Sarichef","no","PACS","WSF","PACS","26AK","","https://en.wikipedia.org/wiki/Cape_Sarichef_Airport",""
"16092","PADK","medium_airport","Adak Airport","51.883564","-176.642783","18","NA","US","US-AK","Adak","yes","PADK","ADK","PADK","ADK","","https://en.wikipedia.org/wiki/Adak_Airport",""
"5368","PAGM","medium_airport","Gambell Airport","63.767694","-171.733303","27","NA","US","US-AK","Gambell","yes","PAGM","GAM","PAGM","GAM","","https://en.wikipedia.org/wiki/Gambell_Airport",""
"18251","PAIW","small_airport","Wales Airport","65.622593","-168.095","22","NA","US","US-AK","Wales","yes","PAIW","WAA","PAIW","IWK","","https://en.wikipedia.org/wiki/Wales_Airport_(Alaska)",""
"19891","PAKF","small_airport","False Pass Airport","54.84751","-163.407168","20","NA","US","US-AK","False Pass","yes","PAKF","KFP","PAKF","KFP","","https://en.wikipedia.org/wiki/False_Pass_Airport",""
"17980","PAKO","small_airport","Nikolski Air Station","52.941552","-168.849478","77","NA","US","US-AK","Nikolski","yes","PAKO","IKO","PAKO","IKO","","https://en.wikipedia.org/wiki/Nikolski_Air_Station",""
"16165","PALN","small_airport","Point Lonely Short Range Radar Site Airfield","70.911118","-153.237766","17","NA","US","US-AK","Point Lonely","no","PALN","LNI","PALN","AK71","","https://en.wikipedia.org/wiki/Point_Lonely_Short_Range_Radar_Site","Lonely Air Station"
"5385","PALU","medium_airport","Cape Lisburne LRRS Airport","68.875099","-166.110001","16","NA","US","US-AK","Cape Lisburne","yes","PALU","LUR","PALU","LUR","","https://en.wikipedia.org/wiki/Cape_Lisburne_LRRS_Airport",""
"5396","PAPB","medium_airport","St George Airport","56.577345","-169.663823","125","NA","US","US-AK","St George","yes","PAPB","STG","PAPB","PBV","","https://en.wikipedia.org/wiki/St._George_Airport_(Alaska)","A8L"
"24089","PAPO","small_airport","Point Hope Airport","68.348801","-166.798996","12","NA","US","US-AK","Point Hope","yes","PAPO","PHO","PAPO","PHO","","https://en.wikipedia.org/wiki/Point_Hope_Airport",""
"5404","PASA","medium_airport","Savoonga Airport","63.686401","-170.492996","53","NA","US","US-AK","Savoonga","yes","PASA","SVA","PASA","SVA","","https://en.wikipedia.org/wiki/Savoonga_Airport",""
"5410","PASN","medium_airport","St Paul Island Airport","57.166311","-170.222555","63","NA","US","US-AK","St Paul Island","yes","PASN","SNP","PASN","SNP","","https://en.wikipedia.org/wiki/St._Paul_Island_Airport","Pribilof"
"5413","PASY","medium_airport","Eareckson Air Station","52.71229935","174.1139984","95","NA","US","US-AK","Shemya","no","PASY","SYA","PASY","SYA","","https://en.wikipedia.org/wiki/Eareckson_Air_Station",""
"5416","PATQ","medium_airport","Atqasuk Edward Burnell Sr Memorial Airport","70.46704","-157.436013","96","NA","US","US-AK","Atqasuk","yes","PATQ","ATK","PATQ","ATK","","https://en.wikipedia.org/wiki/Atqasuk_Edward_Burnell_Sr._Memorial_Airport","Z46"
"5419","PAVL","small_airport","Kivalina Airport","67.734565","-164.559917","13","NA","US","US-AK","Kivalina","yes","PAVL","KVL","PAVL","KVL","","https://en.wikipedia.org/wiki/Kivalina_Airport",""
"5422","PAWI","medium_airport","Wainwright Airport","70.638","-159.994995","41","NA","US","US-AK","Wainwright","yes","PAWI","AIN","PAWI","AWI","","https://en.wikipedia.org/wiki/Wainwright_Airport_(Alaska)","5WW"
"5426","PCIS","medium_airport","Canton Island Airport","-2.7681200504300003","-171.710006714","9","OC","KI","KI-P","Abariringa","no","PCIS","CIS","PCIS","","","https://en.wikipedia.org/wiki/Canton_Island_Airport","Kanton Island"
"5494","PMDY","medium_airport","Henderson Field","28.2017","-177.380997","13","OC","UM","UM-71","Sand Island","no","PMDY","MDY","PMDY","MDY","","https://en.wikipedia.org/wiki/Henderson_Field_(Midway_Atoll)",""
"5495","PPIZ","medium_airport","Point Lay LRRS Airport","69.732903","-163.005005","22","NA","US","US-AK","Point Lay","yes","PPIZ","PIZ","PPIZ","PIZ","","https://en.wikipedia.org/wiki/Point_Lay_LRRS_Airport",""
"5506","PWAK","medium_airport","Wake Island Airfield","19.282437","166.636637","14","OC","UM","UM-79","Wake Island","yes","PWAK","AWK","PWAK","AWK","","https://en.wikipedia.org/wiki/Wake_Island_Airfield",""
"5534","RJAM","small_airport","JMSDF Minami Torishima Air Base","24.2897","153.979004","22","AS","JP","JP-13","Ogasawara","no","RJAM","MUS","RJAM","","","https://en.wikipedia.org/wiki/Minami_Torishima_Airport","Marcus Island Airport"
"5535","RJAW","medium_airport","Ioto (Iwo Jima) Airbase","24.784153","141.32261","384","AS","JP","JP-13","Ogasawara","no","RJAW","IWO","RJAW","","","https://en.wikipedia.org/wiki/Central_Field_(Iwo_Jima)","Iwo Jima Airport, Central Field, Ioto, Iōtō"
"42980","UESU","medium_airport","Zyryanka Airport","65.7485","150.8889","140","AS","RU","RU-SA","Zyryanka","yes","UESU","ZKP","UESU","","","https://en.wikipedia.org/wiki/Zyryanka_Airport","УЕСУ, Аэропорт Зырянка"
"323626","RU-0472","small_airport","Lamutskoye Airport","65.538838","168.844848","601","AS","RU","RU-CHU","Lamutskoye","no","","","UHAL","UHAL","","","УХАЛ, Ламутское"
"338091","RU-0543","small_airport","Tempa Airfield","75.76713","137.576637","3","EU","RU","RU-SA","Kotelny Island","no","","","","","","","Темп"
"6456","UHMA","medium_airport","Ugolny Yuri Ryktheu Airport","64.734902","177.740997","194","AS","RU","RU-CHU","Anadyr","yes","UHMA","DYR","UHMA","","","https://en.wikipedia.org/wiki/Ugolny_Airport","УХМА, Угольный, Аnadyr Airport, Аэропорт Анадырь"
"340795","RU-0605","small_airport","Uelkal Airstrip","65.530823","-179.287263","","EU","RU","RU-CHU","Uelkal","no","","","","","","",""
"340810","RU-0616","small_airport","Taymylyr Airstrip","72.607271","121.893179","","EU","RU","RU-SA","Taymylyr","no","","","","","","",""
"341832","RU-0676","small_airport","Ayanka Airport","63.709269","167.584196","295","AS","RU","RU-KAM","Ayanka","no","","","","","","",""
"346936","RU-0727","small_airport","Khailino Airport","60.95206","166.83801","180","AS","RU","RU-KAM","Khailino","no","","","","UHPF","","","УХПФ, Хаилино"
"42940","UHPA","small_airport","Ust-Pakhachi Airport","60.556587","169.107707","10","AS","RU","RU-KAM","Ust-Pakhachi","no","UHPA","","UHPA","UHPA","","https://en.wikipedia.org/wiki/Ust-Pakhachi_Airport","УХПА, Аэропорт Усть-Пахачи, Пахачи, Pakhachi"
"346939","RU-0730","small_airport","Sredny Pakhachi Airport","60.81718","169.07555","","AS","RU","RU-KAM","Sredny Pakhachi","no","","","","","","",""
"346948","RU-0738","small_airport","Garmanda Airport","62.18334","159.08894","","AS","RU","RU-MAG","Garmanda","no","","","","","","","UEVE"
"347894","RU-0753","small_airport","Zhilinda Airport","70.15387","113.91756","489","EU","RU","RU-SA","Zhilinda","no","","","","","","",""
"347895","RU-0754","small_airport","Ebelyakh Airport","70.88319","113.58159","387","EU","RU","RU-SA","Ebelyakh","no","","","","","","",""
"347902","RU-0760","small_airport","Yukta Airport","63.38788","105.65577","680","EU","RU","RU-KYA","Yukta","no","","","","","","",""
"347903","RU-0761","small_airport","Nakanno Airport","62.89988","108.44788","816","EU","RU","RU-IRK","Nakanno","no","","","","","","",""
"347904","RU-0762","small_airport","Khamakar Airport","61.989","108.17978","889","EU","RU","RU-IRK","Khamakar","no","","","","","","",""
"601237","RU-10132","small_airport","Yagodnoye Airfield","62.54574","149.52257","1646","AS","RU","RU-MAG","Yagodnoye","no","","","UHGE","","","","УХГЕ, Ягодное,"
"602171","RU-10134","small_airport","Valunistoe (airport)","66.421687","177.582464","","AS","RU","RU-CHU","Rudnik Valunisty","no","","","","","","",""
"602186","RU-10135","small_airport","Valunistoe Mining Complex Airport","66.766633","164.319284","999","AS","RU","RU-CHU","Vesenny","no","","","","","","",""
"602304","RU-10136","small_airport","Verkhnee Penzhino Airport","64.222657","164.244866","1093","AS","RU","RU-KAM","Penzhinsky District","no","","","","","","","Верхнее Пенжино"
"609963","RU-10173","small_airport","Stadukhino Airfield","66.965897","166.82135","1905","AS","RU","RU-CHU","Stadukhino","no","","","","ZC8P","","","ЗЦ8П, Стадукхино"
"34989","RU-2510","small_airport","Greem Bell Air Base","81.15","64.33","30","EU","RU","RU-ARK","Graham Bell Island","no","","","","XLDG","","https://en.wikipedia.org/wiki/Greem_Bell","Graham Bell Airbase, Аэродром Греэм Белл, Аэродром Грээм Белл, ЬЛДГ"
"39078","SAYE","small_airport","Esperanza Base","-63.400002","-56.983299","75","AN","AQ","AQ-U-A","Fortín Sargento Cabral","no","","","SAYE","BET","","https://en.wikipedia.org/wiki/Esperanza_Base",""
"5830","SAWB","small_airport","Gustavo Marambio Airport","-64.238297","-56.630798","760","AN","AQ","AQ-U-A","Marambio Base","no","","","SAWB","MBI","","https://en.wikipedia.org/wiki/Marambio_Airport",""
"39076","SAWZ","small_airport","Matienzo Airfield","-64.976998","-60.108992","75","AN","AQ","AQ-U-A","Matienzo Base","no","","","SAWZ","BTM","","",""
"39077","SAYB","small_airport","Base Belgrano II Airport","-77.874055","-34.62616","820","AN","AQ","AQ-U-A","Base Belgrano II","no","","","SAYB","BEB","","https://en.wikipedia.org/wiki/Belgrano_II_Base",""
"6039","SCRM","small_airport","Teniente Rodolfo Marsh Martin Airport","-62.191026","-58.98669","147","AN","AQ","AQ-U-A","Villa Las Estrellas","no","SCRM","TNM","SCRM","","","https://en.wikipedia.org/wiki/Teniente_R._Marsh_Airport",""
"39080","SAYS","small_airport","San Martín Base Airfield","-68.116699","-67.099998","75","AN","AQ","AQ-U-A","San Martín Base","no","","","SAYS","BSM","","https://en.wikipedia.org/wiki/San_Martin_Base",""
"308226","SCBO","small_airport","General Bernardo O'Higgins Base Skyway","-63.344","-57.842","900","AN","AQ","AQ-U-A","General Bernardo O'Higgins Base","no","","","SCBO","","","",""
"6021","SCFX","small_airport","Isla San Felix Airport","-26.2939","-80.096199","165","SA","CL","CL-AT","Isla San Felix","no","","","SCFX","","","https://en.wikipedia.org/wiki/Isla_San_Felix_Airport",""
"45059","SCGC","small_airport","Union Glacier Blue-Ice Runway","-79.777778","-83.320833","2461","AN","AQ","AQ-U-A","Union Glacier","no","SCGC","UGL","SCGC","","","https://en.wikipedia.org/wiki/Union_Glacier_Blue-Ice_Runway",""
"32268","SCPZ","small_airport","Patriot Hills Airport","-80.318307","-81.308128","2900","AN","AQ","AQ-U-A","Patriot Hills Base Camp","no","SCPZ","","SCPZ","","","https://es.wikipedia.org/wiki/Aer%C3%B3dromo_Patriot_Hills",""
"6055","SEGS","medium_airport","Seymour Galapagos Ecological Airport","-0.453758","-90.2659","207","SA","EC","EC-W","Isla Baltra","yes","SEGS","GPS","SEGS","","https://ecogal.aero/en/","https://en.wikipedia.org/wiki/Seymour_Airport",""
"41131","SEII","small_airport","General Villamil Airport","-0.942628","-90.953003","35","SA","EC","EC-W","Puerto Villamil","yes","SEII","IBB","SEII","","","",""
"32508","UEBN","small_airport","Nizhneyansk Airport","71.437822","136.189701","20","AS","RU","RU-SA","Nizhneyansk","no","","","UEBN","","","","Нижнея́нск"
"335165","UEKY","small_airport","Keng-Kyuyol Airport","68.076828","145.985126","","EU","RU","RU-SA","Keng-Kyuyol","no","","","UEKY","","","",""
"335179","UEMC","small_airport","Khatyngnakh Airport","67.489845","152.575679","","EU","RU","RU-SA","","no","","","UEMC","","","",""
"44597","UERO","small_airport","Olenyok Airport","68.514999","112.480003","847","AS","RU","RU-SA","Olenyok","no","","ONK","UERO","","","https://en.wikipedia.org/wiki/Olenyok_Airport","УЕРО, Olenek Airport, Аэропорт Оленёк, Аэропорт Оленек"
"44870","UERS","medium_airport","Saskylakh Airport","71.927902","114.080002","","AS","RU","RU-SA","Saskylakh","yes","UERS","SYS","UERS","","","https://en.wikipedia.org/wiki/Saskylakh_Airport","УЕРС, Аэропорт Саскылах"
"335193","UESC","small_airport","Berezovka Airport","67.120183","156.589766","","AS","RU","RU-SA","","no","","","UESC","","","","УЕСЦ, Берёзовка"
"43667","UESG","medium_airport","Belaya Gora Airport","68.556227","146.22784","118","AS","RU","RU-SA","Belaya Gora","no","UESG","BGN","UESG","","","https://en.wikipedia.org/wiki/Belaya_Gora_Airport","УЕСГ, Аэропорт Белая Гора"
"335194","UESH","small_airport","Argakhtakh Airport","68.443333","153.362222","65","AS","RU","RU-SA","Argakhtakh","no","","","UESH","","","","УЕСХ, Аргахтах"
"316761","UESK","medium_airport","Srednekolymsk Airport","67.4805","153.7364","60","AS","RU","RU-SA","Srednekolymsk","yes","","SEK","UESK","","","https://en.wikipedia.org/wiki/Srednekolymsk_Airport","УЕСК, Среднеколымск"
"335195","UESL","small_airport","Sylgy-Ytar Airport","67.848145","154.838862","164","AS","RU","RU-SA","","no","","","UESL","","","","УЕСЛ, Сылгы-Ытар"
"32514","UESO","medium_airport","Chokurdakh Airport","70.6231","147.901993","151","AS","RU","RU-SA","Chokurdah","yes","UESO","CKH","UESO","","","https://en.wikipedia.org/wiki/Chokurdakh_Airport","Chokurdah Airport, Cokurdah Airport, Аэропорт Чокурдах"
"335196","UESR","small_airport","Tumat Airport","70.72611","139.235833","","EU","RU","RU-SA","","no","","","UESR","","","",""
"30870","UESS","medium_airport","Cherskiy Airport","68.740601","161.337997","20","AS","RU","RU-SA","Cherskiy","yes","UESS","CYX","UESS","","","https://en.wikipedia.org/wiki/Chersky_Airport","УЕСС, Chersky Airport, Аэропорт Черский"
"6450","UEST","medium_airport","Tiksi Airport","71.697700500488","128.90299987793","26","AS","RU","RU-SA","Tiksi","yes","UEST","IKS","UEST","","","https://en.wikipedia.org/wiki/Tiksi_Airport","УЕСТ, Аеропорт Тикси"
"335197","UESV","small_airport","Svatay Airport","68.057338","151.79625","75","AS","RU","RU-SA","Svatay","no","","","UESW","","","","УЕСВ, Сватай"
"335198","UESX","small_airport","Aleko-Kyuyol Airport","68.676693","151.873798","82","AS","RU","RU-SA","","no","","","UESX","","","","УЕСЬ, Алеко-Кюель"
"335200","UESZ","small_airport","Kazachye Airport","70.746294","136.179271","","EU","RU","RU-SA","","no","","","UESZ","","","",""
"323629","UHAC","small_airport","Chuvanskoye Airport","65.172163","167.952484","644","AS","RU","RU-CHU","Chuvanskoye","no","","","UHAC","UHAC","","","УХАЦ, Чуванское"
"323630","UHAW","small_airport","Vayegi Airport","64.167442","171.057887","131","AS","RU","RU-CHU","Vayegi","no","","","UHAW","UHAW","","","УХАВ, Ваеги"
"324924","UHDW","small_airport","Vankarem Airport","67.838719","-175.8494283","3","EU","RU","RU-CHU","Vankarem","no","","","UHDW","","","","УХДВ, Ванкарем"
"530668","UHEI","small_airport","Ilirney Airport","67.255278","167.949167","1165","AS","RU","RU-CHU","","no","","","UHEI","","","",""
"525055","UHEK","small_airport","Kupol Airport","66.901667","169.56","1745","AS","RU","RU-CHU","","no","","","UHEK","","","https://en.wikipedia.org/wiki/Kupol_Airport",""
"596406","UHGL","small_airport","Glukharinoye Airfield","64.999872","153.096328","977","AS","RU","RU-MAG","Glukharinoye","no","","","UHGL","","","","УХГЛ, Глухариное, Глухариный"
"6457","UHMD","medium_airport","Provideniya Bay Airport","64.378098","-173.242996","72","AS","RU","RU-CHU","Chukotka","no","UHMD","PVS","UHMD","XHMD","","https://en.wikipedia.org/wiki/Provideniya_Bay_Airport","УХМД, ЬХМД, Bukhta Provideniya Airport, Urelik Airport, Ureliki Airport, Аэропорт Бухта Провидения, Аэропорт Урелики"
"43686","UHME","small_airport","Zaliv Kresta Airport","66.358398","-179.108393","22","AS","RU","RU-CHU","Egvekinot","no","","","UHME","","","","УХМЕ, Аэропорт Залив Креста"
"44659","UHMF","medium_airport","Omsukchan Airport","62.457001","155.744995","1732","AS","RU","RU-MAG","Omsukchan","yes","UHMF","","UHMF","","","https://en.wikipedia.org/wiki/Omsukchan_Airport","Аэропорт Омсукчан"
"35040","UHMI","small_airport","Mys Shmidta Airport","68.86808","-179.374183","20","AS","RU","RU-CHU","Mys Shmidta","no","UHMI","","UHMI","","","https://en.wikipedia.org/wiki/Mys_Shmidta_Airport","УХМИ, ЬХМИ, Мыс Шмидта"
"44473","UHMK","medium_airport","Keperveem Airport","67.845001","166.139999","623","AS","RU","RU-CHU","Keperveem","yes","UHMK","KPW","UHMK","","","https://en.wikipedia.org/wiki/Keperveyem_Airport","Keperveyem Airport, Аэропорт Кепервеем"
"42925","UHML","small_airport","Lavrentiya Airport","65.580426","-170.999177","30","AS","RU","RU-CHU","Lavrentiya","no","UHML","","UHML","","","https://en.wikipedia.org/wiki/Lavrentiya_Airport","УХМЛ, Залив Лаврентия, Lavrentiya Bay"
"44610","UHMN","small_airport","Omolon Airport","65.239998","160.539993","869","AS","RU","RU-CHU","Omolon","yes","UHMN","","UHMN","","","https://en.wikipedia.org/wiki/Omolon_Airport","УХМН, Аэропорт Омолон"
"44660","UHMO","small_airport","Markovo Airport","64.665446","170.417626","75","AS","RU","RU-CHU","Markovo","yes","UHMO","KVM","UHMO","","","https://en.wikipedia.org/wiki/Markovo_Airport","Аэропорт Марково"
"6459","UHMP","medium_airport","Pevek Airport","69.783302","170.597","11","AS","RU","RU-CHU","Apapelgino","yes","UHMP","PWE","UHMP","","","https://en.wikipedia.org/wiki/Pevek_Airport","УХМП, Аэропорт Певек"
"32518","UHMR","small_airport","Beringovskiy Airport","63.02","179.292999","3","AS","RU","RU-CHU","Beringovsky","no","UHMR","","UHMR","","","https://es.wikipedia.org/wiki/Aer%C3%B3dromo_de_Beringovski","УХМР, Аэропорт Беринговский"
"42963","UHMS","medium_airport","Seymchan Airport","62.92078","152.422775","679","AS","RU","RU-MAG","Seymchan","no","UHMS","","UHMS","","","https://en.wikipedia.org/wiki/Seymchan_Airport","УХМС, Аэропорт Сеймчан"
"324631","UHMZ","small_airport","Wrangel Island Airport","70.945356","-179.5","112","EU","RU","RU-CHU","Wrangel Island","no","","","UHMZ","UHMZ","","","УХМЗ, Остров Врангеля"
"339646","UHPN","small_airport","Manily Airport","62.485962","165.338917","33","AS","RU","RU-KAM","Manily","no","","","UHPN","","","",""
"597129","UHQE","small_airport","Slautnoye Airfield","63.176423","167.978281","","AS","RU","RU-KAM","Slautnoye","no","","","UHQE","","","","УХЯЕ, Слаутное"
"42926","UIKE","small_airport","Yerbogachen Airport","61.2750015259","108.029998779","400","AS","RU","RU-IRK","Erbogachen","no","UIKE","ERG","UIKE","","","https://en.wikipedia.org/wiki/Erbogachen_Airport","Yerbogachyon Airport, Erbogachyon Airport, Erbogachen Airport, Аэропорт Ербогачен, Аэропорт Ербогачён"
"43672","ULDW","small_airport","Varandey Airport","68.848503","58.201401","23","AS","RU","RU-NEN","Varandey","no","ULDW","VRI","ULDW","","","https://en.wikipedia.org/wiki/Varandey_Airport","УЛДВ, Varandei Airport, Аэропорт Варандей"
"315363","UODL","small_airport","Cape Chelyuskin Airfield","77.712","104.24","60","AS","RU","RU-KYA","Chelyuskin Polar Station","no","","","UODL","UODL","","","УОДЛ, Челюскин"
"35041","UODN","medium_airport","Nagurskoye Airfield","80.803207","47.663586","59","AS","RU","RU-ARK","Alexandra Land","no","UODN","","UODN","","","https://en.wikipedia.org/wiki/Nagurskoye",""
"35086","UODS","small_airport","Sredniy Island Air Base","79.52958","91.07495","26","AS","RU","RU-KYA","Khatanga","no","UODS","","UODS","XODS","","https://en.wikipedia.org/wiki/Sredny_Ostrov","УОДС, Sredniy Ostrov Air Base, Аэродром Средний Остров, ЬОДС"
"301864","US-0200","small_airport","Kogru River Airfield","70.574196","-152.259478","","NA","US","US-AK","Kogru","no","","","","A41","","",""
"340805","US-3039","small_airport","Brownlow Point Airport","69.979281","-144.834986","","NA","US","US-AK","Brownlow Point","no","","","","","","",""
"340807","US-3041","small_airport","Demarcation Bay Airfield","69.882551","-142.305616","","NA","US","US-AK","Nuvagapak Point","no","","","","","","","Nuvagapak Point"
"316465","WAN","small_airport","Waverney Airport","-25.356917","141.925593","570","OC","AU","AU-QLD","Waverney","no","","","","","","","WAN"
"354533","YABL","small_airport","Ambalindum Airport","-23.35187","134.732434","1966","OC","AU","AU-NT","Ambalindum","no","","","YABL","","","",""
"27317","YADO","small_airport","Andado Airport","-25.407772","135.290794","549","OC","AU","AU-NT","Ghan","no","","","YADO","","","",""
"38224","YALC","small_airport","Alcoota Station Airport","-22.801963","134.4036","1994","OC","AU","AU-NT","Alcoota","no","","","YALC","","","","Engawala"
"38226","YALM","small_airport","Allambie Airport","-24.265335","134.402927","","OC","AU","AU-NT","","no","","","YALM","","","",""
"38229","YAMM","small_airport","Ammaroo Airport","-21.738300323486328","135.24200439453125","","OC","AU","AU-NT","","no","","AMX","YAMM","","","",""
"27328","YAMT","small_airport","Amata Airport","-26.097363","131.202732","695","OC","AU","AU-SA","","no","YAMT","AMT","YAMT","","","https://en.wikipedia.org/wiki/Amata_Airport",""
"38230","YANJ","small_airport","Angatja Airport","-26.100000381469727","130.39999389648438","","OC","AU","AU-SA","","no","","","YANJ","","","",""
"38231","YANN","small_airport","Anningie Airport","-21.83169937133789","133.125","","OC","AU","AU-NT","","no","","","YANN","","","",""
"27332","YANW","small_airport","Annitowa Airport","-21.200017","136.451139","901","OC","AU","AU-NT","","no","","","YANW","","","",""
"27336","YARD","small_airport","Argadargada Airport","-21.676700592041016","136.67799377441406","","OC","AU","AU-NT","","no","","","YARD","","","",""
"27340","YARN","small_airport","Areyonga Airport","-24.091565","132.271228","","OC","AU","AU-NT","Mereenie","no","","","YARN","","","",""
"38232","YARP","small_airport","Arapunya Airport","-22.316699981689453","135.6999969482422","","OC","AU","AU-NT","","no","","","YARP","","","",""
"38233","YATL","small_airport","Atula Airport","-23.255344","136.388955","915","OC","AU","AU-NT","Anatye","no","","","YATL","","","",""
"26895","YAYE","medium_airport","Ayers Rock Connellan Airport","-25.185913","130.97703","1626","OC","AU","AU-NT","Yulara","yes","YAYE","AYQ","YAYE","","","https://en.wikipedia.org/wiki/Ayers_Rock_Airport","Ayers Rock, Uluru"
"26900","YBAS","medium_airport","Alice Springs Airport","-23.806588","133.903427","1789","OC","AU","AU-NT","Alice Springs","yes","YBAS","ASP","YBAS","","http://www.alicespringsairport.com.au/","https://en.wikipedia.org/wiki/Alice_Springs_Airport",""
"26907","YBDV","medium_airport","Birdsville Airport","-25.897499084472656","139.34800720214844","159","OC","AU","AU-QLD","","yes","YBDV","BVI","YBDV","","","https://en.wikipedia.org/wiki/Birdsville_Airport",""
"27369","YBEO","small_airport","Betoota Airport","-25.694791","140.738339","91","OC","AU","AU-QLD","","no","YBEO","BTX","YBEO","","","",""
"38256","YBRC","small_airport","Barrow Creek Airport","-21.542202","133.871959","","OC","AU","AU-NT","","no","","","YBRC","","","",""
"27416","YBSR","small_airport","Blackstone Airport","-25.9867000579834","128.28799438476562","","OC","AU","AU-WA","","no","","","YBSR","","","",""
"38278","YCCK","small_airport","Canteen Creek Airport","-20.650800704956055","135.5850067138672","","OC","AU","AU-NT","","no","","","YCCK","","","",""
"38293","YCNS","small_airport","Coniston Airport","-22.13330078125","132.5330047607422","","OC","AU","AU-NT","","no","","","YCNS","","","",""
"348022","YCSK","small_airport","Casey Station Skiway","-66.288056","110.7575","1178","AN","AQ","AQ-U-A","Casey Station","no","","","YCSK","","","https://en.wikipedia.org/wiki/Casey_Station",""
"38304","YCSP","small_airport","Curtin Springs Airport","-25.333921","131.759308","","OC","AU","AU-NT","","no","","","YCSP","","","",""
"38308","YCUD","small_airport","Cuddapan Airport","-25.59000015258789","141.50799560546875","","OC","AU","AU-QLD","","no","","","YCUD","","","",""
"38460","YMDS","small_airport","Macdonald Downs Airport","-22.444000244099996","135.199005127","","OC","AU","AU-NT","","no","YMDS","MNW","YMDS","","","",""
"27532","YDRI","small_airport","Durrie Airport","-25.684999465942383","140.22799682617188","58","OC","AU","AU-QLD","","no","YDRI","DRR","YDRI","","","",""
"38330","YDRL","small_airport","De Rose Hill Airport","-26.435838","133.259954","","OC","AU","AU-SA","De Rose Hill","no","","","YDRL","","","",""
"27535","YDVR","small_airport","Docker River Airport","-24.859533","129.122209","589","OC","AU","AU-NT","Kaltukatjara","no","YDVR","DKV","YDVR","","","",""
"38334","YDYD","small_airport","Derry Downs Airport","-22.08329963684082","135.33299255371094","","OC","AU","AU-NT","","no","","","YDYD","","","",""
"38338","YELK","small_airport","Elkedra Airport","-21.172500610399997","135.444000244","","OC","AU","AU-NT","","no","","EKD","YELK","","","",""
"38342","YEPR","small_airport","Epenarra Airport","-20.433300018310547","135.26699829101562","","OC","AU","AU-NT","","no","","","YEPR","","","",""
"38345","YERL","small_airport","Erldunda Airport","-25.206106","133.254161","","OC","AU","AU-NT","Ghan","no","","EDD","YERL","","","",""
"27554","YERN","small_airport","Ernabella Airport","-26.2632999420166","132.1820068359375","707","OC","AU","AU-SA","","no","YERN","ERB","YERN","","","",""
"27559","YEVP","small_airport","Everard Park Airport","-27.038988","132.688585","1615","OC","AU","AU-SA","Mimili","no","","","YEVP","","","",""
"31129","YFNE","small_airport","Finke Airport","-25.5946998596","134.582992554","","OC","AU","AU-NT","Finke","no","YFNE","FIK","YFNE","","","",""
"27566","YFRG","small_airport","Fregon Airport","-26.774999618530273","132.01699829101562","528","OC","AU","AU-SA","","no","","","YFRG","","","",""
"26985","YFRT","medium_airport","Forrest Airport","-30.83662","128.112811","511","OC","AU","AU-WA","","no","YFRT","FOS","YFRT","","","https://en.wikipedia.org/wiki/Forrest_Airport",""
"27631","YIDK","small_airport","Indulkana Airport","-26.965435","133.321989","401","OC","AU","AU-SA","Indulkana","no","YIDK","IDK","YIDK","","","",""
"27594","YGLE","small_airport","Glengyle Airport","-24.808300018310547","139.60000610351562","91","OC","AU","AU-QLD","","no","YGLE","GLG","YGLE","","","",""
"27599","YGLS","small_airport","Giles Airport","-25.043699","128.296005","579","OC","AU","AU-WA","Warakurna","no","","","YGLS","","","https://en.wikipedia.org/wiki/Giles_Airport",""
"27612","YHAA","small_airport","Haasts Bluff Airport","-23.454999923706","131.85299682617","2269","OC","AU","AU-NT","","no","","","YHAA","","","",""
"27619","YHKT","small_airport","Huckitta Airport","-22.943300247192383","135.44700622558594","","OC","AU","AU-NT","","no","","","YHKT","","","",""
"27621","YHMB","small_airport","Hermannsburg Airport","-23.926485","132.807798","593","OC","AU","AU-NT","Hermannsburg (Ntaria)","no","YHMB","HMG","YHMB","","","",""
"38390","YHSB","small_airport","Horseshoe Bend Airport","-25.216699600219727","134.26699829101562","","OC","AU","AU-NT","","no","","","YHSB","","","",""
"38394","YHTS","small_airport","Harts Range Airport","-22.985000610351562","134.91799926757812","","OC","AU","AU-NT","","no","","","YHTS","","","",""
"27632","YIDR","small_airport","Idracowra Airport","-25.06329917907715","133.73300170898438","","OC","AU","AU-NT","","no","","","YIDR","","","",""
"38396","YIKL","small_airport","Baikal Airport","-22.7632999420166","136.16299438476562","","OC","AU","AU-NT","","no","","","YIKL","","","",""
"27647","YJAM","small_airport","Jameson Airport","-25.850000381469727","127.68299865722656","","OC","AU","AU-WA","","no","","","YJAM","","","",""
"38407","YKCA","small_airport","Kings Canyon Airport","-24.260229","131.488924","2100","OC","AU","AU-NT","Petermann","no","YKCA","KBJ","YKCA","","","",""
"38425","YLBG","small_airport","Mount Liebig Airport","-23.24329948425293","131.25999450683594","","OC","AU","AU-NT","","no","","","YLBG","","","",""
"27719","YLGN","small_airport","Loongana Airport","-30.940771","127.028781","","OC","AU","AU-WA","","no","","","YLGN","","","",""
"27727","YLLC","small_airport","Lilla Creek Airport","-25.55791","134.07114","","OC","AU","AU-NT","","no","","","YLLC","","","",""
"38444","YLSY","small_airport","Mount Lindsay Airport","-27.018299102783203","129.88499450683594","","OC","AU","AU-SA","","no","","","YLSY","","","",""
"27749","YMAD","small_airport","Madura Airport","-31.887825","127.025573","","OC","AU","AU-WA","","no","","","YMAD","","","",""
"32730","YMBX","small_airport","Mundrabilla Airport","-31.86720085144043","127.85399627685547","120","OC","AU","AU-WA","Mundrabilla","no","","","YMBX","","","",""
"38455","YMBZ","small_airport","Mount Ebenezer Airport","-25.169763","132.643107","","OC","AU","AU-NT","","no","","","YMBZ","","","",""
"27763","YMDV","small_airport","Mount Davies Airport","-26.16670036315918","129.13299560546875","","OC","AU","AU-SA","","no","","","YMDV","","","",""
"27789","YMNK","small_airport","Monkira Airport","-24.816699981689453","140.5330047607422","107","OC","AU","AU-QLD","","no","YMNK","ONR","YMNK","","","",""
"27185","YYND","small_airport","Yuendumu Airport","-22.2542","131.781998","2205","OC","AU","AU-NT","","no","YYND","YUE","YYND","","","https://en.wikipedia.org/wiki/Yuendumu_Airport",""
"31943","YMQA","small_airport","Marqua Airport","-22.80579948425293","137.25100708007812","","OC","AU","AU-NT","Marqua","no","YMQA","MQE","YMQA","","","",""
"38495","YMSK","small_airport","Mount Skinner Airport","-22.187801","134.171648","","OC","AU","AU-NT","","no","","","YMSK","","","",""
"27812","YMTX","small_airport","Mount Dare Airport","-26.06170082092285","135.2469940185547","","OC","AU","AU-SA","","no","","","YMTX","","","",""
"38500","YMUP","small_airport","Mulga Park Airport","-25.860000610399997","131.649993896","","OC","AU","AU-NT","","no","YMUP","MUP","YMUP","","","",""
"27823","YMWE","small_airport","Mount Wedge Airport","-22.737199783325195","132.1510009765625","559","OC","AU","AU-NT","","no","","","YMWE","","","",""
"38507","YMYV","small_airport","Maryvale Airport","-24.647992","134.026358","","OC","AU","AU-NT","","no","","","YMYV","","","",""
"38508","YMYW","small_airport","Murray Downs Airport","-21.04829978942871","134.68299865722656","","OC","AU","AU-NT","","no","","","YMYW","","","",""
"38513","YNHV","small_airport","New Haven Airport","-22.728300094604492","131.14500427246094","","OC","AU","AU-NT","","no","","","YNHV","","","",""
"27850","YNRR","small_airport","Nyrripi Airport","-22.645299911499023","130.56500244140625","","OC","AU","AU-NT","","no","","","YNRR","","","",""
"38523","YNUE","small_airport","Numery Airport","-23.983299255371094","135.39999389648438","","OC","AU","AU-NT","","no","","","YNUE","","","",""
"38528","YNWT","small_airport","Narwietooma Airport","-23.228786","132.629378","","OC","AU","AU-NT","","no","","","YNWT","","","",""
"38535","YORA","small_airport","Moonerah Airport","-31.691413","126.590523","","OC","AU","AU-WA","","no","","","YORA","","","",""
"38537","YORT","small_airport","Ooratippra Airport","-21.905799865722656","136.06900024414062","","OC","AU","AU-NT","","no","","","YORT","","","",""
"354815","YPHS","small_airport","Pine Hill Station Airport","-22.386977","133.06025","2142","OC","AU","AU-NT","Anmatjere","no","","","YPHS","","","",""
"27924","YRNW","small_airport","Ringwood Airport","-23.82830047607422","134.96200561523438","","OC","AU","AU-NT","","no","","","YRNW","","","",""
"27991","YTIT","small_airport","Ti Tree Airport","-22.131701","133.419998","","OC","AU","AU-NT","","no","","","YTIT","","","https://en.wikipedia.org/wiki/Ti-Tree_Airfield",""
"38607","YTJU","small_airport","Tjuntjuntjarra Airport","-29.344938","127.107348","740","OC","AU","AU-WA","","no","","","YTJU","","","",""
"38609","YTLT","small_airport","Tarlton Downs Airport","-22.63330078125","136.8000030517578","","OC","AU","AU-NT","","no","","","YTLT","","","",""
"32491","YTMY","small_airport","Tobermorey Airport","-22.255800247192383","137.9530029296875","","OC","AU","AU-NT","Tobermorey","no","YTMY","TYP","YTMY","","","",""
"28014","YTYN","small_airport","Tieyon Airport","-26.216699600219727","133.91700744628906","","OC","AU","AU-SA","","no","","","YTYN","","","",""
"38623","YUMB","small_airport","Umbeara Airport","-25.746700286865234","133.70199584960938","","OC","AU","AU-NT","","no","","","YUMB","","","",""
"38625","YUTP","small_airport","Utopia Airport","-22.05500030517578","134.7899932861328","","OC","AU","AU-NT","","no","","","YUTP","","","",""
"38629","YVNS","small_airport","Vaughan Springs Airport","-22.33329963684082","130.86700439453125","","OC","AU","AU-NT","","no","","","YVNS","","","",""
"27165","YWBR","small_airport","Warburton Airport","-26.125538","126.583158","1500","OC","AU","AU-WA","Warburton","no","","","YWBR","","","https://en.wikipedia.org/wiki/Warburton_Airport",""
"302312","YWKS","small_airport","Wilkins Runway","-66.690833","111.523611","2529","AN","AQ","AQ-U-A","Preston Heath","no","","","YWKS","","","https://en.wikipedia.org/wiki/Wilkins_Runway",""
"38645","YWLA","small_airport","Willowra Airport","-21.27669906616211","132.6230010986328","","OC","AU","AU-NT","","no","","","YWLA","","","",""
"38647","YWLH","small_airport","Wallara Ranch Airport","-24.649999618530273","132.31700134277344","","OC","AU","AU-NT","","no","","","YWLH","","","",""
1 id ident type name latitude_deg longitude_deg elevation_ft continent iso_country iso_region municipality scheduled_service icao_code iata_code gps_code local_code home_link wikipedia_link keywords
11 610368 CA-1292 large_airport YEG 50.341652 -106.699219 2373 NA CA CA-AB Edmonton yes
12 1763 CYHM large_airport John C. Munro Hamilton International Airport 43.171308 -79.929416 780 NA CA CA-ON Hamilton yes CYHM YHM CYHM https://www.flyhi.ca/ https://en.wikipedia.org/wiki/Hamilton/John_C._Munro_International_Airport Mount Hope Airport
13 1770 CYHZ large_airport Halifax / Stanfield International Airport 44.8807983398 -63.5085983276 477 NA CA CA-NS Halifax yes CYHZ YHZ CYHZ http://www.hiaa.ca/ https://en.wikipedia.org/wiki/Halifax_International_Airport Robert L. Stanfield International Airport
14 1808 CYLW large_airport Kelowna International Airport 49.9561 -119.377998 1421 NA CA CA-BC Kelowna yes CYLW YLW CYLW http://www.kelowna.ca/CM/Page68.aspx https://ylw.kelowna.ca/ https://en.wikipedia.org/wiki/Kelowna_International_Airport Kelowna, Okanagan
15 1840 CYOW large_airport Ottawa Macdonald-Cartier International Airport 45.322498 -75.669197 374 NA CA CA-ON Ottawa yes CYOW YOW CYOW YOW https://yow.ca/ https://en.wikipedia.org/wiki/Ottawa_Macdonald%E2%80%93Cartier_International_Airport Uplands, UUP, CUUP
16 1864 CYQB large_airport Quebec Jean Lesage International Airport 46.7911 -71.393303 244 NA CA CA-QC Quebec yes CYQB YQB CYQB YQB http://www.aeroportdequebec.com/ https://en.wikipedia.org/wiki/Qu%C3%A9bec/Jean_Lesage_International_Airport Quebec City
17 1867 CYQG large_airport Windsor International Airport 42.2756 -82.955597 622 NA CA CA-ON Windsor yes CYQG YQG CYQG https://flyyqg.ca/ https://en.wikipedia.org/wiki/Windsor_Airport
1118 27241 ZYQQ large_airport Qiqihar Sanjiazi Airport 47.229969 123.914179 477 AS CN CN-23 Qiqihar yes ZYQQ NDG ZYQQ https://en.wikipedia.org/wiki/Qiqihar_Airport 齐齐哈尔, 齐齐哈尔三家子机场
1119 27242 ZYTL large_airport Dalian Zhoushuizi International Airport 38.965719 121.538477 107 AS CN CN-21 Dalian (Ganjingzi) yes ZYTL DLC ZYTL https://dlairport.com https://en.wikipedia.org/wiki/Dalian_Zhoushuizi_International_Airport Dalian Air Base
1120 27243 ZYTX large_airport Shenyang Taoxian International Airport 41.6398 123.483668 198 AS CN CN-21 Shenyang yes ZYTX SHE ZYTX https://en.wikipedia.org/wiki/Shenyang_Taoxian_International_Airport 沈阳, 沈阳桃仙国际机场
1121 16155 AK62 seaplane_base Naukati Bay Seaplane Base 55.849602 -133.227994 NA US US-AK Tuxekan Island yes NKI AK62 AK62 https://en.wikipedia.org/wiki/Naukati_Bay_Seaplane_Base 62A, Nichin Cove Seaplane Base, WNC
1122 8159 19P seaplane_base Port Protection Seaplane Base 56.3288 -133.610001 NA US US-AK Port Protection yes PPV 19P 19P https://en.wikipedia.org/wiki/Port_Protection_Seaplane_Base AK19
1123 9296 2AK8 small_airport Icy Cape Air Force Station Airport 70.293545 -161.907151 48 NA US US-AK Icy Cape no 2AK8 2AK8
1124 9902 2Z1 seaplane_base Entrance Island Seaplane Base 57.412201 -133.43848 0 NA US US-AK Entrance Island no HBH 2Z1
1125 5398 PAPG medium_airport Petersburg James A Johnson Airport 56.80170059 -132.9450073 111 NA US US-AK Petersburg yes PAPG PSG PAPG PSG https://en.wikipedia.org/wiki/Petersburg_James_A._Johnson_Airport
1126 5421 PAWG medium_airport Wrangell Airport 56.48429871 -132.3699951 49 NA US US-AK Wrangell yes PAWG WRG PAWG WRG https://en.wikipedia.org/wiki/Wrangell_Airport
1127 19240 KAE seaplane_base Kake Seaplane Base 56.973 -133.945999 NA US US-AK Kake yes KAE KAE https://en.wikipedia.org/wiki/Kake_Seaplane_Base
1128 14860 PABU small_airport Bullen Point Short Range Radar Station Airport 70.170999 -146.844897 18 NA US US-AK Kaktovik no PABU 8AK7 https://en.wikipedia.org/wiki/Bullen_Point_Short_Range_Radar_Site
1129 307366 EGAR small_airport Rothera Research Station -67.5675 -68.127403 9 AN AQ AQ-U-A Rothera Research Station no EGAR EGAR http://www.antarctica.ac.uk/living_and_working/research_stations/rothera/ https://en.wikipedia.org/wiki/Rothera_Research_Station
1130 5405 PASC medium_airport Deadhorse Airport 70.19470215 -148.4649963 65 NA US US-AK Deadhorse yes PASC SCC PASC SCC https://en.wikipedia.org/wiki/Deadhorse_Airport
1131 5401 PAQT medium_airport Nuiqsut Airport 70.209999 -151.005998 38 NA US US-AK Nuiqsut yes PAQT NUI PAQT AQT https://en.wikipedia.org/wiki/Nuiqsut_Airport 10AK
1132 312361 ANZ small_airport Angus Downs Airport -25.0325 132.2748 1724 OC AU AU-NT Angus Downs Station no ANZ YADN
1133 39579 AQ-0001 small_airport Novolazarevskaya Station -70.8461 11.8472 390 AN AQ AQ-U-A Queen Maud Land no AT17 https://en.wikipedia.org/wiki/Novolazarevskaya_Station
1134 42221 AQ-0002 small_airport Troll Airfield -71.95714 2.45257 4167 AN AQ AQ-U-A Troll Station no ENOE AT27 https://en.wikipedia.org/wiki/Troll_airfield
1135 336951 AQBC medium_airport Boulder Clay Runway -74.739373 164.03539 672 AN AQ AQ-U-A Zucchelli Station no AQBC https://en.wikipedia.org/wiki/Zucchelli_Station
1136 345862 AQ-0011 small_airport Wolfs Fang Runway -71.545026 8.798389 3707 AN AQ AQ-U-A no https://white-desert.com/about-us/wolfsfang-runway-logistics/ https://en.wikipedia.org/wiki/Wolfs_Fang_Runway AT98, Henrickson Nunatak, Queen Maud Land
1137 5054 NZSP medium_airport Amundsen–Scott South Pole Station Airport -90 -1 9300 AN AQ AQ-U-A Amundsen-Scott South Pole Station no NZSP NZSP https://en.wikipedia.org/wiki/Amundsen-Scott_South_Pole_Station
1138 603000 AQ-0016 medium_airport Grandfather Skiway -77.530242 -31.827393 AN AQ AQ-U-A Antartica no
1139 336953 AT03 medium_airport Concordia Skyway -75.103278 123.35825 10725 AN AQ AQ-U-A Concordia Station no AT03 https://en.wikipedia.org/wiki/Concordia_Station
1140 330063 AT25 small_airport Showa Station Skiway -69.006167 39.59 95 AN AQ AQ-U-A Showa Station no AT25 https://en.wikipedia.org/wiki/Showa_Station_(Antarctica) Syowa Station
1141 336959 AT28 medium_airport Vostok Skiway -78.466139 106.84825 11447 AN AQ AQ-U-A Vostok Station no AT28 https://en.wikipedia.org/wiki/Vostok_Station
1142 333856 AU-0112 small_airport Aileron Airstrip -22.652908 133.347244 2186 OC AU AU-NT Anmatjere no YALR
1143 351706 AU-0272 small_airport Planet Downs OS -25.872662 141.116788 OC AU AU-QLD Planet downs OS no
1144 352795 AU-0345 small_airport Hamilton Downs Airstrip -23.507335 133.260577 OC AU AU-NT Burt Plain no
1145 27846 YNPB small_airport Napperby Airport -22.5312 132.7632 2135 OC AU AU-NT Napperby no NPP YNPB
1146 27793 YMNY small_airport Morney Airport -25.358299255371094 141.43299865722656 104 OC AU AU-QLD no YMNY OXY YMNY
1147 507903 AU-0571 small_airport Lake MacKay Airstrip -23.670782 129.976158 OC AU AU-NT Lake MacKay no
1148 508151 AU-0586 small_airport homestead -23.317075 138.587637 OC AU AU-NT Sturt QLD 4829 no
1149 38379 YHBY small_airport Henbury Airport -24.584 133.236 OC AU AU-NT Ghan no YHBY HRY YHBY
1150 31745 AU-KGR small_airport Kulgera Airport -25.8428 133.292007 OC AU AU-NT Ghan no KGR
1151 44051 BGDH small_airport Danmarkshavn Landing Strip 76.76667 -18.666668 NA GL GL-NE Danmarkshavn no BGDH
1152 299843 BGMI small_airport Station Nord Landing Strip 81.601292 -16.679306 35 NA GL GL-NE Station Nord no BGMI https://en.wikipedia.org/wiki/Nord,_Greenland
1153 32004 BGQQ medium_airport Qaanaaq Airport 77.488602 -69.388702 51 NA GL GL-AV Qaanaaq yes BGQQ NAQ BGQQ https://en.wikipedia.org/wiki/Qaanaaq_Airport Mittarfik Qaanaaq, Thule
1154 116 BGTL medium_airport Pituffik Space Base 76.53063 -68.700541 251 NA GL GL-AV Pituffik no BGTL THU BGTL https://en.wikipedia.org/wiki/Pituffik_Space_Base Thule Air Base
1155 874 CEM3 small_airport Whatì Airport 63.131699 -117.246002 882 NA CA CA-NT Whatì yes YLE CEM3 CEM3 https://en.wikipedia.org/wiki/What%C3%AC_Airport EM3, Lac la Martre, Wha Ti
1156 299911 CA-0504 small_airport Mary River Aerodrome 71.324167 -79.356944 584 NA CA CA-NU Mary River no YMV CMR2 https://en.wikipedia.org/wiki/Mary_River_Aerodrome
1157 316098 CA-0551 seaplane_base Cameron Bay Water Aerodrome 66.06 -117.89 512 NA CA CA-NT Cameron Bay no EA7
1158 316114 CA-0554 seaplane_base Clarence Lagoon Water Aerodrome 69.62 -140.81 0 NA CA CA-YT no EC7
1159 316197 CA-0556 seaplane_base Boffa Lake Water Aerodrome 69.637 -116.196 338 NA CA CA-NU no EX6
1160 342506 CA-0737 small_airport Seal River Airstrip 59.154598 -94.785554 20 NA CA CA-MB Churchill no
1161 342507 CA-0738 small_airport Nester One Airstrip 58.6529 -93.19061 26 NA CA CA-MB Churchill no
1162 723 CBU2 small_airport Eddontenajon / Iskut Village Airport 57.847994155 -129.983968735 3100 NA CA CA-BC Eddontenajon no CBU2 CBU2 https://en.wikipedia.org/wiki/Eddontenajon/Iskut_Village_Airport BU2
1163 349351 CA-0771 small_airport Arctic Watch Lodge Airport 74.065757 -93.785965 NA CA CA-NU Somerset Island no CRW4 RW4 https://en.wikipedia.org/wiki/Arctic_Watch_Lodge_Aerodrome
1164 430490 CA-0815 small_airport Nuskenford Airstrip 69.863861 -126.843167 NA CA CA-NT Nuskenford no
1165 524817 CA-0924 seaplane_base Herschel Island Water Aerodrome 69.572 -138.93 0 NA CA CA-YT Herschel no EG8
1166 595702 CA-1179 small_airport Cassiar Aerodrome 59.277137 -129.805044 3618 NA CA CA-BC Cassiar no AU9
1167 606385 CA-1249 small_airport Fort Conger Airstrip 81.754925 -64.824958 15 NA CA CA-NU Qikiqtaaluk Region no CA1249 FCON
1168 606387 CA-1250 small_airport Lake Hazen Airstrip 81.823025 -71.360321 10 NA CA CA-NU Qikiqtaaluk Region no CA1250 LHAZ
1169 606493 CA-1251 small_airport McGill Arctic Research Station (MARS) 79.41596 -90.761018 NA CA CA-NU Axel Heiberg Island no
1170 607046 CA-1252 small_airport Ward Hunt Island Airport 83.091029 -74.138317 NA CA CA-NU Qikiqtaaluk Region no CA1252 https://en.wikipedia.org/wiki/Ward_Hunt_Island
1171 609524 CA-1259 small_airport Bathurst Inlet Airport 66.836865 -108.011278 36 NA CA CA-NU Bathurst Inlet/Qingaut no ᕿᙵᐅᓐ
1172 28437 CAH9 seaplane_base Telegraph Creek Seaplane Base 57.9071 -131.18946 1129 NA CA CA-BC Telegraph Creek no CAH9 CAH9 https://en.wikipedia.org/wiki/Telegraph_Creek_Water_Aerodrome AH9
1173 665 CBC2 small_airport Ford Bay Airport 66.0374984741211 -124.71499633789062 673 NA CA CA-NT Ford Bay no CBC2 CBC2 https://en.wikipedia.org/wiki/Ford_Bay_Airport BC2
1174 672 CBD6 small_airport Nahanni Butte Airport 61.029701232910156 -123.38899993896484 600 NA CA CA-NT Nahanni Butte no CBD6 CBD6 https://en.wikipedia.org/wiki/Nahanni_Butte_Airport BD6
1175 686 CBH4 small_airport Prairie Creek Airport 61.564701080322266 -124.81500244140625 2950 NA CA CA-NT Prairie Creek no CBH4 CBH4 https://en.wikipedia.org/wiki/Prairie_Creek_Airport BH4
1176 736 CBX5 small_airport Tungsten (Cantung) Airport 61.956901550293 -128.20300292969 3500 NA CA CA-NT Tungsten no TNS CBX5 CBX5 https://en.wikipedia.org/wiki/Tungsten_(Cantung)_Airport BX5
1177 814 CDK2 small_airport Diavik Airport 64.5113983154 -110.289001465 1413 NA CA CA-NT Diavik no DVK CDK2 CDK2 https://en.wikipedia.org/wiki/Diavik_Airport DK2
1178 43879 CDL7 small_airport Doris Lake 68.1252746582 -106.585281372 50 NA CA CA-NU Hope Bay no JOJ CDL7 https://en.wikipedia.org/wiki/Doris_Lake_Aerodrome
1179 1802 CYLK small_airport Lutselk'e Airport 62.417823 -110.682793 596 NA CA CA-NT Lutselk'e yes CYLK YSG CYLK https://en.wikipedia.org/wiki/Lutselk'e_Airport YLK, EL3, Snowdrift Airport
1180 314953 CYVL small_airport Tommy Kochon Airport 67.02015 -126.128364 870 NA CA CA-NT Colville Lake yes CYVL YCK CYVL https://en.wikipedia.org/wiki/Colville_Lake/Tommy_Kochon_Aerodrome
1181 925 CFA7 small_airport Taltheilei Narrows Airport 62.5980987549 -111.542999268 570 NA CA CA-NT Taltheilei Narrows no GSL CFA7 CFA7 https://en.wikipedia.org/wiki/Taltheilei_Narrows_Airport FA7
1182 1726 CYEV medium_airport Inuvik Mike Zubko Airport 68.30419921880001 -133.483001709 224 NA CA CA-NT Inuvik yes CYEV YEV CYEV https://en.wikipedia.org/wiki/Inuvik_(Mike_Zubko)_Airport
1183 1868 CYQH medium_airport Watson Lake Airport 60.116839 -128.821993 2255 NA CA CA-YT Watson Lake yes CYQH YQH CYQH https://en.wikipedia.org/wiki/Watson_Lake_Airport
1184 1948 CYWJ small_airport Déline Airport 65.211098 -123.435997 703 NA CA CA-NT Déline yes CYWJ YWJ CYWJ https://en.wikipedia.org/wiki/Deline_Airport Délı̨nę, Fort Franklin
1185 1993 CYZF medium_airport Yellowknife International Airport 62.462799 -114.440002 675 NA CA CA-NT Yellowknife yes CYZF YZF CYZF https://www.inf.gov.nt.ca/en/services/airports/yellowknife-airport https://en.wikipedia.org/wiki/Yellowknife_Airport
1186 28331 CEP9 seaplane_base Namushka Lodge Seaplane Base 62.416698 -113.349998 670 NA CA CA-NT no CEP9 CEP9 https://en.wikipedia.org/wiki/Namushka_Lodge_Water_Aerodrome EP9
1187 1786 CYKD small_airport Aklavik/Freddie Carmichael Airport 68.223297 -135.00599 23 NA CA CA-NT Aklavik yes CYKD LAK CYKD https://en.wikipedia.org/wiki/Aklavik_Airport YKD
1188 28159 CES6 seaplane_base Arctic Red River Seaplane Base 67.449997 -133.75 20 NA CA CA-NT no ES6 https://en.wikipedia.org/wiki/Arctic_Red_River_Water_Aerodrome
1189 944 CFF4 small_airport Great Bear Lake Airport 66.703053 -119.716816 562 NA CA CA-NT Great Bear Lake no DAS CFF4 CFF4 https://en.wikipedia.org/wiki/Great_Bear_Lake_Airport FF4
1190 1737 CYFS medium_airport Fort Simpson Airport 61.76020050048828 -121.23699951171875 555 NA CA CA-NT Fort Simpson yes CYFS YFS CYFS https://en.wikipedia.org/wiki/Fort_Simpson_Airport
1191 901 CET9 small_airport Jean Marie River Airport 61.522449 -120.625334 470 NA CA CA-NT Jean Marie River no CET9 CET9 https://en.wikipedia.org/wiki/Jean_Marie_River_Airport ET9
1192 1940 CYVQ medium_airport Norman Wells Airport 65.28160095214844 -126.7979965209961 238 NA CA CA-NT Norman Wells yes CYVQ YVQ CYVQ https://en.wikipedia.org/wiki/Norman_Wells_Airport
1193 909 CEV9 small_airport Snare River Airport 63.4333 -116.174963 700 NA CA CA-NT Snare River no CEV9 CEV9 https://en.wikipedia.org/wiki/Snare_River_Airport EV9
1194 1843 CYPC small_airport Paulatuk (Nora Aliqatchialuk Ruben) Airport 69.360838 -124.07547 15 NA CA CA-NT Paulatuk yes CYPC YPC CYPC https://en.wikipedia.org/wiki/Paulatuk_Airport
1195 933 CFC4 small_airport Macmillan Pass Airport 63.181098938 -130.20199585 3810 NA CA CA-YT Macmillan Pass no XMP CFC4 CFC4 https://en.wikipedia.org/wiki/Macmillian_Pass_Airport FC4
1196 996 CFT3 small_airport Finlayson Lake Airport 61.6913986206 -130.774002075 3094 NA CA CA-YT Finlayson Lake no CFT3 CFT3 https://en.wikipedia.org/wiki/Finlayson_Lake_Airport FT3
1197 997 CFT5 small_airport Hyland Airport 61.52389907836914 -128.2689971923828 3000 NA CA CA-YT Hyland no CFT5 CFT5 https://en.wikipedia.org/wiki/Hyland_Airport FT5
1198 28459 CFV5 seaplane_base Virginia Falls Seaplane Base 61.607575 -125.756272 1702 NA CA CA-NT no CFV5 CFV5 https://en.wikipedia.org/wiki/Virginia_Falls_Water_Aerodrome
1199 1021 CFY5 small_airport Pine Lake 60.10309982299805 -130.9340057373047 3250 NA CA CA-YT Pine Lake no CFY5 CFY5 https://en.wikipedia.org/wiki/Daughney_Aerodrome FY5
1200 44373 CGK2 small_airport Gahcho Kue 63.435198 -109.144812 1371 NA CA CA-NT Kennedy Lake no GHK CGK2 CGK2 https://en.wikipedia.org/wiki/Gahcho_Kue_Aerodrome De Beers Canada
1201 308297 CGR3 small_airport George Lake Aerodrome 65.928056 -107.462222 1150 NA CA CA-NU no CGR3 CGR3 https://en.wikipedia.org/wiki/George_Lake_Aerodrome
1202 308296 CGS2 small_airport Goose Lake Aerodrome 65.552778 -106.433611 907 NA CA CA-NU no CGS2 CGS2 https://en.wikipedia.org/wiki/Goose_Lake_Aerodrome
1203 308295 CHC5 small_airport Hayes Camp Aerodrome 66.661012 -91.55346 780 NA CA CA-NU no CHC5 CHC5 https://en.wikipedia.org/wiki/Hayes_Camp_Aerodrome
1204 1685 CYCB medium_airport Cambridge Bay Airport 69.1081008911 -105.138000488 90 NA CA CA-NU Cambridge Bay yes CYCB YCB CYCB https://en.wikipedia.org/wiki/Cambridge_Bay_Airport
1205 1674 CYBK medium_airport Baker Lake Airport 64.29889678960001 -96.077796936 59 NA CA CA-NU Baker Lake yes CYBK YBK CYBK https://en.wikipedia.org/wiki/Baker_Lake_Airport
1206 28228 CJN8 seaplane_base Fort Reliance Seaplane Base 62.7 -109.167 514 NA CA CA-NT Fort Reliance no YFL CJN8 CJN8 https://en.wikipedia.org/wiki/Fort_Reliance_Water_Aerodrome JN8
1207 1111 CJQ6 small_airport Tanquary Fiord Airport 81.409422 -76.867901 50 NA CA CA-NU Tanquary Fiord no CJQ6 CJQ6 https://en.wikipedia.org/wiki/Tanquary_Fiord_Airport JQ6
1208 299180 CMB2 small_airport Meadowbank Airport 65.0246615457 -96.06865882870001 475 NA CA CA-NU Agnico-Eagle Meadowbank Gold Mine no CMB2 CMB2 https://en.wikipedia.org/wiki/Meadowbank_Aerodrome
1209 1308 CNH2 small_airport Natuashish Airport 55.913898 -61.184399 30 NA CA CA-NL Natuashish yes YNP CNH2 CNH2 https://en.wikipedia.org/wiki/Natuashish_Airport NH2
1210 1486 CRE2 small_airport Edzo Airport 62.766701 -116.084 587 NA CA CA-NT Rae-Edzo no CRE2 CRE2 https://en.wikipedia.org/wiki/Rae/Edzo_Airport RE2
1211 1718 CYEK small_airport Arviat Airport 61.0942 -94.070801 32 NA CA CA-NU Arviat yes CYEK YEK CYEK https://en.wikipedia.org/wiki/Arviat_Airport
1212 1531 CSK6 small_airport Snap Lake Airport 63.593601 -110.905998 1557 NA CA CA-NT Snap Lake Mine no YNX https://en.wikipedia.org/wiki/Snap_Lake_Airport CSK6
1213 316099 CTM7 small_airport Tundra Mine/Salamita Mine Aerodrome 64.0725 -111.158 1445 NA CA CA-NT Tundra and Salamita Mines no CTM7 CTM7 https://en.wikipedia.org/wiki/Tundra_Mine/Salamita_Mine_Aerodrome
1214 1608 CTP9 small_airport Donaldson Airport 61.662201 -73.321404 1902 NA CA CA-QC Kattiniq no YAU CTP9 CTP9 https://en.wikipedia.org/wiki/Kattiniq/Donaldson_Airport
1215 1712 CYDP small_airport Nain Airport 56.550778 -61.682224 22 NA CA CA-NL Nain yes CYDP YDP CYDP https://en.wikipedia.org/wiki/Nain_Airport
1216 300457 CWJC small_airport Ennadai Lake Airport 61.1333333333 -100.9 1021 NA CA CA-NU Ennadai no CWJC
1217 46596 CYAB small_airport Arctic Bay Airport 73.006101 -85.04616 72 NA CA CA-NU Arctic Bay yes CYAB YAB CYAB https://en.wikipedia.org/wiki/Arctic_Bay_Airport CJX7
1218 1659 CYAS small_airport Kangirsuk Airport 60.027199 -69.999199 403 NA CA CA-QC Kangirsuk yes CYAS YKG CYAS https://en.wikipedia.org/wiki/Kangirsuk_Airport YAS
1219 1668 CYBB small_airport Kugaaruk Airport 68.535711 -89.805508 56 NA CA CA-NU Kugaaruk yes CYBB YBB CYBB https://en.wikipedia.org/wiki/Kugaaruk_Airport YBB, Pelly Bay Townsite Airport
1220 1693 CYCO small_airport Kugluktuk Airport 67.816408 -115.14307 74 NA CA CA-NU Kugluktuk yes CYCO YCO CYCO https://en.wikipedia.org/wiki/Kugluktuk_Airport Copper Mine Airport
1221 1697 CYCS small_airport Chesterfield Inlet Airport 63.346901 -90.731102 32 NA CA CA-NU Chesterfield Inlet yes CYCS YCS CYCS https://en.wikipedia.org/wiki/Chesterfield_Inlet_Airport
1222 353838 CYD2 seaplane_base Yellow Dog Lodge Seaplane Base 62.890556 -113.867778 725 NA CA CA-NT Graham Lake no CYD2 CYD2 https://yellowdoglodge.ca/ https://en.wikipedia.org/wiki/Graham_Lake_(Yellow_Dog_Lodge)_Water_Aerodrome
1223 1708 CYDL small_airport Dease Lake Airport 58.422199 -130.031998 2600 NA CA CA-BC Dease Lake yes CYDL YDL CYDL https://en.wikipedia.org/wiki/Dease_Lake_Airport YDL
1224 1725 CYEU small_airport Eureka Airport 79.9946975708 -85.814201355 256 NA CA CA-NU Eureka no CYEU YEU CYEU https://en.wikipedia.org/wiki/Eureka_Aerodrome YEU
1225 1742 CYGH small_airport Fort Good Hope Airport 66.240658 -128.647757 268 NA CA CA-NT Fort Good Hope yes CYGH YGH CYGH https://en.wikipedia.org/wiki/Fort_Good_Hope_Airport
1226 1750 CYGT small_airport Igloolik Airport 69.3647 -81.816101 174 NA CA CA-NU Igloolik yes CYGT YGT CYGT https://en.wikipedia.org/wiki/Igloolik_Airport
1227 1752 CYGW medium_airport Kuujjuarapik Airport 55.281898498535156 -77.76529693603516 34 NA CA CA-QC Kuujjuarapik yes CYGW YGW CYGW https://en.wikipedia.org/wiki/Kuujjuarapik_Airport
1228 1754 CYGZ small_airport Grise Fiord Airport 76.425823 -82.908583 146 NA CA CA-NU Grise Fiord yes CYGZ YGZ CYGZ https://en.wikipedia.org/wiki/Grise_Fiord_Airport
1229 1761 CYHI small_airport Ulukhaktok Holman Airport 70.762802 -117.806 117 NA CA CA-NT Ulukhaktok yes CYHI YHI CYHI https://en.wikipedia.org/wiki/Ulukhaktok/Holman_Airport
1230 1762 CYHK small_airport Gjoa Haven Airport 68.635597 -95.849701 152 NA CA CA-NU Gjoa Haven yes CYHK YHK CYHK https://en.wikipedia.org/wiki/Gjoa_Haven_Airport
1231 1765 CYHO small_airport Hopedale Airport 55.448757 -60.228124 39 NA CA CA-NL Hopedale yes CYHO YHO CYHO https://en.wikipedia.org/wiki/Hopedale_Airport CC5
1232 1774 CYIK small_airport Ivujivik Airport 62.417301 -77.925301 126 NA CA CA-QC Ivujivik yes CYIK YIK CYIK https://en.wikipedia.org/wiki/Ivujivik_Airport
1233 1775 CYIO small_airport Pond Inlet Airport 72.689494 -77.968941 181 NA CA CA-NU Pond Inlet yes CYIO YIO CYIO https://en.wikipedia.org/wiki/Pond_Inlet_Airport
1234 1788 CYKG small_airport Kangiqsujuaq (Wakeham Bay) Airport 61.5886 -71.929398 501 NA CA CA-QC Kangiqsujuaq yes CYKG YWB CYKG https://en.wikipedia.org/wiki/Kangiqsujuaq_(Wakeham_Bay)_Airport
1235 1791 CYKO small_airport Akulivik Airport 60.8186 -78.148598 75 NA CA CA-QC Akulivik yes CYKO AKV CYKO https://en.wikipedia.org/wiki/Akulivik_Airport YKO
1236 1796 CYLA small_airport Aupaluk Airport 59.2967 -69.599701 119 NA CA CA-QC Aupaluk yes CYLA YPJ CYLA https://en.wikipedia.org/wiki/Aupaluk_Airport YLA
1237 1806 CYLT medium_airport Alert Airport 82.517263 -62.283037 100 NA CA CA-NU Alert no CYLT YLT CYLT https://en.wikipedia.org/wiki/Alert_Airport YLT
1238 1818 CYMU small_airport Umiujaq Airport 56.536098 -76.518303 250 NA CA CA-QC Umiujaq yes CYMU YUD CYMU https://en.wikipedia.org/wiki/Umiujaq_Airport YMU
1239 1847 CYPH small_airport Inukjuak Airport 58.471901 -78.076897 83 NA CA CA-QC Inukjuak yes CYPH YPH CYPH https://en.wikipedia.org/wiki/Inukjuak_Airport
1240 1860 CYPX medium_airport Puvirnituq Airport 60.050598 -77.286903 74 NA CA CA-QC Puvirnituq yes CYPX YPX CYPX https://en.wikipedia.org/wiki/Puvirnituq_Airport
1241 1884 CYRA small_airport Rae Lakes Airport 64.116096 -117.309998 723 NA CA CA-NT Gamètì yes CYRA YRA CYRA https://en.wikipedia.org/wiki/Gam%C3%A8t%C3%AC/Rae_Lakes_Airport
1242 1885 CYRB medium_airport Resolute Bay Airport 74.7169036865 -94.9693984985 215 NA CA CA-NU Resolute Bay yes CYRB YRB CYRB https://en.wikipedia.org/wiki/Resolute_Bay_Airport
1243 1895 CYRT medium_airport Rankin Inlet Airport 62.8114013672 -92.1157989502 94 NA CA CA-NU Rankin Inlet yes CYRT YRT CYRT https://en.wikipedia.org/wiki/Rankin_Inlet_Airport
1244 1905 CYSK small_airport Sanikiluaq Airport 56.536891 -79.250221 104 NA CA CA-NU Sanikiluaq yes CYSK YSK CYSK https://en.wikipedia.org/wiki/Sanikiluaq_Airport
1245 1915 CYSY small_airport Sachs Harbour (David Nasogaluak Jr. Saaryuaq) Airport 71.993896 -125.242996 282 NA CA CA-NT Sachs Harbour yes CYSY YSY CYSY https://en.wikipedia.org/wiki/Sachs_Harbour_Airport
1246 1918 CYTE small_airport Cape Dorset Airport 64.230003 -76.526703 164 NA CA CA-NU Kinngait yes CYTE YTE CYTE https://en.wikipedia.org/wiki/Cape_Dorset_Airport
1247 1923 CYTQ small_airport Tasiujaq Airport 58.667801 -69.955803 122 NA CA CA-QC Tasiujaq yes CYTQ YTQ CYTQ https://en.wikipedia.org/wiki/Tasiujaq_Airport
1248 1927 CYUB small_airport Tuktoyaktuk / James Gruben Airport 69.433296 -133.026001 15 NA CA CA-NT Tuktoyaktuk no CYUB YUB CYUB https://en.wikipedia.org/wiki/Tuktoyaktuk/James_Gruben_Airport
1249 1929 CYUT small_airport Naujaat Airport 66.521024 -86.225166 80 NA CA CA-NU Repulse Bay yes CYUT YUT CYUT https://en.wikipedia.org/wiki/Repulse_Bay_Airport Repulse Bay Airport
1250 1930 CYUX medium_airport Hall Beach Airport 68.7761 -81.2425 30 NA CA CA-NU Sanirajak yes CYUX YUX CYUX https://en.wikipedia.org/wiki/Hall_Beach_Airport
1251 1939 CYVP medium_airport Kuujjuaq Airport 58.096099853515625 -68.4269027709961 129 NA CA CA-QC Kuujjuaq yes CYVP YVP CYVP https://en.wikipedia.org/wiki/Kuujjuaq_Airport
1252 954 CYWE small_airport Wekweètì Airport 64.190804 -114.077002 1208 NA CA CA-NT Wekweètì yes CYWE YFJ CYWE CFJ7 https://en.wikipedia.org/wiki/Wekwe%C3%A8t%C3%AC_Airport Wekweti, Snare Lake
1253 1954 CYWY medium_airport Wrigley Airport 63.20940017700195 -123.43699645996094 489 NA CA CA-NT Wrigley no CYWY YWY CYWY https://en.wikipedia.org/wiki/Wrigley_Airport
1254 1962 CYXN small_airport Whale Cove Airport 62.240002 -92.598099 40 NA CA CA-NU Whale Cove yes CYXN YXN CYXN https://en.wikipedia.org/wiki/Whale_Cove_Airport
1255 1978 CYYH small_airport Taloyoak Airport 69.5467 -93.576698 92 NA CA CA-NU Taloyoak yes CYYH YYH CYYH https://en.wikipedia.org/wiki/Taloyoak_Airport Spence Bay
1256 1984 CYYQ medium_airport Churchill Airport 58.739200592041016 -94.06500244140625 94 NA CA CA-MB Churchill yes CYYQ YYQ CYYQ https://en.wikipedia.org/wiki/Churchill_Airport
1257 1994 CYZG small_airport Salluit Airport 62.179401 -75.667198 743 NA CA CA-QC Salluit yes CYZG YZG CYZG https://en.wikipedia.org/wiki/Salluit_Airport
1258 1998 CYZS medium_airport Coral Harbour Airport 64.1932983398 -83.3593978882 210 NA CA CA-NU Coral Harbour yes CYZS YZS CYZS https://en.wikipedia.org/wiki/Coral_Harbour_Airport
1259 2017 CZFM small_airport Fort Mcpherson Airport 67.406993 -134.860182 116 NA CA CA-NT Fort Mcpherson yes CZFM ZFM CZFM https://en.wikipedia.org/wiki/Fort_McPherson_Airport
1260 2018 CZFN small_airport Tulita Airport 64.909496 -125.570297 332 NA CA CA-NT Tulita yes CZFN ZFN CZFN https://en.wikipedia.org/wiki/Tulita_Airport Fort Norman
1261 307365 EGAH small_airport Halley Research Station -75.567406 -25.516435 103 AN AQ AQ-U-A Halley Research Station no EGAH EGAH https://en.wikipedia.org/wiki/Halley_Research_Station Halley, Antarctica, British Antarctic Survey
1262 324046 EGAT small_airport Sky Blu Airstrip -74.849722 -71.566666 4740 AN AQ AQ-U-A Sky Blu no EGAT EGAT https://www.bas.ac.uk/polar-operations/sites-and-facilities/facility/rothera/sky-blu/ https://en.wikipedia.org/wiki/Sky_Blu
1263 31004 ENAS small_airport Ny-Ålesund Airport, Hamnerabben 78.927498 11.8743 50 EU NO NO-21 Ny-Ålesund no ENAS https://en.wikipedia.org/wiki/Ny-%C3%85lesund_Airport,_Hamnerabben Brøggerhalvøya Airport
1264 2877 FHAW medium_airport RAF Ascension Island -7.970179 -14.392744 278 AF SH SH-AC Cat Hill yes FHAW ASI FHAW https://www.raf.mod.uk/our-organisation/stations/ascension-island-base/ https://en.wikipedia.org/wiki/RAF_Ascension_Island Wideawake Airfield, Ascension Island Auxiliary Field
1265 318444 FHSH medium_airport Saint Helena International Airport -15.958898 -5.646066 1017 AF SH SH-SH Jamestown yes FHSH HLE FHSH http://sthelenaairport.com/ https://en.m.wikipedia.org/wiki/Saint_Helena_Airport#
1266 44073 GL-0006 small_airport Summit Ice Landing Strip 72.616669 -38.5 10523 NA GL GL-NE Summit Camp no https://en.wikipedia.org/wiki/Summit_Camp SUMUD
1267 44064 GL-0003 small_airport NorthGRIP Airport 75.099998 -42.316666 NA GL GL-NE NorthGRIP no GIRPA, North Greenland Ice Core Project
1268 505046 GL-0014 small_airport EastGRIP Airport 75.63 -35.99 NA GL GL-NE EastGRIP no East Greenland Ice-Core Project
1269 4582 HL56 medium_airport Matan al-Sarra Air Base 21.6877 21.8309 1769 AF LY LY-KF no HL56 HL56 https://en.wikipedia.org/wiki/Maaten_al-Sarra_Air_Base
1270 19520 KCN seaplane_base Chernofski Harbor Seaplane Base 53.402899 -167.520272 NA US US-AK Chernofski Harbor no KCN KCN KCN http://wikimapia.org/6966644/Port-of-Chernofski-Harbor
1271 26910 YBIE medium_airport Bedourie Airport -24.3461 139.460007 300 OC AU AU-QLD Bedourie yes YBIE BEU YBIE https://en.wikipedia.org/wiki/Bedourie_Airport
1272 308030 PAUT small_airport Akutan Airport 54.14459 -165.604332 133 NA US US-AK Akutan yes PAUT KQA PAUT 7AK https://web.archive.org/web/20100410064944/http://dot.alaska.gov/creg/akutan/assets/Akun_ALP_Sheet-Set-1-9.pdf https://en.wikipedia.org/wiki/Akutan_Airport Akun Airport
1273 31907 NCMH small_airport Manihiki Island Airport -10.38091 -160.999424 11 OC CK CK-U-A Manihiki Island yes NCMH MHX NCMH https://en.wikipedia.org/wiki/Manihiki_Island_Airport Humphrey Island, Te Fuinga o Niva
1274 32184 NCPY small_airport Tongareva Airport -9.01437 -158.03241 8 OC CK CK-U-A Penrhyn Island no NCPY PYE NCPY https://en.wikipedia.org/wiki/Tongareva_Airport
1275 4986 NTGE medium_airport Reao Airport -18.46652 -136.43855 12 OC PF PF-U-A Reao no NTGE REA NTGE https://en.wikipedia.org/wiki/Reao_Airport
1276 4989 NTGJ medium_airport Totegegie Airport -23.07990074157715 -134.88999938964844 7 OC PF PF-U-A yes NTGJ GMR NTGJ https://en.wikipedia.org/wiki/Totegegie_Airport
1277 32456 NTGO small_airport Tatakoto Airport -17.355226 -138.44734 12 OC PF PF-U-A Tatakoto yes NTGO TKV NTGO https://en.wikipedia.org/wiki/Tatakoto_Airport
1278 4992 NTGP small_airport Puka Puka Airport -14.80955 -138.812621 5 OC PF PF-U-A yes NTGP PKP NTGP https://en.wikipedia.org/wiki/Puka-Puka_Airport
1279 32177 NTGQ small_airport Pukaruha Airport -18.295726 -137.016291 5 OC PF PF-U-A Pukaruha no NTGQ PUK NTGQ https://en.wikipedia.org/wiki/Pukarua_Airport
1280 44636 NTGS small_airport Marutea Airport -21.482194900512695 -135.63705444335938 10 OC PF PF-U-A Auorotini no NTGS https://en.wikipedia.org/wiki/Marutea_Sud
1281 32055 NTGW small_airport Nukutavake Airport -19.284613 -138.768367 17 OC PF PF-U-A Nukutavake no NTGW NUK NTGW https://en.wikipedia.org/wiki/Nukutavake_Airport
1282 4996 NTGY small_airport Tureia Airport -20.784262 -138.56796 12 OC PF PF-U-A Tureia no NTGY ZTA NTGY https://en.wikipedia.org/wiki/Tureia_Airport
1283 31128 NTKH small_airport Fakahina Airport -15.992259 -140.164246 3 OC PF PF-U-A Fakahina yes NTKH FHZ NTKH https://en.wikipedia.org/wiki/Fakahina_Airfield
1284 5001 NTMD medium_airport Nuku Hiva Airport -8.7956 -140.229004 220 OC PF PF-U-A Nuku Hiva yes NTMD NHV NTMD https://en.wikipedia.org/wiki/Nuku_Hiva_Airport
1285 5002 NTMN medium_airport Hiva Oa-Atuona Airport -9.76879024506 -139.011001587 1481 OC PF PF-U-A Hiva Oa Island yes NTMN AUQ NTMN https://en.wikipedia.org/wiki/Atuona_Airport HIX
1286 32499 NTMP small_airport Ua Pou Airport -9.35167 -140.078003 16 OC PF PF-U-A Ua Pou yes NTMP UAP NTMP https://en.wikipedia.org/wiki/Ua_Pou_Airport
1287 32497 NTMU small_airport Ua Huka Airport -8.936228 -139.554062 160 OC PF PF-U-A Ua Huka yes NTMU UAH NTMU https://en.wikipedia.org/wiki/Ua_Huka_Airport
1288 32053 NTTX small_airport Moruroa Airport -21.80978 -138.813385 7 OC PF PF-TG Moruroa Atoll no NTTX UOA NTTX Mururoa, Mururura, Aopuni
1289 32573 NTUV small_airport Vahitahi Airport -18.780697 -138.85568 9 OC PF PF-U-A Vahitahi no NTUV VHZ NTUV https://en.wikipedia.org/wiki/Vahitahi_Airport
1290 11 NZ12 small_airport Palmer Station Airport -64.774582 -64.035907 149 AN AQ AQ-U-A Palmer Station no NZ0B NZ0B https://en.wikipedia.org/wiki/Palmer_Station
1291 340683 NZFX small_airport Phoenix Airfield -77.956389 166.766667 18 AN AQ AQ-U-A McMurdo Station no NZFX https://en.wikipedia.org/wiki/Phoenix_Airfield
1292 16190 PAAK small_airport Atka Airport 52.220299 -174.205994 57 NA US US-AK Atka yes PAAK AKB PAAK AKA https://en.wikipedia.org/wiki/Atka_Airport 40A
1293 5354 PADU medium_airport Tom Madsen (Dutch Harbor) Airport 53.89881 -166.544996 22 NA US US-AK Unalaska yes PADU DUT PADU DUT https://en.wikipedia.org/wiki/Unalaska_Airport Dutch Harbor, Unalaska
1294 16094 PAAP seaplane_base Port Alexander Seaplane Base 56.246799 -134.647995 NA US US-AK Port Alexander yes PAAP PTD PAAP AHP https://en.wikipedia.org/wiki/Port_Alexander_Seaplane_Base AK15
1295 5337 PABA medium_airport Barter Island Long Range Radar Station Airport 70.134003 -143.582001 2 NA US US-AK Barter Island yes PABA BTI PABA BTI https://en.wikipedia.org/wiki/Barter_Island_LRRS_Airport
1296 5342 PABR medium_airport Wiley Post Will Rogers Memorial Airport 71.285402 -156.766008 44 NA US US-AK Utqiaġvik yes PABR BRW PABR BRW https://en.wikipedia.org/wiki/Wiley_Post-Will_Rogers_Memorial_Airport Barrow
1297 9088 PACS small_airport Cape Sarichef Airport 54.583934 -164.905727 291 NA US US-AK Cape Sarichef no PACS WSF PACS 26AK https://en.wikipedia.org/wiki/Cape_Sarichef_Airport
1298 16092 PADK medium_airport Adak Airport 51.883564 -176.642783 18 NA US US-AK Adak yes PADK ADK PADK ADK https://en.wikipedia.org/wiki/Adak_Airport
1299 5368 PAGM medium_airport Gambell Airport 63.767694 -171.733303 27 NA US US-AK Gambell yes PAGM GAM PAGM GAM https://en.wikipedia.org/wiki/Gambell_Airport
1300 18251 PAIW small_airport Wales Airport 65.622593 -168.095 22 NA US US-AK Wales yes PAIW WAA PAIW IWK https://en.wikipedia.org/wiki/Wales_Airport_(Alaska)
1301 19891 PAKF small_airport False Pass Airport 54.84751 -163.407168 20 NA US US-AK False Pass yes PAKF KFP PAKF KFP https://en.wikipedia.org/wiki/False_Pass_Airport
1302 17980 PAKO small_airport Nikolski Air Station 52.941552 -168.849478 77 NA US US-AK Nikolski yes PAKO IKO PAKO IKO https://en.wikipedia.org/wiki/Nikolski_Air_Station
1303 16165 PALN small_airport Point Lonely Short Range Radar Site Airfield 70.911118 -153.237766 17 NA US US-AK Point Lonely no PALN LNI PALN AK71 https://en.wikipedia.org/wiki/Point_Lonely_Short_Range_Radar_Site Lonely Air Station
1304 5385 PALU medium_airport Cape Lisburne LRRS Airport 68.875099 -166.110001 16 NA US US-AK Cape Lisburne yes PALU LUR PALU LUR https://en.wikipedia.org/wiki/Cape_Lisburne_LRRS_Airport
1305 5396 PAPB medium_airport St George Airport 56.577345 -169.663823 125 NA US US-AK St George yes PAPB STG PAPB PBV https://en.wikipedia.org/wiki/St._George_Airport_(Alaska) A8L
1306 24089 PAPO small_airport Point Hope Airport 68.348801 -166.798996 12 NA US US-AK Point Hope yes PAPO PHO PAPO PHO https://en.wikipedia.org/wiki/Point_Hope_Airport
1307 5404 PASA medium_airport Savoonga Airport 63.686401 -170.492996 53 NA US US-AK Savoonga yes PASA SVA PASA SVA https://en.wikipedia.org/wiki/Savoonga_Airport
1308 5410 PASN medium_airport St Paul Island Airport 57.166311 -170.222555 63 NA US US-AK St Paul Island yes PASN SNP PASN SNP https://en.wikipedia.org/wiki/St._Paul_Island_Airport Pribilof
1309 5413 PASY medium_airport Eareckson Air Station 52.71229935 174.1139984 95 NA US US-AK Shemya no PASY SYA PASY SYA https://en.wikipedia.org/wiki/Eareckson_Air_Station
1310 5416 PATQ medium_airport Atqasuk Edward Burnell Sr Memorial Airport 70.46704 -157.436013 96 NA US US-AK Atqasuk yes PATQ ATK PATQ ATK https://en.wikipedia.org/wiki/Atqasuk_Edward_Burnell_Sr._Memorial_Airport Z46
1311 5419 PAVL small_airport Kivalina Airport 67.734565 -164.559917 13 NA US US-AK Kivalina yes PAVL KVL PAVL KVL https://en.wikipedia.org/wiki/Kivalina_Airport
1312 5422 PAWI medium_airport Wainwright Airport 70.638 -159.994995 41 NA US US-AK Wainwright yes PAWI AIN PAWI AWI https://en.wikipedia.org/wiki/Wainwright_Airport_(Alaska) 5WW
1313 5426 PCIS medium_airport Canton Island Airport -2.7681200504300003 -171.710006714 9 OC KI KI-P Abariringa no PCIS CIS PCIS https://en.wikipedia.org/wiki/Canton_Island_Airport Kanton Island
1314 5494 PMDY medium_airport Henderson Field 28.2017 -177.380997 13 OC UM UM-71 Sand Island no PMDY MDY PMDY MDY https://en.wikipedia.org/wiki/Henderson_Field_(Midway_Atoll)
1315 5495 PPIZ medium_airport Point Lay LRRS Airport 69.732903 -163.005005 22 NA US US-AK Point Lay yes PPIZ PIZ PPIZ PIZ https://en.wikipedia.org/wiki/Point_Lay_LRRS_Airport
1316 5506 PWAK medium_airport Wake Island Airfield 19.282437 166.636637 14 OC UM UM-79 Wake Island yes PWAK AWK PWAK AWK https://en.wikipedia.org/wiki/Wake_Island_Airfield
1317 5534 RJAM small_airport JMSDF Minami Torishima Air Base 24.2897 153.979004 22 AS JP JP-13 Ogasawara no RJAM MUS RJAM https://en.wikipedia.org/wiki/Minami_Torishima_Airport Marcus Island Airport
1318 5535 RJAW medium_airport Ioto (Iwo Jima) Airbase 24.784153 141.32261 384 AS JP JP-13 Ogasawara no RJAW IWO RJAW https://en.wikipedia.org/wiki/Central_Field_(Iwo_Jima) Iwo Jima Airport, Central Field, Ioto, Iōtō
1319 42980 UESU medium_airport Zyryanka Airport 65.7485 150.8889 140 AS RU RU-SA Zyryanka yes UESU ZKP UESU https://en.wikipedia.org/wiki/Zyryanka_Airport УЕСУ, Аэропорт Зырянка
1320 323626 RU-0472 small_airport Lamutskoye Airport 65.538838 168.844848 601 AS RU RU-CHU Lamutskoye no UHAL UHAL УХАЛ, Ламутское
1321 338091 RU-0543 small_airport Tempa Airfield 75.76713 137.576637 3 EU RU RU-SA Kotelny Island no Темп
1322 6456 UHMA medium_airport Ugolny Yuri Ryktheu Airport 64.734902 177.740997 194 AS RU RU-CHU Anadyr yes UHMA DYR UHMA https://en.wikipedia.org/wiki/Ugolny_Airport УХМА, Угольный, Аnadyr Airport, Аэропорт Анадырь
1323 340795 RU-0605 small_airport Uelkal Airstrip 65.530823 -179.287263 EU RU RU-CHU Uelkal no
1324 340810 RU-0616 small_airport Taymylyr Airstrip 72.607271 121.893179 EU RU RU-SA Taymylyr no
1325 341832 RU-0676 small_airport Ayanka Airport 63.709269 167.584196 295 AS RU RU-KAM Ayanka no
1326 346936 RU-0727 small_airport Khailino Airport 60.95206 166.83801 180 AS RU RU-KAM Khailino no UHPF УХПФ, Хаилино
1327 42940 UHPA small_airport Ust-Pakhachi Airport 60.556587 169.107707 10 AS RU RU-KAM Ust-Pakhachi no UHPA UHPA UHPA https://en.wikipedia.org/wiki/Ust-Pakhachi_Airport УХПА, Аэропорт Усть-Пахачи, Пахачи, Pakhachi
1328 346939 RU-0730 small_airport Sredny Pakhachi Airport 60.81718 169.07555 AS RU RU-KAM Sredny Pakhachi no
1329 346948 RU-0738 small_airport Garmanda Airport 62.18334 159.08894 AS RU RU-MAG Garmanda no UEVE
1330 347894 RU-0753 small_airport Zhilinda Airport 70.15387 113.91756 489 EU RU RU-SA Zhilinda no
1331 347895 RU-0754 small_airport Ebelyakh Airport 70.88319 113.58159 387 EU RU RU-SA Ebelyakh no
1332 347902 RU-0760 small_airport Yukta Airport 63.38788 105.65577 680 EU RU RU-KYA Yukta no
1333 347903 RU-0761 small_airport Nakanno Airport 62.89988 108.44788 816 EU RU RU-IRK Nakanno no
1334 347904 RU-0762 small_airport Khamakar Airport 61.989 108.17978 889 EU RU RU-IRK Khamakar no
1335 601237 RU-10132 small_airport Yagodnoye Airfield 62.54574 149.52257 1646 AS RU RU-MAG Yagodnoye no UHGE УХГЕ, Ягодное,
1336 602171 RU-10134 small_airport Valunistoe (airport) 66.421687 177.582464 AS RU RU-CHU Rudnik Valunisty no
1337 602186 RU-10135 small_airport Valunistoe Mining Complex Airport 66.766633 164.319284 999 AS RU RU-CHU Vesenny no
1338 602304 RU-10136 small_airport Verkhnee Penzhino Airport 64.222657 164.244866 1093 AS RU RU-KAM Penzhinsky District no Верхнее Пенжино
1339 609963 RU-10173 small_airport Stadukhino Airfield 66.965897 166.82135 1905 AS RU RU-CHU Stadukhino no ZC8P ЗЦ8П, Стадукхино
1340 34989 RU-2510 small_airport Greem Bell Air Base 81.15 64.33 30 EU RU RU-ARK Graham Bell Island no XLDG https://en.wikipedia.org/wiki/Greem_Bell Graham Bell Airbase, Аэродром Греэм Белл, Аэродром Грээм Белл, ЬЛДГ
1341 39078 SAYE small_airport Esperanza Base -63.400002 -56.983299 75 AN AQ AQ-U-A Fortín Sargento Cabral no SAYE BET https://en.wikipedia.org/wiki/Esperanza_Base
1342 5830 SAWB small_airport Gustavo Marambio Airport -64.238297 -56.630798 760 AN AQ AQ-U-A Marambio Base no SAWB MBI https://en.wikipedia.org/wiki/Marambio_Airport
1343 39076 SAWZ small_airport Matienzo Airfield -64.976998 -60.108992 75 AN AQ AQ-U-A Matienzo Base no SAWZ BTM
1344 39077 SAYB small_airport Base Belgrano II Airport -77.874055 -34.62616 820 AN AQ AQ-U-A Base Belgrano II no SAYB BEB https://en.wikipedia.org/wiki/Belgrano_II_Base
1345 6039 SCRM small_airport Teniente Rodolfo Marsh Martin Airport -62.191026 -58.98669 147 AN AQ AQ-U-A Villa Las Estrellas no SCRM TNM SCRM https://en.wikipedia.org/wiki/Teniente_R._Marsh_Airport
1346 39080 SAYS small_airport San Martín Base Airfield -68.116699 -67.099998 75 AN AQ AQ-U-A San Martín Base no SAYS BSM https://en.wikipedia.org/wiki/San_Martin_Base
1347 308226 SCBO small_airport General Bernardo O'Higgins Base Skyway -63.344 -57.842 900 AN AQ AQ-U-A General Bernardo O'Higgins Base no SCBO
1348 6021 SCFX small_airport Isla San Felix Airport -26.2939 -80.096199 165 SA CL CL-AT Isla San Felix no SCFX https://en.wikipedia.org/wiki/Isla_San_Felix_Airport
1349 45059 SCGC small_airport Union Glacier Blue-Ice Runway -79.777778 -83.320833 2461 AN AQ AQ-U-A Union Glacier no SCGC UGL SCGC https://en.wikipedia.org/wiki/Union_Glacier_Blue-Ice_Runway
1350 32268 SCPZ small_airport Patriot Hills Airport -80.318307 -81.308128 2900 AN AQ AQ-U-A Patriot Hills Base Camp no SCPZ SCPZ https://es.wikipedia.org/wiki/Aer%C3%B3dromo_Patriot_Hills
1351 6055 SEGS medium_airport Seymour Galapagos Ecological Airport -0.453758 -90.2659 207 SA EC EC-W Isla Baltra yes SEGS GPS SEGS https://ecogal.aero/en/ https://en.wikipedia.org/wiki/Seymour_Airport
1352 41131 SEII small_airport General Villamil Airport -0.942628 -90.953003 35 SA EC EC-W Puerto Villamil yes SEII IBB SEII
1353 32508 UEBN small_airport Nizhneyansk Airport 71.437822 136.189701 20 AS RU RU-SA Nizhneyansk no UEBN Нижнея́нск
1354 335165 UEKY small_airport Keng-Kyuyol Airport 68.076828 145.985126 EU RU RU-SA Keng-Kyuyol no UEKY
1355 335179 UEMC small_airport Khatyngnakh Airport 67.489845 152.575679 EU RU RU-SA no UEMC
1356 44597 UERO small_airport Olenyok Airport 68.514999 112.480003 847 AS RU RU-SA Olenyok no ONK UERO https://en.wikipedia.org/wiki/Olenyok_Airport УЕРО, Olenek Airport, Аэропорт Оленёк, Аэропорт Оленек
1357 44870 UERS medium_airport Saskylakh Airport 71.927902 114.080002 AS RU RU-SA Saskylakh yes UERS SYS UERS https://en.wikipedia.org/wiki/Saskylakh_Airport УЕРС, Аэропорт Саскылах
1358 335193 UESC small_airport Berezovka Airport 67.120183 156.589766 AS RU RU-SA no UESC УЕСЦ, Берёзовка
1359 43667 UESG medium_airport Belaya Gora Airport 68.556227 146.22784 118 AS RU RU-SA Belaya Gora no UESG BGN UESG https://en.wikipedia.org/wiki/Belaya_Gora_Airport УЕСГ, Аэропорт Белая Гора
1360 335194 UESH small_airport Argakhtakh Airport 68.443333 153.362222 65 AS RU RU-SA Argakhtakh no UESH УЕСХ, Аргахтах
1361 316761 UESK medium_airport Srednekolymsk Airport 67.4805 153.7364 60 AS RU RU-SA Srednekolymsk yes SEK UESK https://en.wikipedia.org/wiki/Srednekolymsk_Airport УЕСК, Среднеколымск
1362 335195 UESL small_airport Sylgy-Ytar Airport 67.848145 154.838862 164 AS RU RU-SA no UESL УЕСЛ, Сылгы-Ытар
1363 32514 UESO medium_airport Chokurdakh Airport 70.6231 147.901993 151 AS RU RU-SA Chokurdah yes UESO CKH UESO https://en.wikipedia.org/wiki/Chokurdakh_Airport Chokurdah Airport, Cokurdah Airport, Аэропорт Чокурдах
1364 335196 UESR small_airport Tumat Airport 70.72611 139.235833 EU RU RU-SA no UESR
1365 30870 UESS medium_airport Cherskiy Airport 68.740601 161.337997 20 AS RU RU-SA Cherskiy yes UESS CYX UESS https://en.wikipedia.org/wiki/Chersky_Airport УЕСС, Chersky Airport, Аэропорт Черский
1366 6450 UEST medium_airport Tiksi Airport 71.697700500488 128.90299987793 26 AS RU RU-SA Tiksi yes UEST IKS UEST https://en.wikipedia.org/wiki/Tiksi_Airport УЕСТ, Аеропорт Тикси
1367 335197 UESV small_airport Svatay Airport 68.057338 151.79625 75 AS RU RU-SA Svatay no UESW УЕСВ, Сватай
1368 335198 UESX small_airport Aleko-Kyuyol Airport 68.676693 151.873798 82 AS RU RU-SA no UESX УЕСЬ, Алеко-Кюель
1369 335200 UESZ small_airport Kazachye Airport 70.746294 136.179271 EU RU RU-SA no UESZ
1370 323629 UHAC small_airport Chuvanskoye Airport 65.172163 167.952484 644 AS RU RU-CHU Chuvanskoye no UHAC UHAC УХАЦ, Чуванское
1371 323630 UHAW small_airport Vayegi Airport 64.167442 171.057887 131 AS RU RU-CHU Vayegi no UHAW UHAW УХАВ, Ваеги
1372 324924 UHDW small_airport Vankarem Airport 67.838719 -175.8494283 3 EU RU RU-CHU Vankarem no UHDW УХДВ, Ванкарем
1373 530668 UHEI small_airport Ilirney Airport 67.255278 167.949167 1165 AS RU RU-CHU no UHEI
1374 525055 UHEK small_airport Kupol Airport 66.901667 169.56 1745 AS RU RU-CHU no UHEK https://en.wikipedia.org/wiki/Kupol_Airport
1375 596406 UHGL small_airport Glukharinoye Airfield 64.999872 153.096328 977 AS RU RU-MAG Glukharinoye no UHGL УХГЛ, Глухариное, Глухариный
1376 6457 UHMD medium_airport Provideniya Bay Airport 64.378098 -173.242996 72 AS RU RU-CHU Chukotka no UHMD PVS UHMD XHMD https://en.wikipedia.org/wiki/Provideniya_Bay_Airport УХМД, ЬХМД, Bukhta Provideniya Airport, Urelik Airport, Ureliki Airport, Аэропорт Бухта Провидения, Аэропорт Урелики
1377 43686 UHME small_airport Zaliv Kresta Airport 66.358398 -179.108393 22 AS RU RU-CHU Egvekinot no UHME УХМЕ, Аэропорт Залив Креста
1378 44659 UHMF medium_airport Omsukchan Airport 62.457001 155.744995 1732 AS RU RU-MAG Omsukchan yes UHMF UHMF https://en.wikipedia.org/wiki/Omsukchan_Airport Аэропорт Омсукчан
1379 35040 UHMI small_airport Mys Shmidta Airport 68.86808 -179.374183 20 AS RU RU-CHU Mys Shmidta no UHMI UHMI https://en.wikipedia.org/wiki/Mys_Shmidta_Airport УХМИ, ЬХМИ, Мыс Шмидта
1380 44473 UHMK medium_airport Keperveem Airport 67.845001 166.139999 623 AS RU RU-CHU Keperveem yes UHMK KPW UHMK https://en.wikipedia.org/wiki/Keperveyem_Airport Keperveyem Airport, Аэропорт Кепервеем
1381 42925 UHML small_airport Lavrentiya Airport 65.580426 -170.999177 30 AS RU RU-CHU Lavrentiya no UHML UHML https://en.wikipedia.org/wiki/Lavrentiya_Airport УХМЛ, Залив Лаврентия, Lavrentiya Bay
1382 44610 UHMN small_airport Omolon Airport 65.239998 160.539993 869 AS RU RU-CHU Omolon yes UHMN UHMN https://en.wikipedia.org/wiki/Omolon_Airport УХМН, Аэропорт Омолон
1383 44660 UHMO small_airport Markovo Airport 64.665446 170.417626 75 AS RU RU-CHU Markovo yes UHMO KVM UHMO https://en.wikipedia.org/wiki/Markovo_Airport Аэропорт Марково
1384 6459 UHMP medium_airport Pevek Airport 69.783302 170.597 11 AS RU RU-CHU Apapelgino yes UHMP PWE UHMP https://en.wikipedia.org/wiki/Pevek_Airport УХМП, Аэропорт Певек
1385 32518 UHMR small_airport Beringovskiy Airport 63.02 179.292999 3 AS RU RU-CHU Beringovsky no UHMR UHMR https://es.wikipedia.org/wiki/Aer%C3%B3dromo_de_Beringovski УХМР, Аэропорт Беринговский
1386 42963 UHMS medium_airport Seymchan Airport 62.92078 152.422775 679 AS RU RU-MAG Seymchan no UHMS UHMS https://en.wikipedia.org/wiki/Seymchan_Airport УХМС, Аэропорт Сеймчан
1387 324631 UHMZ small_airport Wrangel Island Airport 70.945356 -179.5 112 EU RU RU-CHU Wrangel Island no UHMZ UHMZ УХМЗ, Остров Врангеля
1388 339646 UHPN small_airport Manily Airport 62.485962 165.338917 33 AS RU RU-KAM Manily no UHPN
1389 597129 UHQE small_airport Slautnoye Airfield 63.176423 167.978281 AS RU RU-KAM Slautnoye no UHQE УХЯЕ, Слаутное
1390 42926 UIKE small_airport Yerbogachen Airport 61.2750015259 108.029998779 400 AS RU RU-IRK Erbogachen no UIKE ERG UIKE https://en.wikipedia.org/wiki/Erbogachen_Airport Yerbogachyon Airport, Erbogachyon Airport, Erbogachen Airport, Аэропорт Ербогачен, Аэропорт Ербогачён
1391 43672 ULDW small_airport Varandey Airport 68.848503 58.201401 23 AS RU RU-NEN Varandey no ULDW VRI ULDW https://en.wikipedia.org/wiki/Varandey_Airport УЛДВ, Varandei Airport, Аэропорт Варандей
1392 315363 UODL small_airport Cape Chelyuskin Airfield 77.712 104.24 60 AS RU RU-KYA Chelyuskin Polar Station no UODL UODL УОДЛ, Челюскин
1393 35041 UODN medium_airport Nagurskoye Airfield 80.803207 47.663586 59 AS RU RU-ARK Alexandra Land no UODN UODN https://en.wikipedia.org/wiki/Nagurskoye
1394 35086 UODS small_airport Sredniy Island Air Base 79.52958 91.07495 26 AS RU RU-KYA Khatanga no UODS UODS XODS https://en.wikipedia.org/wiki/Sredny_Ostrov УОДС, Sredniy Ostrov Air Base, Аэродром Средний Остров, ЬОДС
1395 301864 US-0200 small_airport Kogru River Airfield 70.574196 -152.259478 NA US US-AK Kogru no A41
1396 340805 US-3039 small_airport Brownlow Point Airport 69.979281 -144.834986 NA US US-AK Brownlow Point no
1397 340807 US-3041 small_airport Demarcation Bay Airfield 69.882551 -142.305616 NA US US-AK Nuvagapak Point no Nuvagapak Point
1398 316465 WAN small_airport Waverney Airport -25.356917 141.925593 570 OC AU AU-QLD Waverney no WAN
1399 354533 YABL small_airport Ambalindum Airport -23.35187 134.732434 1966 OC AU AU-NT Ambalindum no YABL
1400 27317 YADO small_airport Andado Airport -25.407772 135.290794 549 OC AU AU-NT Ghan no YADO
1401 38224 YALC small_airport Alcoota Station Airport -22.801963 134.4036 1994 OC AU AU-NT Alcoota no YALC Engawala
1402 38226 YALM small_airport Allambie Airport -24.265335 134.402927 OC AU AU-NT no YALM
1403 38229 YAMM small_airport Ammaroo Airport -21.738300323486328 135.24200439453125 OC AU AU-NT no AMX YAMM
1404 27328 YAMT small_airport Amata Airport -26.097363 131.202732 695 OC AU AU-SA no YAMT AMT YAMT https://en.wikipedia.org/wiki/Amata_Airport
1405 38230 YANJ small_airport Angatja Airport -26.100000381469727 130.39999389648438 OC AU AU-SA no YANJ
1406 38231 YANN small_airport Anningie Airport -21.83169937133789 133.125 OC AU AU-NT no YANN
1407 27332 YANW small_airport Annitowa Airport -21.200017 136.451139 901 OC AU AU-NT no YANW
1408 27336 YARD small_airport Argadargada Airport -21.676700592041016 136.67799377441406 OC AU AU-NT no YARD
1409 27340 YARN small_airport Areyonga Airport -24.091565 132.271228 OC AU AU-NT Mereenie no YARN
1410 38232 YARP small_airport Arapunya Airport -22.316699981689453 135.6999969482422 OC AU AU-NT no YARP
1411 38233 YATL small_airport Atula Airport -23.255344 136.388955 915 OC AU AU-NT Anatye no YATL
1412 26895 YAYE medium_airport Ayers Rock Connellan Airport -25.185913 130.97703 1626 OC AU AU-NT Yulara yes YAYE AYQ YAYE https://en.wikipedia.org/wiki/Ayers_Rock_Airport Ayers Rock, Uluru
1413 26900 YBAS medium_airport Alice Springs Airport -23.806588 133.903427 1789 OC AU AU-NT Alice Springs yes YBAS ASP YBAS http://www.alicespringsairport.com.au/ https://en.wikipedia.org/wiki/Alice_Springs_Airport
1414 26907 YBDV medium_airport Birdsville Airport -25.897499084472656 139.34800720214844 159 OC AU AU-QLD yes YBDV BVI YBDV https://en.wikipedia.org/wiki/Birdsville_Airport
1415 27369 YBEO small_airport Betoota Airport -25.694791 140.738339 91 OC AU AU-QLD no YBEO BTX YBEO
1416 38256 YBRC small_airport Barrow Creek Airport -21.542202 133.871959 OC AU AU-NT no YBRC
1417 27416 YBSR small_airport Blackstone Airport -25.9867000579834 128.28799438476562 OC AU AU-WA no YBSR
1418 38278 YCCK small_airport Canteen Creek Airport -20.650800704956055 135.5850067138672 OC AU AU-NT no YCCK
1419 38293 YCNS small_airport Coniston Airport -22.13330078125 132.5330047607422 OC AU AU-NT no YCNS
1420 348022 YCSK small_airport Casey Station Skiway -66.288056 110.7575 1178 AN AQ AQ-U-A Casey Station no YCSK https://en.wikipedia.org/wiki/Casey_Station
1421 38304 YCSP small_airport Curtin Springs Airport -25.333921 131.759308 OC AU AU-NT no YCSP
1422 38308 YCUD small_airport Cuddapan Airport -25.59000015258789 141.50799560546875 OC AU AU-QLD no YCUD
1423 38460 YMDS small_airport Macdonald Downs Airport -22.444000244099996 135.199005127 OC AU AU-NT no YMDS MNW YMDS
1424 27532 YDRI small_airport Durrie Airport -25.684999465942383 140.22799682617188 58 OC AU AU-QLD no YDRI DRR YDRI
1425 38330 YDRL small_airport De Rose Hill Airport -26.435838 133.259954 OC AU AU-SA De Rose Hill no YDRL
1426 27535 YDVR small_airport Docker River Airport -24.859533 129.122209 589 OC AU AU-NT Kaltukatjara no YDVR DKV YDVR
1427 38334 YDYD small_airport Derry Downs Airport -22.08329963684082 135.33299255371094 OC AU AU-NT no YDYD
1428 38338 YELK small_airport Elkedra Airport -21.172500610399997 135.444000244 OC AU AU-NT no EKD YELK
1429 38342 YEPR small_airport Epenarra Airport -20.433300018310547 135.26699829101562 OC AU AU-NT no YEPR
1430 38345 YERL small_airport Erldunda Airport -25.206106 133.254161 OC AU AU-NT Ghan no EDD YERL
1431 27554 YERN small_airport Ernabella Airport -26.2632999420166 132.1820068359375 707 OC AU AU-SA no YERN ERB YERN
1432 27559 YEVP small_airport Everard Park Airport -27.038988 132.688585 1615 OC AU AU-SA Mimili no YEVP
1433 31129 YFNE small_airport Finke Airport -25.5946998596 134.582992554 OC AU AU-NT Finke no YFNE FIK YFNE
1434 27566 YFRG small_airport Fregon Airport -26.774999618530273 132.01699829101562 528 OC AU AU-SA no YFRG
1435 26985 YFRT medium_airport Forrest Airport -30.83662 128.112811 511 OC AU AU-WA no YFRT FOS YFRT https://en.wikipedia.org/wiki/Forrest_Airport
1436 27631 YIDK small_airport Indulkana Airport -26.965435 133.321989 401 OC AU AU-SA Indulkana no YIDK IDK YIDK
1437 27594 YGLE small_airport Glengyle Airport -24.808300018310547 139.60000610351562 91 OC AU AU-QLD no YGLE GLG YGLE
1438 27599 YGLS small_airport Giles Airport -25.043699 128.296005 579 OC AU AU-WA Warakurna no YGLS https://en.wikipedia.org/wiki/Giles_Airport
1439 27612 YHAA small_airport Haasts Bluff Airport -23.454999923706 131.85299682617 2269 OC AU AU-NT no YHAA
1440 27619 YHKT small_airport Huckitta Airport -22.943300247192383 135.44700622558594 OC AU AU-NT no YHKT
1441 27621 YHMB small_airport Hermannsburg Airport -23.926485 132.807798 593 OC AU AU-NT Hermannsburg (Ntaria) no YHMB HMG YHMB
1442 38390 YHSB small_airport Horseshoe Bend Airport -25.216699600219727 134.26699829101562 OC AU AU-NT no YHSB
1443 38394 YHTS small_airport Harts Range Airport -22.985000610351562 134.91799926757812 OC AU AU-NT no YHTS
1444 27632 YIDR small_airport Idracowra Airport -25.06329917907715 133.73300170898438 OC AU AU-NT no YIDR
1445 38396 YIKL small_airport Baikal Airport -22.7632999420166 136.16299438476562 OC AU AU-NT no YIKL
1446 27647 YJAM small_airport Jameson Airport -25.850000381469727 127.68299865722656 OC AU AU-WA no YJAM
1447 38407 YKCA small_airport Kings Canyon Airport -24.260229 131.488924 2100 OC AU AU-NT Petermann no YKCA KBJ YKCA
1448 38425 YLBG small_airport Mount Liebig Airport -23.24329948425293 131.25999450683594 OC AU AU-NT no YLBG
1449 27719 YLGN small_airport Loongana Airport -30.940771 127.028781 OC AU AU-WA no YLGN
1450 27727 YLLC small_airport Lilla Creek Airport -25.55791 134.07114 OC AU AU-NT no YLLC
1451 38444 YLSY small_airport Mount Lindsay Airport -27.018299102783203 129.88499450683594 OC AU AU-SA no YLSY
1452 27749 YMAD small_airport Madura Airport -31.887825 127.025573 OC AU AU-WA no YMAD
1453 32730 YMBX small_airport Mundrabilla Airport -31.86720085144043 127.85399627685547 120 OC AU AU-WA Mundrabilla no YMBX
1454 38455 YMBZ small_airport Mount Ebenezer Airport -25.169763 132.643107 OC AU AU-NT no YMBZ
1455 27763 YMDV small_airport Mount Davies Airport -26.16670036315918 129.13299560546875 OC AU AU-SA no YMDV
1456 27789 YMNK small_airport Monkira Airport -24.816699981689453 140.5330047607422 107 OC AU AU-QLD no YMNK ONR YMNK
1457 27185 YYND small_airport Yuendumu Airport -22.2542 131.781998 2205 OC AU AU-NT no YYND YUE YYND https://en.wikipedia.org/wiki/Yuendumu_Airport
1458 31943 YMQA small_airport Marqua Airport -22.80579948425293 137.25100708007812 OC AU AU-NT Marqua no YMQA MQE YMQA
1459 38495 YMSK small_airport Mount Skinner Airport -22.187801 134.171648 OC AU AU-NT no YMSK
1460 27812 YMTX small_airport Mount Dare Airport -26.06170082092285 135.2469940185547 OC AU AU-SA no YMTX
1461 38500 YMUP small_airport Mulga Park Airport -25.860000610399997 131.649993896 OC AU AU-NT no YMUP MUP YMUP
1462 27823 YMWE small_airport Mount Wedge Airport -22.737199783325195 132.1510009765625 559 OC AU AU-NT no YMWE
1463 38507 YMYV small_airport Maryvale Airport -24.647992 134.026358 OC AU AU-NT no YMYV
1464 38508 YMYW small_airport Murray Downs Airport -21.04829978942871 134.68299865722656 OC AU AU-NT no YMYW
1465 38513 YNHV small_airport New Haven Airport -22.728300094604492 131.14500427246094 OC AU AU-NT no YNHV
1466 27850 YNRR small_airport Nyrripi Airport -22.645299911499023 130.56500244140625 OC AU AU-NT no YNRR
1467 38523 YNUE small_airport Numery Airport -23.983299255371094 135.39999389648438 OC AU AU-NT no YNUE
1468 38528 YNWT small_airport Narwietooma Airport -23.228786 132.629378 OC AU AU-NT no YNWT
1469 38535 YORA small_airport Moonerah Airport -31.691413 126.590523 OC AU AU-WA no YORA
1470 38537 YORT small_airport Ooratippra Airport -21.905799865722656 136.06900024414062 OC AU AU-NT no YORT
1471 354815 YPHS small_airport Pine Hill Station Airport -22.386977 133.06025 2142 OC AU AU-NT Anmatjere no YPHS
1472 27924 YRNW small_airport Ringwood Airport -23.82830047607422 134.96200561523438 OC AU AU-NT no YRNW
1473 27991 YTIT small_airport Ti Tree Airport -22.131701 133.419998 OC AU AU-NT no YTIT https://en.wikipedia.org/wiki/Ti-Tree_Airfield
1474 38607 YTJU small_airport Tjuntjuntjarra Airport -29.344938 127.107348 740 OC AU AU-WA no YTJU
1475 38609 YTLT small_airport Tarlton Downs Airport -22.63330078125 136.8000030517578 OC AU AU-NT no YTLT
1476 32491 YTMY small_airport Tobermorey Airport -22.255800247192383 137.9530029296875 OC AU AU-NT Tobermorey no YTMY TYP YTMY
1477 28014 YTYN small_airport Tieyon Airport -26.216699600219727 133.91700744628906 OC AU AU-SA no YTYN
1478 38623 YUMB small_airport Umbeara Airport -25.746700286865234 133.70199584960938 OC AU AU-NT no YUMB
1479 38625 YUTP small_airport Utopia Airport -22.05500030517578 134.7899932861328 OC AU AU-NT no YUTP
1480 38629 YVNS small_airport Vaughan Springs Airport -22.33329963684082 130.86700439453125 OC AU AU-NT no YVNS
1481 27165 YWBR small_airport Warburton Airport -26.125538 126.583158 1500 OC AU AU-WA Warburton no YWBR https://en.wikipedia.org/wiki/Warburton_Airport
1482 302312 YWKS small_airport Wilkins Runway -66.690833 111.523611 2529 AN AQ AQ-U-A Preston Heath no YWKS https://en.wikipedia.org/wiki/Wilkins_Runway
1483 38645 YWLA small_airport Willowra Airport -21.27669906616211 132.6230010986328 OC AU AU-NT no YWLA
1484 38647 YWLH small_airport Wallara Ranch Airport -24.649999618530273 132.31700134277344 OC AU AU-NT no YWLH
+4 -5
View File
@@ -8,11 +8,10 @@ services:
# Game state SQLite (v0.6.0): seeded on first run, must survive rebuilds. # Game state SQLite (v0.6.0): seeded on first run, must survive rebuilds.
# Dedicated dir — do NOT mount over /app/data (would mask airports_world.csv). # Dedicated dir — do NOT mount over /app/data (would mask airports_world.csv).
- "./db:/app/db" - "./db:/app/db"
environment: # No environment on purpose (#135, v0.62.0): FLIGHT_TEST_HOOKS must NOT be set in production —
# e2e-only affordance (v0.7.0): enables POST /api/test/create-package and # it enables the /api/test/* hooks AND makes tickOnce honor legacy stored timeScale values
# /api/test/expire-package so the suites can force known routes/expiries; # (pre-v0.52.0 saves hold 1000). The e2e suite runs only in CI against docker-compose.ci.yml,
# 404 without this var. # which sets the var itself.
FLIGHT_TEST_HOOKS: "1"
networks: networks:
- dev_net - dev_net
labels: labels:
+7 -7
View File
@@ -98,10 +98,10 @@ async function setHealth(page: Page, planeId: string, fields: Record<string, unk
expect(res.status()).toBe(200); expect(res.status()).toBe(200);
} }
// A fully grounded fleet only advances at the idle real-time rate (ISS-128) — put the starter in // A fully grounded fleet freezes the world clock (#135) — put the starter in repair so the clock
// repair so the clock runs at FULL scale for tests that need fast-forwarding. The €1.5k repair cost // runs at FULL scale for tests that need fast-forwarding. The €1.5k repair cost is why the expiry
// is why the expiry test captures its cash/rep baseline AFTER deactivateWorld; deactivateWorld // test captures its cash/rep baseline AFTER deactivateWorld; deactivateWorld restores full health
// restores full health and no gate afterwards. // and no gate afterwards.
async function activateWorld(page: Page): Promise<void> { async function activateWorld(page: Page): Promise<void> {
await setHealth(page, 'plane-starter', { health: 50 }); await setHealth(page, 'plane-starter', { health: 50 });
expect((await page.request.post('/api/planes/plane-starter/repair')).status()).toBe(200); expect((await page.request.post('/api/planes/plane-starter/repair')).status()).toBe(200);
@@ -344,9 +344,9 @@ test('expired packages deliver and abandon with no reward and no penalty', async
expect(res.ok()).toBeTruthy(); expect(res.ok()).toBeTruthy();
} }
// A fully grounded fleet only advances at the idle real-time rate (ISS-128) — put the starter in // A fully grounded fleet freezes the world clock (#135) — put the starter in repair for the expiry
// repair for the expiry window so scale 1000 can fast-forward past both deadlines quickly. The €1.5k // window so scale 1000 can fast-forward past both deadlines quickly. The €1.5k repair cost is why
// repair cost is why the cash/rep baseline below is captured AFTER deactivateWorld, not before it. // the cash/rep baseline below is captured AFTER deactivateWorld, not before it.
await activateWorld(page); await activateWorld(page);
try { try {
// Fast-forward past both deadlines — the tick flips loaded → expired (slot kept). // Fast-forward past both deadlines — the tick flips loaded → expired (slot kept).
+19 -1
View File
@@ -8,8 +8,13 @@ const baseUrl = process.env.E2E_BASE_URL ?? 'https://flight.dev.kkhost.pl';
interface StateBody { interface StateBody {
simState: { clockMs: number }; simState: { clockMs: number };
packages?: Array<{ status: string }>;
} }
// ISS-133 (v0.59.0): frames carry only the package statuses the client renders — terminal history
// (delivered/abandoned/ignored) is unbounded in the DB and must never leak into a pushed frame.
const ALLOWED_PACKAGE_STATUSES = new Set(['open', 'loaded', 'expired']);
test('GET /api/events streams state snapshots over SSE', async () => { test('GET /api/events streams state snapshots over SSE', async () => {
const res = await fetch(`${baseUrl}/api/events`, { headers: { Accept: 'text/event-stream' } }); const res = await fetch(`${baseUrl}/api/events`, { headers: { Accept: 'text/event-stream' } });
expect(res.status).toBe(200); expect(res.status).toBe(200);
@@ -20,6 +25,8 @@ test('GET /api/events streams state snapshots over SSE', async () => {
const decoder = new TextDecoder(); const decoder = new TextDecoder();
let buffer = ''; let buffer = '';
const clocks: number[] = []; // simState.clockMs of each parsed snapshot event const clocks: number[] = []; // simState.clockMs of each parsed snapshot event
const statusesSeen = new Set<string>(); // package statuses observed in any frame (ISS-133)
let maxFrameBytes = 0;
try { try {
// Collect two snapshot events: the initial one, then at least one pushed by a background tick. // Collect two snapshot events: the initial one, then at least one pushed by a background tick.
@@ -46,6 +53,8 @@ test('GET /api/events streams state snapshots over SSE', async () => {
if (!line.startsWith('data: ')) continue; // heartbeats are comment lines (" : ping") if (!line.startsWith('data: ')) continue; // heartbeats are comment lines (" : ping")
const snap = JSON.parse(line.slice('data: '.length)) as StateBody; const snap = JSON.parse(line.slice('data: '.length)) as StateBody;
clocks.push(snap.simState.clockMs); clocks.push(snap.simState.clockMs);
for (const p of snap.packages ?? []) statusesSeen.add(p.status);
maxFrameBytes = Math.max(maxFrameBytes, line.length);
} }
} }
} }
@@ -54,6 +63,15 @@ test('GET /api/events streams state snapshots over SSE', async () => {
} }
// The initial snapshot arrives on connect; the second comes from a background tick within ~1 s. // The initial snapshot arrives on connect; the second comes from a background tick within ~1 s.
// A grounded fleet freezes the clock (#135), so consecutive frames may carry the SAME clockMs —
// non-decreasing is what proves real pushes, not replays (advance itself is pinned in sim.spec.ts).
expect(clocks.length).toBeGreaterThanOrEqual(2); expect(clocks.length).toBeGreaterThanOrEqual(2);
expect(clocks[1]).toBeGreaterThan(clocks[0]); // clock advanced between pushes — real updates, not replays expect(clocks[1]).toBeGreaterThanOrEqual(clocks[0]);
// ISS-133: no terminal package history in any frame (the DB keeps it forever; frames must not),
// and a bounded frame size even on an instance with long-running history (~597 KB pre-v0.59.0).
for (const status of statusesSeen) {
expect(ALLOWED_PACKAGE_STATUSES.has(status)).toBe(true);
}
expect(maxFrameBytes).toBeLessThan(200_000);
}); });
+4 -4
View File
@@ -39,9 +39,9 @@ async function setHealth(page: Page, planeId: string, fields: Record<string, unk
expect(res.status()).toBe(200); expect(res.status()).toBe(200);
} }
// A fully grounded fleet only advances at the idle real-time rate (ISS-128) — put the starter in // A fully grounded fleet freezes the world clock (#135) — put the starter in repair so the clock
// repair so the clock runs at FULL scale for tests that need fast-forwarding. The €1.5k repair cost // runs at FULL scale for tests that need fast-forwarding. The €1.5k repair cost is irrelevant to
// is irrelevant to every spec's relative cash assertions; deactivateWorld restores full health and no gate afterwards. // every spec's relative cash assertions; deactivateWorld restores full health and no gate afterwards.
async function activateWorld(page: Page): Promise<void> { async function activateWorld(page: Page): Promise<void> {
await setHealth(page, STARTER, { health: 50 }); await setHealth(page, STARTER, { health: 50 });
expect((await page.request.post(`/api/planes/${STARTER}/repair`)).status()).toBe(200); expect((await page.request.post(`/api/planes/${STARTER}/repair`)).status()).toBe(200);
@@ -151,7 +151,7 @@ test('sim clock ticks smoothly between polls at the fixed world rate (ISS-007, I
// 409s on non-available planes — it must be grounded before activateWorld. // 409s on non-available planes — it must be grounded before activateWorld.
await flyHomeViaApi(page); await flyHomeViaApi(page);
await setScale(page, WORLD); // self-heal may have left the fast test rate behind await setScale(page, WORLD); // self-heal may have left the fast test rate behind
// A grounded fleet only advances at the idle real-time rate (ISS-128) — put the starter in repair for full scale. // A fully grounded fleet freezes the world clock (#135) — put the starter in repair for full scale.
await activateWorld(page); await activateWorld(page);
try { try {
await page.goto('/'); await page.goto('/');
+4 -13
View File
@@ -274,26 +274,17 @@ test('on-board list: fly-to-destination + abandon with penalty preview; flying p
// The abandon button previews the penalty at its snapshot's clock (same formula as the server). // The abandon button previews the penalty at its snapshot's clock (same formula as the server).
// The fleet is grounded here (the starter just loaded; workers:1 and every spec's cleanup leave no // The fleet is grounded here (the starter just loaded; workers:1 and every spec's cleanup leave no
// other planes), so the world runs at the idle real-time rate (ISS-128) — verify it actually did, // other planes), so the world clock is FROZEN (#135) — verify it actually is, then the preview must
// then bound the UI's staleness instead of racing a frozen clock. // match the server exactly: a frozen clock means zero drift between any two snapshots.
const c0 = (await getState(page)).simState.clockMs; const c0 = (await getState(page)).simState.clockMs;
const t0 = Date.now();
await new Promise((r) => setTimeout(r, 1_500)); // > one background-tick interval await new Promise((r) => setTimeout(r, 1_500)); // > one background-tick interval
const state = await getState(page); const state = await getState(page);
const idleDelta = state.simState.clockMs - c0; expect(state.simState.clockMs - c0, 'the grounded clock must stay frozen (#135)').toBe(0);
expect(idleDelta, 'world should advance at the idle real-time rate while grounded (ISS-128)').toBeGreaterThan(0);
expect(idleDelta).toBeLessThan((Date.now() - t0) * WORLD); // clearly below the full world rate
// The UI renders the penalty from its last snapshot — up to one poll interval (~1 s, useGameState)
// older than `state`, i.e. ≤ ~2 game-seconds of clock drift at the idle real-time rate (ISS-128).
// Allow the formula's slope over that window instead of an exact string match.
const DRIFT_MS = 3_000; // a couple of poll intervals at the idle rate (= 1), margin for slow CI boxes
const span = pkg.deadlineSimTime - pkg.createdSimTime;
const penaltyText = ((await page.getByTestId(`abandon-penalty-${pkg.id}`).textContent()) ?? '').replace(/[^0-9.]/g, ''); const penaltyText = ((await page.getByTestId(`abandon-penalty-${pkg.id}`).textContent()) ?? '').replace(/[^0-9.]/g, '');
expect(Number.isFinite(Number(penaltyText)), `penalty text: ${penaltyText}`).toBe(true); expect(Number.isFinite(Number(penaltyText)), `penalty text: ${penaltyText}`).toBe(true);
const expectedPenalty = penaltyFor(pkg.reward, pkg.createdSimTime, pkg.deadlineSimTime, state.simState.clockMs); const expectedPenalty = penaltyFor(pkg.reward, pkg.createdSimTime, pkg.deadlineSimTime, state.simState.clockMs);
const slopePerGameMs = (pkg.reward * 0.45) / span; // abandonPenaltyPct's SPAN across the package lifetime expect(Number(penaltyText), 'frozen clock → the preview matches the server exactly').toBe(expectedPenalty);
expect(Math.abs(Number(penaltyText) - expectedPenalty)).toBeLessThanOrEqual(slopePerGameMs * DRIFT_MS + 0.01);
// Fly to the destination through the UI — the button is the destination's name. // Fly to the destination through the UI — the button is the destination's name.
const flyBtn = page.getByTestId(`fly-to-${pkg.id}`); const flyBtn = page.getByTestId(`fly-to-${pkg.id}`);
+9 -21
View File
@@ -1,15 +1,14 @@
import { test, expect, type Page } from '@playwright/test'; import { test, expect, type Page } from '@playwright/test';
// v0.52.0 (ISS-117) fixed world clock against the live origin: a fully grounded fleet slowing to // v0.52.0 (ISS-117), finalized in #135: fixed world clock against the live origin — a fully
// real time instead of freezing (ISS-128), background-tick advance at a raised rate while // grounded fleet freezes the clock, background-tick advance at a raised rate while something is
// something is active, package expiry via the FLIGHT_TEST_HOOKS hooks (enabled in docker-compose.yml), // active, package expiry via the FLIGHT_TEST_HOOKS hooks (enabled in docker-compose.yml), and
// and market top-up. // market top-up.
// Must match lib/sim/engine.ts — kept in sync manually (same pattern as MIN_ZOOM/MAX_ZOOM in map.spec.ts). // Must match lib/sim/engine.ts — kept in sync manually (same pattern as MIN_ZOOM/MAX_ZOOM in map.spec.ts).
const MAX_TICK_ELAPSED_MS = 2_000; const MAX_TICK_ELAPSED_MS = 2_000;
const SCALE = 1000; // test rate for fast-forwarding legs const SCALE = 1000; // test rate for fast-forwarding legs
const WORLD = 24; // the fixed world rate (ISS-117) — must match lib/worldClock.ts const WORLD = 24; // the fixed world rate (ISS-117) — must match lib/worldClock.ts
const IDLE = 1; // the idle real-time rate (ISS-128) — must match IDLE_WORLD_TIME_SCALE in lib/worldClock.ts (= WORLD / 24)
const MAX_DELTA_PER_TICK = MAX_TICK_ELAPSED_MS * SCALE; // 2_000_000 game ms per tick at scale 1000 const MAX_DELTA_PER_TICK = MAX_TICK_ELAPSED_MS * SCALE; // 2_000_000 game ms per tick at scale 1000
// Must match MARKET_TARGET_OPEN_PACKAGES in lib/game/seed.ts. // Must match MARKET_TARGET_OPEN_PACKAGES in lib/game/seed.ts.
const MARKET_TARGET = 10; const MARKET_TARGET = 10;
@@ -48,10 +47,9 @@ async function setHealth(page: Page, planeId: string, fields: Record<string, unk
expect(res.status()).toBe(200); expect(res.status()).toBe(200);
} }
// A fully grounded fleet only advances at the idle real-time rate (ISS-128) — put the starter in // A fully grounded fleet freezes the world clock (#135) — put the starter in repair so the clock
// repair so the clock runs at FULL scale for tests that need fast-forwarding. The €1.5k repair // runs at FULL scale for tests that need fast-forwarding. The €1.5k repair cost is irrelevant to
// cost is irrelevant to every spec's relative cash assertions; deactivateWorld restores full health // every spec's relative cash assertions; deactivateWorld restores full health and no gate afterwards.
// and no gate afterwards.
async function activateWorld(page: Page): Promise<void> { async function activateWorld(page: Page): Promise<void> {
await setHealth(page, STARTER, { health: 50 }); await setHealth(page, STARTER, { health: 50 });
expect((await page.request.post(`/api/planes/${STARTER}/repair`)).status()).toBe(200); expect((await page.request.post(`/api/planes/${STARTER}/repair`)).status()).toBe(200);
@@ -73,25 +71,15 @@ test.afterEach(async ({ page }) => {
await setScale(page, WORLD); await setScale(page, WORLD);
}); });
test('a fully grounded fleet slows the clock to real time instead of freezing it (ISS-128)', async ({ page }) => { test('a fully grounded fleet freezes the world clock (#135)', async ({ page }) => {
const s = await getState(page); const s = await getState(page);
expect(s.planes.every((p) => p.status === 'available'), 'fleet should be grounded at spec start').toBe(true); expect(s.planes.every((p) => p.status === 'available'), 'fleet should be grounded at spec start').toBe(true);
const t0 = Date.now();
const c0 = s.simState.clockMs; const c0 = s.simState.clockMs;
await sleep(2_500); // ~2.5 s of real idleness — several background ticks plus the reads below await sleep(2_500); // ~2.5 s of real idleness — several background ticks plus the reads below
const after = await getState(page); const after = await getState(page);
const elapsedReal = Date.now() - t0;
const delta = after.simState.clockMs - c0; expect(after.simState.clockMs - c0, 'the grounded clock must stay frozen').toBe(0);
expect(delta, 'the idle clock must advance (no longer frozen)').toBeGreaterThan(0);
// ≈ real time: each tick counts min(gap, MAX_TICK_ELAPSED_MS) × IDLE rate, so the total can only fall
// short of the wall span when a tick gap was clamped — worst case is one clamped idle-rate tick.
expect(delta).toBeGreaterThanOrEqual(Math.min(elapsedReal * IDLE * 0.5, MAX_TICK_ELAPSED_MS * IDLE));
// …and never more than the wall span itself (plus one clamp of pre-read downtime for slow boxes)…
expect(delta).toBeLessThanOrEqual(elapsedReal + MAX_TICK_ELAPSED_MS);
// …which is clearly below the full world rate: at ×24 this window would be ≥ ~60 game seconds.
expect(delta).toBeLessThan(elapsedReal * WORLD);
}); });
test('timeScale 1000 advances the clock by roughly real-time × 1000 between polls', async ({ page }) => { test('timeScale 1000 advances the clock by roughly real-time × 1000 between polls', async ({ page }) => {
+6 -16
View File
@@ -8,9 +8,6 @@ import { test, expect } from '@playwright/test';
const repoRoot = path.join(__dirname, '..'); const repoRoot = path.join(__dirname, '..');
const composeArgs = process.env.E2E_COMPOSE_ARGS ?? ''; const composeArgs = process.env.E2E_COMPOSE_ARGS ?? '';
// Must match lib/sim/engine.ts — kept in sync manually (same pattern as e2e/sim.spec.ts).
const MAX_TICK_ELAPSED_MS = 2_000;
interface StateBody { interface StateBody {
account: { cash: number; reputation: number }; account: { cash: number; reputation: number };
simState: { clockMs: number }; // ISS-117: the snapshot carries only the game clock simState: { clockMs: number }; // ISS-117: the snapshot carries only the game clock
@@ -45,9 +42,8 @@ test('GET /api/state returns a seeded snapshot', async ({ page }) => {
test('state survives a container restart (sim clock + account persisted)', async ({ page }) => { test('state survives a container restart (sim clock + account persisted)', async ({ page }) => {
test.setTimeout(180_000); test.setTimeout(180_000);
// Self-heal to a fully grounded fleet first — while idle the clock advances at real time // Self-heal to a fully grounded fleet first — a grounded fleet freezes the world clock (#135),
// (ISS-128), so the post-restart snapshot is bounded by one clamped tick of downtime plus live // so no tick advances it across the restart and the post-restart clock is exactly unchanged.
// ticks, not byte-for-byte identical.
await expect await expect
.poll(async () => { .poll(async () => {
const res = await page.request.get('/api/state'); const res = await page.request.get('/api/state');
@@ -60,7 +56,6 @@ test('state survives a container restart (sim clock + account persisted)', async
const resBefore = await page.request.get('/api/state'); const resBefore = await page.request.get('/api/state');
expect(resBefore.status()).toBe(200); expect(resBefore.status()).toBe(200);
const before = (await resBefore.json()) as StateBody; const before = (await resBefore.json()) as StateBody;
const tBefore = Date.now();
execSync(`docker compose ${composeArgs} restart flight`, { cwd: repoRoot, stdio: 'pipe' }); execSync(`docker compose ${composeArgs} restart flight`, { cwd: repoRoot, stdio: 'pipe' });
@@ -80,17 +75,12 @@ test('state survives a container restart (sim clock + account persisted)', async
expect(after).toBeDefined(); expect(after).toBeDefined();
const a = after!; const a = after!;
const tAfter = Date.now();
// The DB file on the volume must be loaded, not re-seeded (PLAN.md: "sim clock persisted across // The DB file on the volume must be loaded, not re-seeded (PLAN.md: "sim clock persisted across
// sessions"): account and entity ids are byte-identical. With the fleet grounded above, ISS-128 // sessions"): account and entity ids are byte-identical. With the fleet grounded above, the world
// advances the clock at real time while idle — bounded tolerance instead of exact equality: no // clock is FROZEN (#135) — no tick advances it while the container is down or after restart, so
// ticks run while the container is down, so the first post-restart tick counts the downtime // the post-restart clock is EXACTLY unchanged; a re-seed would reset clockMs backwards instead.
// clamped to MAX_TICK_ELAPSED_MS × IDLE rate (= 1), and every other counted gap lies inside the expect(a.simState.clockMs - before.simState.clockMs).toBe(0);
// live wall span [tBefore, tAfter] at that same rate. A re-seed would reset clockMs backwards.
const delta = a.simState.clockMs - before.simState.clockMs;
expect(delta).toBeGreaterThanOrEqual(0); // never goes backwards — not re-seeded
expect(delta).toBeLessThanOrEqual(MAX_TICK_ELAPSED_MS + (tAfter - tBefore));
expect(a.account.cash).toBe(before.account.cash); expect(a.account.cash).toBe(before.account.cash);
expect(a.account.reputation).toBe(before.account.reputation); expect(a.account.reputation).toBe(before.account.reputation);
expect(a.planes.map((p) => p.id).sort()).toEqual(before.planes.map((p) => p.id).sort()); expect(a.planes.map((p) => p.id).sort()).toEqual(before.planes.map((p) => p.id).sort());
+61 -1
View File
@@ -1,5 +1,7 @@
import { promises as fs } from 'node:fs';
import path from 'node:path';
import { describe, expect, it } from 'vitest'; import { describe, expect, it } from 'vitest';
import { assertUniqueIcaos, filterWorldAirports, parseCsv, toGeoJson, airportsHandler } from './airports'; import { assertUniqueIcaos, filterWorldAirports, isRemote, parseCsv, toGeoJson, airportsHandler, REMOTE_RADIUS_KM } from './airports';
const HEADER = const HEADER =
'"id","ident","type","name","latitude_deg","longitude_deg","elevation_ft","continent","iso_country","iso_region","municipality","scheduled_service","icao_code","iata_code","gps_code","local_code","home_link","wikipedia_link","keywords"'; '"id","ident","type","name","latitude_deg","longitude_deg","elevation_ft","continent","iso_country","iso_region","municipality","scheduled_service","icao_code","iata_code","gps_code","local_code","home_link","wikipedia_link","keywords"';
@@ -132,3 +134,61 @@ describe('/api/airports handler', () => {
expect(await a.json()).toEqual(await b.json()); expect(await a.json()).toEqual(await b.json());
}); });
}); });
describe('isRemote (v0.61.0 — ISS-097 special remote airports)', () => {
it('synthetic: an isolated point is remote; a neighbour inside the radius is not', () => {
// Equator pair: Δlon 8.5° ≈ 945 km (inside REMOTE_RADIUS_KM) vs Δlon 9.5° ≈ 1052 km (outside).
const near = [
{ icao: 'AAA', lat: 0, lon: 0 },
{ icao: 'BBB', lat: 0, lon: 8.5 },
];
expect(isRemote(near, 'AAA')).toBe(false);
expect(isRemote(near, 'BBB')).toBe(false);
const far = [
{ icao: 'AAA', lat: 0, lon: 0 },
{ icao: 'CCC', lat: 0, lon: 9.5 },
];
expect(isRemote(far, 'AAA')).toBe(true);
expect(isRemote(far, 'CCC')).toBe(true);
// A lone airport has no other member to be near — remote by definition.
expect(isRemote([{ icao: 'SOLO', lat: -77.84, lon: 166.91 }], 'SOLO')).toBe(true);
});
it('real coords: Frankfurt↔Amsterdam (~370 km) is not remote; McMurdo vs Christchurch (~3800 km) is', () => {
const eu = [
{ icao: 'EDDF', lat: 50.0376, lon: 8.5622 }, // Frankfurt Main
{ icao: 'EHAM', lat: 52.3093, lon: 13.3698 }, // Amsterdam Schiphol
];
expect(isRemote(eu, 'EDDF')).toBe(false);
const pacific = [
{ icao: 'MCDD', lat: -77.8425, lon: 166.9133 }, // McMurdo Station (Antarctica)
{ icao: 'NZCH', lat: -43.4893, lon: 172.5308 }, // Christchurch
];
expect(isRemote(pacific, 'MCDD')).toBe(true);
expect(REMOTE_RADIUS_KM).toBe(1000);
});
it('an unknown ICAO is not remote', () => {
expect(isRemote([{ icao: 'AAA', lat: 0, lon: 0 }], 'ZZZ')).toBe(false);
});
it('committed dataset curation rule: every non-large row has no large airport within REMOTE_RADIUS_KM', async () => {
const text = await fs.readFile(path.join(process.cwd(), 'data', 'airports_world.csv'), 'utf8');
const rows = filterWorldAirports(parseCsv(text));
expect(rows.length).toBeGreaterThan(0);
const large = rows.filter((r) => r.type === 'large_airport').map((r) => ({ icao: r.icao_code || r.ident, lat: +r.latitude_deg, lon: +r.longitude_deg }));
const nonLarge = rows.filter((r) => r.type !== 'large_airport');
// The dataset must actually carry the "special" airports — not just large ones.
expect(nonLarge.length).toBeGreaterThan(0);
for (const r of nonLarge) {
const self = { icao: r.icao_code || r.ident, lat: +r.latitude_deg, lon: +r.longitude_deg };
// Remote against the kept set: no LARGE airport within REMOTE_RADIUS_KM (the curation rule).
expect(isRemote([...large, self], self.icao), `${self.icao} (${r.name}) must be remote`).toBe(true);
}
});
});
+27 -3
View File
@@ -1,5 +1,6 @@
import { promises as fs } from 'node:fs'; import { promises as fs } from 'node:fs';
import path from 'node:path'; import path from 'node:path';
import { haversineKm } from './geo';
export type CsvRow = Record<string, string>; export type CsvRow = Record<string, string>;
@@ -52,15 +53,38 @@ export function parseCsv(text: string): CsvRow[] {
// The 2026 schema splits "airport" into small/medium/large_airport (older dumps used a // The 2026 schema splits "airport" into small/medium/large_airport (older dumps used a
// single "airport" type + category column) — both spellings are accepted. Heliports are // single "airport" type + category column) — both spellings are accepted. Heliports are
// excluded — no fixed-wing transport ops; other types (closed, balloonport, ...) are // excluded — no fixed-wing transport ops; other types (closed, balloonport, ...) are
// irrelevant to an airline-ops game. The committed dataset is pre-curated to large_airport // irrelevant to an airline-ops game. The committed dataset is pre-curated by
// only (scripts/build-world-airports.mjs); this check stays as a cheap guard against an // scripts/build-world-airports.mjs: every large_airport plus the small/medium/seaplane rows
// uncurated dump being swapped in. // that are REMOTE (see isRemote) — this check stays as a cheap guard against an uncurated
// dump being swapped in.
const INCLUDED_TYPES = new Set(['airport', 'small_airport', 'medium_airport', 'large_airport', 'seaplane_base']); const INCLUDED_TYPES = new Set(['airport', 'small_airport', 'medium_airport', 'large_airport', 'seaplane_base']);
export function filterWorldAirports(rows: CsvRow[]): CsvRow[] { export function filterWorldAirports(rows: CsvRow[]): CsvRow[] {
return rows.filter((r) => INCLUDED_TYPES.has(r.type)); return rows.filter((r) => INCLUDED_TYPES.has(r.type));
} }
// v0.61.0 (ISS-097): "special" remote airports — the issue's loneliness test: an airport is
// remote when no other member of `airports` sits within this radius, so it stands alone in a
// genuinely empty region (Antarctica, high Arctic, far islands) rather than being one of many.
export const REMOTE_RADIUS_KM = 1000;
export interface RemoteAirport {
icao: string;
lat: number;
lon: number;
}
// True when the airport with this ICAO has no OTHER member of `airports` within REMOTE_RADIUS_KM
// (haversine). Unknown ICACOs are not remote — callers only pass rows they intend to include.
export function isRemote(airports: readonly RemoteAirport[], icao: string): boolean {
const a = airports.find((x) => x.icao === icao);
if (!a) return false;
for (const b of airports) {
if (b.icao !== a.icao && haversineKm(a.lat, a.lon, b.lat, b.lon) <= REMOTE_RADIUS_KM) return false;
}
return true;
}
export interface AirportProperties { export interface AirportProperties {
name: string; name: string;
icao: string; icao: string;
+61
View File
@@ -0,0 +1,61 @@
import { describe, expect, it } from 'vitest';
import { SSE_PACKAGE_STATUSES, sseFrame, type PackageState, type StateSnapshot } from './state';
// ISS-133 (v0.59.0) — the SSE projection keeps only the package statuses any component renders.
const pkg = (status: PackageState['status'], id: string): PackageState => ({
id,
originIcao: 'LEMD',
originName: 'Madrid–Barajas',
destIcao: 'EHAM',
destName: 'Amsterdam Schiphol',
reward: 1000,
cargoType: 'mail',
cargoCount: 3,
weightKg: 900,
special: null,
distanceKm: 2000,
deadlineSimTime: 1_000_000,
status,
planeId: null,
createdSimTime: 0,
});
const snapshot = (packages: PackageState[]): StateSnapshot => ({
account: { cash: 20_000, reputation: 1 },
simState: { clockMs: 42 },
catalog: [],
fuelPricePerL: 0.8,
sellFraction: 0.5,
planes: [],
packages,
});
describe('sseFrame', () => {
it('keeps exactly the open/loaded/expired packages and drops terminal history', () => {
const all = [
pkg('open', 'p-open'),
pkg('delivered', 'p-delivered'),
pkg('loaded', 'p-loaded'),
pkg('abandoned', 'p-abandoned'),
pkg('expired', 'p-expired'),
pkg('ignored', 'p-ignored'),
];
const frame = sseFrame(snapshot(all));
expect(frame.packages.map((p) => p.id)).toEqual(['p-open', 'p-loaded', 'p-expired']);
});
it('passes the rest of the snapshot through untouched and does not mutate its input', () => {
const all = [pkg('open', 'a'), pkg('delivered', 'b')];
const snap = snapshot(all);
const frame = sseFrame(snap);
expect(frame.account).toEqual({ cash: 20_000, reputation: 1 });
expect(frame.simState).toEqual({ clockMs: 42 });
expect(frame.planes).toEqual([]);
expect(all.map((p) => p.status)).toContain('delivered'); // input intact
});
it('SSE_PACKAGE_STATUSES matches what the client renders (open market, on-board cargo)', () => {
expect([...SSE_PACKAGE_STATUSES].sort()).toEqual(['expired', 'loaded', 'open']);
});
});
+10
View File
@@ -85,6 +85,16 @@ export interface StateSnapshot {
sellFraction: number; sellFraction: number;
} }
// ISS-133 (v0.59.0): the SSE projection of a snapshot — only the package statuses any component
// renders: open (market list), loaded + expired (on-board cargo, which keeps its payload slot).
// Terminal history (delivered/abandoned/ignored) is unbounded in the DB and never read by the
// client, so it stays out of every pushed frame; /api/state and action responses keep the full set.
export const SSE_PACKAGE_STATUSES = ['open', 'loaded', 'expired'] as const;
export function sseFrame(snapshot: StateSnapshot): StateSnapshot {
return { ...snapshot, packages: snapshot.packages.filter((p) => (SSE_PACKAGE_STATUSES as readonly string[]).includes(p.status)) };
}
export async function getStateSnapshot(): Promise<StateSnapshot> { export async function getStateSnapshot(): Promise<StateSnapshot> {
const { db } = await getGameDb(); const { db } = await getGameDb();
// NOTE: use plain select(), not the relational db.query.* API — in drizzle-orm // NOTE: use plain select(), not the relational db.query.* API — in drizzle-orm
+40 -20
View File
@@ -16,7 +16,6 @@ import {
deliverPackages, deliverPackages,
expirePackages, expirePackages,
finishRepairs, finishRepairs,
IDLE_WORLD_TIME_SCALE,
MAX_TICK_ELAPSED_MS, MAX_TICK_ELAPSED_MS,
reputationGainFor, reputationGainFor,
shouldAdvanceTime, shouldAdvanceTime,
@@ -31,9 +30,9 @@ import {
// public tickNow()/setTestTimeScale() wrappers (singleton + lock) are covered by the e2e suite // public tickNow()/setTestTimeScale() wrappers (singleton + lock) are covered by the e2e suite
// (every spec's setScale helper hits /api/test/set-timescale; sim.spec.ts pins its validation). // (every spec's setScale helper hits /api/test/set-timescale; sim.spec.ts pins its validation).
// ISS-117 / ISS-128: fresh DBs seed a GROUNDED starter, so any test that needs FULL-scale advance // #135: fresh DBs seed a GROUNDED starter, so any test that needs clock advance must put a plane in
// must put a plane in flight first (a grounded fleet only advances at the idle real-time rate) — // flight first (a fully grounded fleet freezes the world) — departureSimTime at the game-clock
// departureSimTime at the game-clock origin keeps its arrival hours away. // origin keeps its arrival hours away.
async function makeWorldActive(inst: Awaited<ReturnType<typeof openGameDb>>) { async function makeWorldActive(inst: Awaited<ReturnType<typeof openGameDb>>) {
await inst.db.update(schema.planes) await inst.db.update(schema.planes)
.set({ status: 'flying', destIcao: 'LEMD', departureSimTime: STARTING_CLOCK_MS }) .set({ status: 'flying', destIcao: 'LEMD', departureSimTime: STARTING_CLOCK_MS })
@@ -46,11 +45,15 @@ const T0 = 1_750_000_000_000; // seed moment / fake "now" at DB open
beforeAll(async () => { beforeAll(async () => {
vi.useFakeTimers(); vi.useFakeTimers();
vi.setSystemTime(T0); vi.setSystemTime(T0);
// #135 (v0.62.0): this file exercises the FLIGHT_TEST_HOOKS branch of tickOnce — stored
// sim.timeScale overrides are only honored when the env var is set, exactly like CI.
vi.stubEnv('FLIGHT_TEST_HOOKS', '1');
dir = await fs.mkdtemp(path.join(os.tmpdir(), 'flight-sim-')); dir = await fs.mkdtemp(path.join(os.tmpdir(), 'flight-sim-'));
}); });
afterAll(async () => { afterAll(async () => {
vi.useRealTimers(); vi.useRealTimers();
vi.unstubAllEnvs();
await fs.rm(dir, { recursive: true, force: true }); await fs.rm(dir, { recursive: true, force: true });
}); });
@@ -62,7 +65,7 @@ async function freshDb(name: string) {
describe('tickOnce — clock advance', () => { describe('tickOnce — clock advance', () => {
it('advances the clock by elapsed real ms × timeScale', async () => { it('advances the clock by elapsed real ms × timeScale', async () => {
const inst = await freshDb('scale.db'); const inst = await freshDb('scale.db');
await makeWorldActive(inst); // a grounded fleet would slow the world to the idle real-time rate (ISS-128) await makeWorldActive(inst); // a fully grounded fleet freezes the clock (#135)
vi.setSystemTime(T0 + 1_000); // one real second later vi.setSystemTime(T0 + 1_000); // one real second later
await inst.db.update(schema.simState).set({ timeScale: 5 }); await inst.db.update(schema.simState).set({ timeScale: 5 });
@@ -72,30 +75,48 @@ describe('tickOnce — clock advance', () => {
expect(sim.lastRealTickMs).toBe(T0 + 1_000); expect(sim.lastRealTickMs).toBe(T0 + 1_000);
}); });
it('a fully grounded fleet advances at the idle real-time rate, not frozen (ISS-128)', async () => { it('production (no FLIGHT_TEST_HOOKS): a legacy stored timeScale is ignored — always WORLD_TIME_SCALE (#135)', async () => {
const inst = await freshDb('idle.db'); // seeded starter is on the ground → idle const inst = await freshDb('prod-rate.db');
await makeWorldActive(inst);
await inst.db.update(schema.simState).set({ timeScale: 1_000 }); // what a pre-v0.52.0 save holds
vi.setSystemTime(T0 + 1_000);
const saved = process.env.FLIGHT_TEST_HOOKS;
delete process.env.FLIGHT_TEST_HOOKS;
let sim: schema.SimStateRow;
try {
sim = await tickOnce(inst);
} finally {
if (saved !== undefined) process.env.FLIGHT_TEST_HOOKS = saved; // restore the stubbed value
}
expect(sim.clockMs).toBe(STARTING_CLOCK_MS + 1_000 * WORLD_TIME_SCALE); // ×24, NOT ×1000
});
it('a fully grounded fleet freezes the clock, then resumes with no catch-up (#135)', async () => {
const inst = await freshDb('idle.db'); // seeded starter is on the ground → frozen
vi.setSystemTime(T0 + 3_600_000); // an hour of real idleness vi.setSystemTime(T0 + 3_600_000); // an hour of real idleness
let sim = await tickOnce(inst); let sim = await tickOnce(inst);
expect(sim.clockMs).toBe(STARTING_CLOCK_MS + MAX_TICK_ELAPSED_MS * IDLE_WORLD_TIME_SCALE); // clamped to one idle-rate tick — no fast-forward, no freeze expect(sim.clockMs).toBe(STARTING_CLOCK_MS); // frozen — no fast-forward, no idle creep
expect(sim.lastRealTickMs).toBe(T0 + 3_600_000); expect(sim.lastRealTickMs).toBe(T0 + 3_600_000);
// A plane takes off: resumes from where it stopped, with NO catch-up for the idle time. // A plane takes off: resumes from where it stopped, with NO catch-up for the frozen time.
await inst.db.update(schema.simState).set({ timeScale: 60 }); await inst.db.update(schema.simState).set({ timeScale: 60 });
await makeWorldActive(inst); await makeWorldActive(inst);
vi.setSystemTime(T0 + 3_600_500); vi.setSystemTime(T0 + 3_600_500);
sim = await tickOnce(inst); sim = await tickOnce(inst);
expect(sim.clockMs).toBe(STARTING_CLOCK_MS + MAX_TICK_ELAPSED_MS * IDLE_WORLD_TIME_SCALE + 500 * 60); // only the 500 ms since activity × 60 expect(sim.clockMs).toBe(STARTING_CLOCK_MS + 500 * 60); // only the 500 ms since activity × 60
}); });
it('a grounded fleet ignores any raised timeScale — the idle rate wins (ISS-128)', async () => { it('a grounded fleet ignores any raised timeScale — frozen regardless (#135)', async () => {
const inst = await freshDb('idle-scale.db'); const inst = await freshDb('idle-scale.db');
await inst.db.update(schema.simState).set({ timeScale: 1_000 }); // FLIGHT_TEST_HOOKS-style override await inst.db.update(schema.simState).set({ timeScale: 1_000 }); // FLIGHT_TEST_HOOKS-style override
vi.setSystemTime(T0 + 1_000); vi.setSystemTime(T0 + 1_000);
const sim = await tickOnce(inst); const sim = await tickOnce(inst);
expect(sim.clockMs).toBe(STARTING_CLOCK_MS + 1_000 * IDLE_WORLD_TIME_SCALE); // real time, NOT ×1000 expect(sim.clockMs).toBe(STARTING_CLOCK_MS); // frozen, NOT ×1000
}); });
it('clamps long absences: a 1-hour gap advances at most MAX_TICK_ELAPSED_MS × scale', async () => { it('clamps long absences: a 1-hour gap advances at most MAX_TICK_ELAPSED_MS × scale', async () => {
@@ -586,13 +607,12 @@ describe('finishRepairs (v0.39.0, ISS-069)', () => {
}); });
}); });
describe('idle slowdown — a grounded fleet slows the world to real time (ISS-128)', () => { describe('grounded fleet freezes the world clock (#135)', () => {
it('pins IDLE_WORLD_TIME_SCALE = WORLD_TIME_SCALE / 24, i.e. exactly real time', () => { it('pins WORLD_TIME_SCALE = 24 — the single fixed world rate (ISS-117)', () => {
expect(IDLE_WORLD_TIME_SCALE).toBe(WORLD_TIME_SCALE / 24); expect(WORLD_TIME_SCALE).toBe(24);
expect(IDLE_WORLD_TIME_SCALE).toBe(1); // one game-second per real second
}); });
it('shouldAdvanceTime: grounded/empty fleets are idle; any flying or repairing plane advances', () => { it('shouldAdvanceTime: grounded/empty fleets are frozen; any flying or repairing plane advances', () => {
expect(shouldAdvanceTime([])).toEqual({ advance: false, flying: 0, repairing: 0 }); expect(shouldAdvanceTime([])).toEqual({ advance: false, flying: 0, repairing: 0 });
expect(shouldAdvanceTime([{ status: 'available' }, { status: 'available' }])).toEqual({ advance: false, flying: 0, repairing: 0 }); expect(shouldAdvanceTime([{ status: 'available' }, { status: 'available' }])).toEqual({ advance: false, flying: 0, repairing: 0 });
expect(shouldAdvanceTime([{ status: 'flying' }, { status: 'available' }])).toEqual({ advance: true, flying: 1, repairing: 0 }); expect(shouldAdvanceTime([{ status: 'flying' }, { status: 'available' }])).toEqual({ advance: true, flying: 1, repairing: 0 });
@@ -600,13 +620,13 @@ describe('idle slowdown — a grounded fleet slows the world to real time (ISS-1
expect(shouldAdvanceTime([{ status: 'flying' }, { status: 'repairing' }])).toEqual({ advance: true, flying: 1, repairing: 1 }); expect(shouldAdvanceTime([{ status: 'flying' }, { status: 'repairing' }])).toEqual({ advance: true, flying: 1, repairing: 1 });
}); });
it('a fully grounded fleet advances at the idle rate but keeps tracking real time', async () => { it('a fully grounded fleet stays frozen but keeps tracking real time', async () => {
const inst = await freshDb('idle-pause.db'); // seeded starter is on the ground → idle const inst = await freshDb('idle-pause.db'); // seeded starter is on the ground → frozen
vi.setSystemTime(T0 + 3_600_000); vi.setSystemTime(T0 + 3_600_000);
const sim = await tickOnce(inst); const sim = await tickOnce(inst);
expect(sim.clockMs).toBe(STARTING_CLOCK_MS + MAX_TICK_ELAPSED_MS * IDLE_WORLD_TIME_SCALE); // real-time rate, clamped — not frozen expect(sim.clockMs).toBe(STARTING_CLOCK_MS); // frozen — no idle creep
expect(sim.lastRealTickMs).toBe(T0 + 3_600_000); // …and the real-time anchor moved on expect(sim.lastRealTickMs).toBe(T0 + 3_600_000); // …and the real-time anchor moved on
}); });
+28 -23
View File
@@ -7,9 +7,9 @@ import { haversineKm, initialBearingDeg } from '@/lib/geo';
import { weatherFor } from '@/lib/weather'; import { weatherFor } from '@/lib/weather';
import { FUEL_DISCOUNT_PER_REP, FUEL_PRICE_PER_L, MAX_FUEL_DISCOUNT, PLANE_TYPES, REPAIR_DURATION_MS, repRate, WEAR_PER_KM } from '@/lib/game/catalog'; import { FUEL_DISCOUNT_PER_REP, FUEL_PRICE_PER_L, MAX_FUEL_DISCOUNT, PLANE_TYPES, REPAIR_DURATION_MS, repRate, WEAR_PER_KM } from '@/lib/game/catalog';
import { SPECIALS } from '@/lib/game/specials'; import { SPECIALS } from '@/lib/game/specials';
import { getStateSnapshot, parseIcaoQueue } from '@/lib/game/state'; import { getStateSnapshot, parseIcaoQueue, sseFrame } from '@/lib/game/state';
import { broadcast } from '@/lib/sse'; import { broadcast } from '@/lib/sse';
import { IDLE_WORLD_TIME_SCALE } from '@/lib/worldClock';
import { import {
generatePackage, generatePackage,
MARKET_TARGET_OPEN_PACKAGES, MARKET_TARGET_OPEN_PACKAGES,
@@ -22,10 +22,12 @@ import { arrivalTimeFor, fuelAtWeighted, requiredFuelFor, windBurnFactor } from
// Server-authoritative sim engine (v0.7.0). ISS-117 (v0.52.0): the clock advances on a background // Server-authoritative sim engine (v0.7.0). ISS-117 (v0.52.0): the clock advances on a background
// tick (~1 s, started at boot from instrumentation.ts) AND on every read/action — both through the // tick (~1 s, started at boot from instrumentation.ts) AND on every read/action — both through the
// same locked tickOnce path. Each tick advances by (real ms since last tick) × timeScale, clamped // same locked tickOnce path. Each tick advances by (real ms since last tick) × scale, clamped per
// per tick so long absences never fast-forward the game; while no plane is flying or in repair the // tick so long absences never fast-forward the game; while no plane is flying or in repair the
// world slows to real time instead of freezing (IDLE_WORLD_TIME_SCALE, ISS-128 v0.56.0), and // world clock stays FROZEN (#135 v0.62.0 — final ISS-117 semantics), and lastRealTickMs always
// lastRealTickMs always keeps tracking real time. // keeps tracking real time, so resuming activity never fast-forwards the frozen span. Scale is the
// fixed WORLD_TIME_SCALE in production; only FLIGHT_TEST_HOOKS deployments honor sim.timeScale
// (the test-hook override) — legacy saves may hold stale values (#135).
// Clamp constant: max real-time gap counted by a single tick. Chosen at 2000 ms — comfortably above // Clamp constant: max real-time gap counted by a single tick. Chosen at 2000 ms — comfortably above
// both the client poll interval (~1 s) and the background-tick interval, so active play advances // both the client poll interval (~1 s) and the background-tick interval, so active play advances
@@ -33,9 +35,10 @@ import { arrivalTimeFor, fuelAtWeighted, requiredFuelFor, windBurnFactor } from
// 2 s × scale. // 2 s × scale.
export const MAX_TICK_ELAPSED_MS = 2_000; export const MAX_TICK_ELAPSED_MS = 2_000;
// ISS-117 / ISS-128: the fixed world rates — re-exported here so server code and tests have one // ISS-117: the fixed world rate — imported for tickOnce, re-exported so server code and tests
// familiar home (full rate while something is active, real-time rate while fully grounded). // have one familiar home.
export { IDLE_WORLD_TIME_SCALE, WORLD_TIME_SCALE } from '@/lib/worldClock'; import { WORLD_TIME_SCALE } from '@/lib/worldClock';
export { WORLD_TIME_SCALE };
// Reputation gain per delivered package: BASE + PER_KM × great-circle km, rounded // Reputation gain per delivered package: BASE + PER_KM × great-circle km, rounded
// to 2 decimals (reputation is REAL). A short hop (~300 km) earns ~1.15 rep, a // to 2 decimals (reputation is REAL). A short hop (~300 km) earns ~1.15 rep, a
@@ -64,10 +67,10 @@ function withLock<T>(fn: () => Promise<T>): Promise<T> {
// --- Tick core (takes a GameDb so unit tests can inject their own instance) --- // --- Tick core (takes a GameDb so unit tests can inject their own instance) ---
// ISS-117 / ISS-128: idle decision — pure, so unit tests feed it synthetic fleets. The world clock // #135: advance decision — pure, so unit tests feed it synthetic fleets. The world clock runs at
// runs at full scale only while something is happening (at least one plane flying OR in repair); a // full scale only while something is happening (at least one plane flying OR in repair); a fully
// fully grounded fleet slows it to IDLE_WORLD_TIME_SCALE (real time) instead of freezing it, so // grounded fleet freezes it entirely — no expiry/spawn/repair progress until a dispatch or repair
// expiries/spawns keep running until a dispatch or repair starts. // starts again.
export function shouldAdvanceTime(planes: Array<{ status: string }>): { advance: boolean; flying: number; repairing: number } { export function shouldAdvanceTime(planes: Array<{ status: string }>): { advance: boolean; flying: number; repairing: number } {
let flying = 0; let flying = 0;
let repairing = 0; let repairing = 0;
@@ -84,15 +87,16 @@ export async function tickOnce(inst: GameDb): Promise<schema.SimStateRow> {
if (!sim) throw new Error('sim_state row missing'); if (!sim) throw new Error('sim_state row missing');
const nowMs = Date.now(); const nowMs = Date.now();
// ISS-128: a fully grounded fleet slows the world to real time (IDLE_WORLD_TIME_SCALE) instead of // #135: a fully grounded fleet freezes the world — no advance, no expiry/spawn/repair progress.
// freezing it — packages keep spawning/expiring while idle. An active fleet keeps its full scale, // lastRealTickMs always tracks real time, so resuming activity never fast-forwards the frozen span.
// including any FLIGHT_TEST_HOOKS override in sim.timeScale. lastRealTickMs always tracks real
// time, so resuming activity never fast-forwards the idle duration.
const planeRows = await inst.db.select().from(schema.planes); const planeRows = await inst.db.select().from(schema.planes);
const { advance } = shouldAdvanceTime(planeRows.map((p) => ({ status: p.status }))); const { advance } = shouldAdvanceTime(planeRows.map((p) => ({ status: p.status })));
// #135 (v0.62.0): production ALWAYS runs at the fixed world rate — legacy saves may hold a stale
// timeScale (e.g. 1000 from pre-v0.52.0 UI controls, or an old e2e run against the live instance).
// Only FLIGHT_TEST_HOOKS deployments honor sim.timeScale, which POST /api/test/set-timescale writes.
const scale = process.env.FLIGHT_TEST_HOOKS === '1' ? sim.timeScale : WORLD_TIME_SCALE;
const elapsed = Math.max(0, nowMs - sim.lastRealTickMs); const elapsed = Math.max(0, nowMs - sim.lastRealTickMs);
const scale = advance ? sim.timeScale : IDLE_WORLD_TIME_SCALE; const advanceMs = advance ? Math.min(elapsed, MAX_TICK_ELAPSED_MS) * scale : 0;
const advanceMs = Math.min(elapsed, MAX_TICK_ELAPSED_MS) * scale;
const clockMs = Math.round(sim.clockMs + advanceMs); const clockMs = Math.round(sim.clockMs + advanceMs);
if (advanceMs > 0) { if (advanceMs > 0) {
@@ -420,12 +424,13 @@ export async function spawnCoveragePackages(
// --- Public API (singleton DB + lock) — call from every read/action endpoint --- // --- Public API (singleton DB + lock) — call from every read/action endpoint ---
// ISS-129 (v0.57.0): after each tick on the singleton path, push a fresh snapshot to all SSE // ISS-129 (v0.57.0): after each tick on the singleton path, push a fresh snapshot to all SSE
// subscribers (/api/events) — the exact same body GET /api/state returns (getStateSnapshot), so // subscribers (/api/events). ISS-133 (v0.59.0): frames carry the sseFrame projection — terminal
// pushed and polled states can never diverge in shape. Failures are logged, not fatal: polling // package history is dropped, everything else matches GET /api/state exactly. Failures are logged,
// still works either way. Background ticks (~1 s) cover action mutations for other clients too. // not fatal: polling still works either way. Background ticks (~1 s) cover action mutations for
// other clients too.
async function broadcastState(): Promise<void> { async function broadcastState(): Promise<void> {
try { try {
broadcast(JSON.stringify(await getStateSnapshot())); broadcast(JSON.stringify(sseFrame(await getStateSnapshot())));
} catch (err) { } catch (err) {
console.error('flight: state broadcast failed', err); console.error('flight: state broadcast failed', err);
} }
+6 -6
View File
@@ -1,11 +1,11 @@
import { describe, expect, it } from 'vitest'; import { describe, expect, it } from 'vitest';
import { advanceSimClock, type SimClockAnchor } from './useSimClock'; import { advanceSimClock, type SimClockAnchor } from './useSimClock';
import { IDLE_WORLD_TIME_SCALE, WORLD_TIME_SCALE } from './worldClock'; import { WORLD_TIME_SCALE } from './worldClock';
// ISS-007 (v0.16.1) — the pure extrapolation core of lib/useSimClock.ts. The hook itself is a // ISS-007 (v0.16.1) — the pure extrapolation core of lib/useSimClock.ts. The hook itself is a
// thin setInterval + re-sync wrapper covered by e2e (panes.spec.ts "ticks smoothly between polls"); // thin setInterval + re-sync wrapper covered by e2e (panes.spec.ts "ticks smoothly between polls");
// this suite pins the math: game time advances real-time × WORLD_TIME_SCALE, and slows to // this suite pins the math: game time advances real-time × WORLD_TIME_SCALE while something is
// real-time × IDLE_WORLD_TIME_SCALE while idle (ISS-128). // flying or in repair, and stays frozen at the anchor value while fully grounded (#135).
const anchor = (over: Partial<SimClockAnchor> = {}): SimClockAnchor => ({ const anchor = (over: Partial<SimClockAnchor> = {}): SimClockAnchor => ({
clockMs: 1_750_000_000_000, clockMs: 1_750_000_000_000,
@@ -25,10 +25,10 @@ describe('advanceSimClock', () => {
expect(advanceSimClock(anchor(), 1_000_000)).toBe(1_750_000_000_000); expect(advanceSimClock(anchor(), 1_000_000)).toBe(1_750_000_000_000);
}); });
it('advances at the idle real-time rate (IDLE_WORLD_TIME_SCALE) while grounded, not frozen (ISS-128)', () => { it('stays exactly at the anchor value while grounded (frozen, #135)', () => {
const a = anchor({ advancing: false }); const a = anchor({ advancing: false });
expect(advanceSimClock(a, 1_000_000)).toBe(1_750_000_000_000); // zero elapsed — still the anchor value expect(advanceSimClock(a, 1_000_000)).toBe(1_750_000_000_000); // zero elapsed — the anchor value
expect(advanceSimClock(a, 1_001_000)).toBe(1_750_000_000_000 + 1_000 * IDLE_WORLD_TIME_SCALE); // a full second later — real time, not frozen expect(advanceSimClock(a, 1_001_000)).toBe(1_750_000_000_000); // a full second later — still frozen
}); });
it('clamps to the anchor value when nowMs is before the anchor (clock skew), never backwards', () => { it('clamps to the anchor value when nowMs is before the anchor (clock skew), never backwards', () => {
+7 -8
View File
@@ -2,16 +2,15 @@
import { useEffect, useRef, useState } from 'react'; import { useEffect, useRef, useState } from 'react';
import type { StateSnapshot } from './game/state'; import type { StateSnapshot } from './game/state';
import { IDLE_WORLD_TIME_SCALE, WORLD_TIME_SCALE } from './worldClock'; import { WORLD_TIME_SCALE } from './worldClock';
// ISS-007 (v0.16.1): the sim clock ticks smoothly on the CLIENT between polls instead of // ISS-007 (v0.16.1): the sim clock ticks smoothly on the CLIENT between polls instead of
// jumping once per snapshot. The server's authoritative rate is exactly real-time × scale // jumping once per snapshot. The server's authoritative rate is exactly real-time × scale
// (tickOnce in lib/sim/engine.ts: advance = min(elapsed, MAX_TICK_ELAPSED_MS) × timeScale), so // (tickOnce in lib/sim/engine.ts: advance = min(elapsed, MAX_TICK_ELAPSED_MS) × timeScale), so
// client-side extrapolation mirrors the server's own model. Every new snapshot re-anchors to // client-side extrapolation mirrors the server's own model. Every new snapshot re-anchors to
// server truth, bounding any drift by network latency only. ISS-117 (v0.52.0): the scale is the // server truth, bounding any drift by network latency only. ISS-117 (v0.52.0): the scale is the
// fixed WORLD_TIME_SCALE; ISS-128 (v0.56.0): while nothing is happening it slows to // fixed WORLD_TIME_SCALE; #135 (v0.62.0): while nothing is happening it stays FROZEN at the anchor
// IDLE_WORLD_TIME_SCALE (real time) instead of freezing — mirroring the server's idle slowdown, // value — mirroring the server's freeze, so polls re-anchor without any jump.
// so polls re-anchor without a visible jump.
export interface SimClockAnchor { export interface SimClockAnchor {
// Server truth at anchor time — the snapshot's simState.clockMs. // Server truth at anchor time — the snapshot's simState.clockMs.
@@ -23,11 +22,11 @@ export interface SimClockAnchor {
} }
// Pure core of the extrapolation — mirrors tickOnce: while advancing, game time advances by // Pure core of the extrapolation — mirrors tickOnce: while advancing, game time advances by
// real-time × WORLD_TIME_SCALE; while idle it slows to real-time × IDLE_WORLD_TIME_SCALE (ISS-128). // real-time × WORLD_TIME_SCALE; while fully grounded it stays frozen at the anchor value (#135).
// nowMs before `at` clamps to the anchor value instead of going backwards. Unit-testable in node. // nowMs before `at` clamps to the anchor value instead of going backwards. Unit-testable in node.
export function advanceSimClock(anchor: SimClockAnchor, nowMs: number): number { export function advanceSimClock(anchor: SimClockAnchor, nowMs: number): number {
const scale = anchor.advancing ? WORLD_TIME_SCALE : IDLE_WORLD_TIME_SCALE; if (!anchor.advancing) return anchor.clockMs; // frozen while everything is grounded (#135)
return anchor.clockMs + Math.max(0, nowMs - anchor.at) * scale; return anchor.clockMs + Math.max(0, nowMs - anchor.at) * WORLD_TIME_SCALE;
} }
// ~10 fps display refresh — smooth for a seconds-precision wall clock without busy re-renders. // ~10 fps display refresh — smooth for a seconds-precision wall clock without busy re-renders.
@@ -43,7 +42,7 @@ export function useSimClock(snapshot: StateSnapshot | null): number | null {
useEffect(() => { useEffect(() => {
if (!snapshot) return; if (!snapshot) return;
// Mirror of the server's shouldAdvanceTime (lib/sim/engine.ts): full rate only while a plane // Mirror of the server's shouldAdvanceTime (lib/sim/engine.ts): full rate only while a plane
// is flying or in repair, idle real-time otherwise. One line on purpose — keep it in sync. // is flying or in repair, frozen otherwise (#135). One line on purpose — keep it in sync.
const advancing = snapshot.planes.some((p) => p.status === 'flying' || p.status === 'repairing'); const advancing = snapshot.planes.some((p) => p.status === 'flying' || p.status === 'repairing');
anchorRef.current = { clockMs: snapshot.simState.clockMs, at: Date.now(), advancing }; anchorRef.current = { clockMs: snapshot.simState.clockMs, at: Date.now(), advancing };
setDisplayMs(advanceSimClock(anchorRef.current, Date.now())); setDisplayMs(advanceSimClock(anchorRef.current, Date.now()));
+5 -4
View File
@@ -3,7 +3,8 @@
// lib/useSimClock.ts extrapolates between polls at this same constant, so keep them in sync here. // lib/useSimClock.ts extrapolates between polls at this same constant, so keep them in sync here.
export const WORLD_TIME_SCALE = 24; export const WORLD_TIME_SCALE = 24;
// ISS-128 (v0.56.0): a fully grounded fleet no longer freezes the world — it slows to real time // #135 (v0.62.0): a fully grounded fleet FREEZES the world clock — shouldAdvanceTime
// (one game-second per real second) so packages keep spawning/expiring and the market stays fresh. // (lib/sim/engine.ts) gates every tick and advanceSimClock (lib/useSimClock.ts) holds its anchor
// Derived from the existing constant: WORLD_TIME_SCALE / 24 = 1, i.e. exactly "real-time". // value, so polls re-anchor without any jump. This replaces the v0.56.0 idle slowdown
export const IDLE_WORLD_TIME_SCALE = WORLD_TIME_SCALE / 24; // (IDLE_WORLD_TIME_SCALE = WORLD_TIME_SCALE / 24): final semantics are ISS-117's — frozen when
// everything is grounded, full rate otherwise.
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "flight-ops", "name": "flight-ops",
"version": "0.58.0", "version": "0.63.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev -p 3000", "dev": "next dev -p 3000",
+54 -18
View File
@@ -3,6 +3,10 @@
// //
// Pipeline: download → keep `large_airport` rows only (same density curation as the EU file, // Pipeline: download → keep `large_airport` rows only (same density curation as the EU file,
// v0.2.8) → greedy 40 km haversine clustering → one airport per cluster ("the biggest"). // v0.2.8) → greedy 40 km haversine clustering → one airport per cluster ("the biggest").
// v0.61.0 (ISS-097): additionally keeps every non-large fixed-wing row that is REMOTE — no other
// airport within 1000 km of the kept set (lib/airports.ts isRemote) — so Antarctica, the high
// Arctic, Alaska, northern Canada and far islands are represented even though they carry no
// large_airport; same-station twins collapse via the same 40 km clustering.
// The output keeps the exact OurAirports header so lib/airports.ts parses it unchanged. // The output keeps the exact OurAirports header so lib/airports.ts parses it unchanged.
// //
// Usage: node scripts/build-world-airports.mjs (writes data/airports_world.csv, prints stats) // Usage: node scripts/build-world-airports.mjs (writes data/airports_world.csv, prints stats)
@@ -14,6 +18,22 @@ import path from 'node:path';
const SOURCE_URL = 'https://davidmegginson.github.io/ourairports-data/airports.csv'; // legacy ourairports.com/data URL is dead (see CHANGELOG v0.1.0) const SOURCE_URL = 'https://davidmegginson.github.io/ourairports-data/airports.csv'; // legacy ourairports.com/data URL is dead (see CHANGELOG v0.1.0)
const OUT_FILE = path.join(import.meta.dirname, '..', 'data', 'airports_world.csv'); const OUT_FILE = path.join(import.meta.dirname, '..', 'data', 'airports_world.csv');
const CLUSTER_RADIUS_KM = 40; // mid of the issue's 30–50 km range — n≈1k rows makes O(n²) trivial const CLUSTER_RADIUS_KM = 40; // mid of the issue's 30–50 km range — n≈1k rows makes O(n²) trivial
// v0.61.0 (ISS-097): mirrors REMOTE_RADIUS_KM in lib/airports.ts — "no other airport within this
// radius" is what makes a small airport worth keeping (Antarctica, high Arctic, far islands).
const REMOTE_RADIUS_KM = 1000;
// Same fixed-wing type set as INCLUDED_TYPES in lib/airports.ts (standalone copy — the script must
// stay dependency-free): all fixed-wing airports plus seaplane bases.
const FIXED_WING_TYPES = new Set(['airport', 'small_airport', 'medium_airport', 'large_airport', 'seaplane_base']);
// Standalone copy of isRemote in lib/airports.ts, for CSV rows: true when `row` has no member of
// `others` within REMOTE_RADIUS_KM. Callers pass disjoint sets (the row itself is not in `others`).
function isRemoteRow(row, others) {
for (const o of others) {
if (haversineKm(row, o) <= REMOTE_RADIUS_KM) return false;
}
return true;
}
// --- Minimal RFC-4180 parser (same semantics as lib/airports.ts parseCsv, standalone copy) --- // --- Minimal RFC-4180 parser (same semantics as lib/airports.ts parseCsv, standalone copy) ---
function parseCsv(text) { function parseCsv(text) {
@@ -86,26 +106,33 @@ const header = headerLine.replace(/\r$/, '').split(',').map((h) => h.replace(/^"
if (header.length !== 19) { console.error(`unexpected header (${header.length} columns): ${headerLine}`); process.exit(1); } if (header.length !== 19) { console.error(`unexpected header (${header.length} columns): ${headerLine}`); process.exit(1); }
const allRows = parseCsv(text); const allRows = parseCsv(text);
const large = allRows.filter((r) => r.type === 'large_airport'); // v0.61.0 (ISS-097): curation runs over ALL fixed-wing rows, not just large_airport — the remote
console.log(`downloaded ${allRows.length} rows; ${large.length} are large_airport`); // pass below needs the full pool to test against.
const fixed = allRows.filter((r) => FIXED_WING_TYPES.has(r.type));
const large = fixed.filter((r) => r.type === 'large_airport');
console.log(`downloaded ${allRows.length} rows; ${fixed.length} are fixed-wing, ${large.length} of them large_airport`);
// Greedy clustering in file order: a row joins the first cluster whose anchor is within the // Greedy clustering in file order: a row joins the first cluster whose anchor is within the
// radius, otherwise it starts a new one. Deterministic — same input, same output. // radius, otherwise it starts a new one. Deterministic — same input, same output. Returns the
const clusters = []; // { anchorIdx (into `large`), members } // "biggest" member (one airport per cluster) plus the clusters themselves for reporting.
for (let i = 0; i < large.length; i++) { function clusterWinners(rows) {
let joined = false; const clusters = []; // { anchorIdx (into rows), members }
for (const c of clusters) { for (let i = 0; i < rows.length; i++) {
if (haversineKm(large[i], large[c.anchorIdx]) <= CLUSTER_RADIUS_KM) { c.members.push(i); joined = true; break; } let joined = false;
for (const c of clusters) {
if (haversineKm(rows[i], rows[c.anchorIdx]) <= CLUSTER_RADIUS_KM) { c.members.push(i); joined = true; break; }
}
if (!joined) clusters.push({ anchorIdx: i, members: [i] });
} }
if (!joined) clusters.push({ anchorIdx: i, members: [i] }); const winners = clusters.map((c) => biggestOf(c.members.map((i) => rows[i])));
return { winners, clusters };
} }
const kept = []; const { winners: kept, clusters: largeClusters } = clusterWinners(large);
const multiClusters = []; const multiClusters = [];
for (const c of clusters) { for (const c of largeClusters) {
const winner = biggestOf(c.members.map((i) => large[i]));
kept.push(winner);
if (c.members.length > 1) { if (c.members.length > 1) {
const winner = biggestOf(c.members.map((i) => large[i]));
multiClusters.push({ multiClusters.push({
city: winner.municipality || winner.name, city: winner.municipality || winner.name,
keptIcao: winner.icao_code || winner.ident, keptIcao: winner.icao_code || winner.ident,
@@ -114,17 +141,26 @@ for (const c of clusters) {
} }
} }
// v0.61.0 (ISS-097): "special" remote airports — every non-large fixed-wing row with no other
// airport within REMOTE_RADIUS_KM of the kept set joins the dataset, so empty regions get their
// real (small) airports instead of nothing. Same-station twins (two strips <40 km apart at one
// base) collapse via the same greedy clustering as above.
const remote = fixed.filter((r) => r.type !== 'large_airport' && isRemoteRow(r, kept));
const { winners: remoteKept } = clusterWinners(remote);
// --- Guards (fail loud before writing anything) --- // --- Guards (fail loud before writing anything) ---
const finalRows = [...kept, ...remoteKept];
const key = (r) => r.icao_code || r.ident; // the effective ICAO consumers key by (toGeoJson fallback) const key = (r) => r.icao_code || r.ident; // the effective ICAO consumers key by (toGeoJson fallback)
const keys = new Set(kept.map(key)); const keys = new Set(finalRows.map(key));
if (keys.size !== kept.length) { console.error('duplicate ICAO in curated set — aborting'); process.exit(1); } if (keys.size !== finalRows.length) { console.error('duplicate ICAO in curated set — aborting'); process.exit(1); }
for (const must of ['EDDF', 'UNNT', 'LPPD']) { // EDDF is the seed hub; UNNT (Novosibirsk) + LPPD (Ponta Delgada) pin the 409-backstop test pair for (const must of ['EDDF', 'UNNT', 'LPPD']) { // EDDF is the seed hub; UNNT (Novosibirsk) + LPPD (Ponta Delgada) pin the 409-backstop test pair
if (!keys.has(must)) { console.error(`required airport ${must} missing from curated set — aborting`); process.exit(1); } if (!keys.has(must)) { console.error(`required airport ${must} missing from curated set — aborting`); process.exit(1); }
} }
if (kept.length < 300 || kept.length > 2500) { console.error(`unexpected row count ${kept.length}`); process.exit(1); } if (remoteKept.length === 0) { console.error('no remote airports found in the dump — curation rule broken, aborting'); process.exit(1); }
if (finalRows.length < 300 || finalRows.length > 2500) { console.error(`unexpected row count ${finalRows.length}`); process.exit(1); }
await fs.writeFile(OUT_FILE, [headerLine.replace(/\r$/, ''), ...kept.map((r) => header.map((h) => `"${String(r[h] ?? '').replace(/"/g, '""')}"`).join(','))].join('\n') + '\n', 'utf8'); await fs.writeFile(OUT_FILE, [headerLine.replace(/\r$/, ''), ...finalRows.map((r) => header.map((h) => `"${String(r[h] ?? '').replace(/"/g, '""')}"`).join(','))].join('\n') + '\n', 'utf8');
console.log(`wrote ${OUT_FILE}: ${kept.length} rows kept, ${large.length - kept.length} dropped into ${multiClusters.length} multi-airport clusters`); console.log(`wrote ${OUT_FILE}: ${kept.length} large + ${remoteKept.length} remote = ${finalRows.length} rows (${large.length - kept.length} large dropped into ${multiClusters.length} multi-airport clusters)`);
console.log('sample merged cities (kept ← dropped):'); console.log('sample merged cities (kept ← dropped):');
for (const c of multiClusters.slice(0, 15)) console.log(` ${c.city}: kept ${c.keptIcao} ← ${c.dropped.join(', ')}`); for (const c of multiClusters.slice(0, 15)) console.log(` ${c.city}: kept ${c.keptIcao} ← ${c.dropped.join(', ')}`);