137 lines
3.2 KiB
JavaScript
137 lines
3.2 KiB
JavaScript
// countries.js — country data and helpers
|
|
|
|
/**
|
|
* @typedef {{ name: string, x: number, y: number }} City
|
|
* @typedef {{ name: string, hint: string, cities: City[] }} Country
|
|
*/
|
|
|
|
const Countries = (() => {
|
|
/** @type {Country[]} */
|
|
const COUNTRIES_DATA = [
|
|
{
|
|
name: "Switzerland",
|
|
hint: "Alpine country in Central Europe",
|
|
cities: [
|
|
{ name: "Bern", x: 48, y: 58 },
|
|
{ name: "Zürich", x: 58, y: 38 },
|
|
{ name: "Geneva", x: 22, y: 72 },
|
|
],
|
|
},
|
|
{
|
|
name: "Norway",
|
|
hint: "Scandinavian country with long coastline",
|
|
cities: [
|
|
{ name: "Oslo", x: 55, y: 72 },
|
|
{ name: "Bergen", x: 32, y: 60 },
|
|
{ name: "Tromsø", x: 62, y: 18 },
|
|
],
|
|
},
|
|
{
|
|
name: "Italy",
|
|
hint: "Boot-shaped peninsula in Southern Europe",
|
|
cities: [
|
|
{ name: "Rome", x: 52, y: 58 },
|
|
{ name: "Milan", x: 42, y: 22 },
|
|
{ name: "Naples", x: 58, y: 72 },
|
|
],
|
|
},
|
|
{
|
|
name: "Japan",
|
|
hint: "Island nation in East Asia",
|
|
cities: [
|
|
{ name: "Tokyo", x: 72, y: 48 },
|
|
{ name: "Osaka", x: 58, y: 58 },
|
|
{ name: "Sapporo", x: 70, y: 22 },
|
|
],
|
|
},
|
|
{
|
|
name: "Brazil",
|
|
hint: "Largest country in South America",
|
|
cities: [
|
|
{ name: "Brasília", x: 58, y: 52 },
|
|
{ name: "São Paulo", x: 60, y: 68 },
|
|
{ name: "Manaus", x: 38, y: 38 },
|
|
],
|
|
},
|
|
{
|
|
name: "Australia",
|
|
hint: "Continent and country in the Southern Hemisphere",
|
|
cities: [
|
|
{ name: "Canberra", x: 72, y: 72 },
|
|
{ name: "Sydney", x: 78, y: 68 },
|
|
{ name: "Perth", x: 22, y: 65 },
|
|
],
|
|
},
|
|
{
|
|
name: "France",
|
|
hint: "Western Europe, roughly hexagonal shape",
|
|
cities: [
|
|
{ name: "Paris", x: 50, y: 32 },
|
|
{ name: "Lyon", x: 58, y: 55 },
|
|
{ name: "Marseille", x: 58, y: 72 },
|
|
],
|
|
},
|
|
{
|
|
name: "India",
|
|
hint: "Large peninsula in South Asia",
|
|
cities: [
|
|
{ name: "New Delhi", x: 46, y: 28 },
|
|
{ name: "Mumbai", x: 32, y: 55 },
|
|
{ name: "Chennai", x: 52, y: 72 },
|
|
],
|
|
},
|
|
{
|
|
name: "Canada",
|
|
hint: "Second largest country in the world",
|
|
cities: [
|
|
{ name: "Ottawa", x: 62, y: 52 },
|
|
{ name: "Vancouver", x: 22, y: 55 },
|
|
{ name: "Toronto", x: 60, y: 58 },
|
|
],
|
|
},
|
|
{
|
|
name: "Germany",
|
|
hint: "Central European country",
|
|
cities: [
|
|
{ name: "Berlin", x: 58, y: 28 },
|
|
{ name: "Munich", x: 48, y: 68 },
|
|
{ name: "Hamburg", x: 42, y: 18 },
|
|
],
|
|
},
|
|
];
|
|
|
|
/** @type {Country[]} */
|
|
let _data = [];
|
|
|
|
/**
|
|
* Load country data into memory. Safe to call multiple times.
|
|
* Returns a Promise for future compatibility with a real API fetch.
|
|
* @returns {Promise<Country[]>}
|
|
*/
|
|
function loadCountries() {
|
|
if (!_data.length) _data = COUNTRIES_DATA;
|
|
return Promise.resolve(_data);
|
|
}
|
|
|
|
/**
|
|
* Return a random subset of countries.
|
|
* @param {number} count
|
|
* @returns {Country[]}
|
|
*/
|
|
function getRandomCountries(count = 3) {
|
|
return [..._data].sort(() => Math.random() - 0.5).slice(0, count);
|
|
}
|
|
|
|
/**
|
|
* Get city list for a specific country by name.
|
|
* @param {string} countryName
|
|
* @returns {City[]}
|
|
*/
|
|
function getCities(countryName) {
|
|
const country = _data.find((c) => c.name === countryName);
|
|
return country ? country.cities : [];
|
|
}
|
|
|
|
return { loadCountries, getRandomCountries, getCities };
|
|
})();
|