# Prompt 2: Modelo de datos y persistencia para el mapa de viajes

Eres un programador JavaScript senior. Necesito un módulo `data.js` que gestione el modelo de datos del mapa de viajes. Requisitos:

1. **Estructura del modelo:**
   ```js
   {
     "MX": {
       "status": "visited",          // "visited" | "bucketlist" | "none"
       "cities": [
         {"name": "Ciudad de México", "times": 3, "last": "2024-11"},
         {"name": "Oaxaca", "times": 1, "last": "2023-02"}
       ]
     },
     "JP": {
       "status": "bucketlist",
       "cities": [
         {"name": "Tokio", "horizon": "mediano"}  // "corto" | "mediano" | "largo"
       ]
     }
   }
   ```

2. **Tabla de países:** incluye una tabla `COUNTRIES` con al menos 200 entradas. Cada entrada debe tener `{name, iso2, region, flag}`. La bandera se deriva de `iso2` convirtiendo cada letra a su símbolo indicador regional (por ejemplo, `"MX"` → `"🇲🇽"`). Usa esta tabla para:
   - Llenar el selector de país sin pedir emojis a mano.
   - Calcular estadísticas por región sin caer en un default sesgado como `'eu'`.

3. **API mínima:**
   - `loadData()`: lee de `localStorage` bajo la clave `travelmap_data_v1`. Si no existe, devuelve objeto vacío. Si el JSON está corrupto, devuelve objeto vacío y avisa por consola.
   - `saveData(data)`: guarda en `localStorage`.
   - `toggleCountry(data, iso)`: alterna el status del país entre `none → visited → bucketlist → none`. Si no existe, lo crea con `cities: []`.
   - `addCity(data, iso, cityName, options)`: añade una ciudad al país, o incrementa `times` si ya existe. `options` puede incluir `last` y `horizon`.
   - `editCity(data, iso, oldName, newName, options)`: renombra una ciudad y actualiza sus campos opcionales.
   - `removeCity(data, iso, cityName)`: elimina la ciudad.
   - `getStats(data)`: devuelve `{visited: N, bucketlist: N, totalCities: N, byRegion: {...}}`.

4. **IDs seguros:** si generas IDs para ciudades, nunca uses `Math.max(...arr.map(d => d.id)) + 1` sobre un arreglo vacío (devuelve `-Infinity`). Usa `crypto.randomUUID()` o un contador inicializado en 1.

5. **Sanitización:** cualquier texto introducido por el usuario (nombre de ciudad, notas) debe escaparse antes de insertarse en el DOM. No uses `innerHTML` con texto de usuario.

6. **Defensivo:**
   - Si `iso` no es un string de dos letras, recházalo.
   - Si `cityName` está vacío, recházalo.
   - En `getStats`, evita divisiones entre cero; si no hay países visitados, devuelve 0, no `NaN`.

7. **Exportar/importar:** añade `exportToJSON(data)` y `importFromJSON(jsonString)` para que el usuario pueda hacer backup manual.
   - `exportToJSON(data)` debe devolver un blob o string listo para descargar.
   - `importFromJSON(jsonString)` debe validar que el JSON tenga la estructura esperada antes de reemplazar los datos.

No uses frameworks. Entrégame `data.js` con comentarios y una pequeña prueba en consola al final.

Pregúntame: ¿quieres que las ciudades tengan fechas exactas o solo meses/años?
