// NL cities we can place on the homepage map, pre-projected into the 240x300 viewBox // (bbox lon 3.30-7.25, lat 50.72-53.60). The location stat and the map both resolve // member locations through matchNlCity, so the count always equals the plotted dots. // The map is deliberately NL-only: members living abroad are welcome but do not appear here. export const NL_CITIES: Record = { Amsterdam: [97.5, 128.4], Rotterdam: [71.6, 174.5], 'The Hague': [60.8, 159.3], Utrecht: [110.7, 157.2], Eindhoven: [131.8, 224.8], Groningen: [198.5, 39.6], Tilburg: [108.8, 212.4], Almere: [119.4, 130.1], Breda: [89.2, 211.3], Nijmegen: [154.2, 186.2], Enschede: [218.4, 143.6], Haarlem: [81.8, 126.3], Arnhem: [157.9, 168.2], Amersfoort: [126.9, 150.4], "'s-Hertogenbosch": [121.7, 198.1], Zwolle: [169.1, 112.8], Leiden: [72.7, 150.0], Maastricht: [145.3, 286.3], Delft: [64.2, 165.5], Alkmaar: [88.3, 100.8], 'Sprang-Capelle': [99.2, 201.4], Deventer: [174.0, 140.1], Leeuwarden: [151.9, 41.5], }; // Aliases that should resolve to a canonical key in NL_CITIES. const ALIASES: Record = { 'den haag': 'The Hague', "'s-gravenhage": 'The Hague', "den bosch": "'s-Hertogenbosch", }; /** Resolve a Sifa location string to a canonical NL city key, or null if it is not * an NL city we can place (bare country, non-NL city, or unknown town). */ export function matchNlCity(location: string): string | null { const raw = location.split(',')[0].trim(); if (!raw) return null; if (Object.prototype.hasOwnProperty.call(NL_CITIES, raw)) return raw; const lc = raw.toLowerCase(); if (ALIASES[lc]) return ALIASES[lc]; for (const key of Object.keys(NL_CITIES)) { if (key.toLowerCase() === lc) return key; } return null; }