{
  "formato": "talaya.complemento/1",
  "id": "dev.pages.talaya.terremotos",
  "nombre": "Terremotos cerca",
  "version": "1.0.0",
  "autor": {
    "nombre": "Talaya",
    "web": "https://heytalaya.com"
  },
  "descripcion": "Los últimos terremotos alrededor de donde estás: magnitud, zona, a qué distancia y hace cuánto. Y su mapa en el reloj.",
  "icono": "waveform.path.ecg",
  "cobertura": null,
  "permisos": {
    "red": [
      "www.seismicportal.eu"
    ],
    "ubicacion": true,
    "memoria": false,
    "pantalla": true
  },
  "habilidades": [
    {
      "nombre": "terremotos_cerca",
      "descripcion": "Los terremotos de los últimos días cerca del usuario, con datos del Centro Sismológico Euromediterráneo (EMSC): cuántos, el último y el mayor, con magnitud, zona, distancia y hace cuánto. Los pinta en el mapa del reloj. Para «¿ha habido algún terremoto?», «¿qué ha sido ese temblor?», «¿tiembla mucho por aquí?», «any earthquakes nearby?».",
      "parametros": {
        "radio_km": {
          "tipo": "entero",
          "descripcion": "Radio de búsqueda en kilómetros. Si no lo dice, vacío (300 km)",
          "obligatorio": false
        },
        "dias": {
          "tipo": "entero",
          "descripcion": "Cuántos días hacia atrás, hasta 30. Si no lo dice, vacío (7 días)",
          "obligatorio": false
        },
        "magnitud_minima": {
          "tipo": "decimal",
          "descripcion": "Magnitud mínima. Si no lo dice, vacío (2)",
          "obligatorio": false
        }
      },
      "lenta": true,
      "guion": "// Terremotos cerca. Datos del EMSC (www.seismicportal.eu), sin clave.\n// Una sola petición: el servicio ya filtra por distancia, fecha y magnitud.\nasync function run(args, api) {\n  const en = String(api.idioma || \"\").toLowerCase().indexOf(\"en\") === 0;\n  const yo = api.posicion();\n  if (typeof yo.lat !== \"number\") {\n    return en\n      ? \"I don't know where you are right now, so I can't look for earthquakes nearby.\"\n      : \"No sé dónde estás ahora mismo: sin ubicación no puedo mirar los terremotos cercanos.\";\n  }\n\n  const radioKm = Number(args.radio_km) > 0 ? Number(args.radio_km) : 300;\n  const dias = Number(args.dias) > 0 ? Math.min(Number(args.dias), 30) : 7;\n  const minima = Number(args.magnitud_minima) > 0 ? Number(args.magnitud_minima) : 2;\n  const desde = new Date(Date.now() - dias * 86400000).toISOString().slice(0, 19);\n  const grados = Math.min(20, Math.max(0.5, radioKm / 111.2)).toFixed(2);\n\n  const url = \"https://www.seismicportal.eu/fdsnws/event/1/query?format=json&orderby=time&limit=50\"\n    + \"&lat=\" + yo.lat.toFixed(3) + \"&lon=\" + yo.lon.toFixed(3)\n    + \"&maxradius=\" + grados + \"&minmag=\" + minima + \"&start=\" + desde;\n\n  const nada = en\n    ? \"No earthquakes of magnitude \" + minima + \" or more within \" + radioKm + \" km in the last \" + dias + \" days.\"\n    : \"No ha habido terremotos de magnitud \" + minima + \" o más a menos de \" + radioKm + \" km en los últimos \" + dias + \" días.\";\n\n  const r = await api.http.get(url, { plazo: 15 });\n  // El servicio contesta 204, sin cuerpo, cuando no hay nada.\n  if (r.codigo === 204 || !r.cuerpo) return nada;\n  if (r.codigo !== 200) throw new Error(\"el EMSC ha contestado con el error \" + r.codigo);\n\n  const lista = (JSON.parse(r.cuerpo).features || []).map(function (f) {\n    const p = f.properties;\n    const metros = api.distancia(p.lat, p.lon);\n    return {\n      mag: Number(p.mag),\n      zona: String(p.flynn_region || \"\").toLowerCase(),\n      lat: p.lat,\n      lon: p.lon,\n      cuando: Date.parse(p.time),\n      km: metros >= 0 ? Math.round(metros / 1000) : null\n    };\n  });\n  if (!lista.length) return nada;\n\n  function hace(ms) {\n    const min = Math.max(1, Math.round((Date.now() - ms) / 60000));\n    if (min < 60) return en ? min + \" minutes ago\" : \"hace \" + min + \" minutos\";\n    const h = Math.round(min / 60);\n    if (h < 48) return en ? h + \" hours ago\" : \"hace \" + h + \" horas\";\n    const d = Math.round(h / 24);\n    return en ? d + \" days ago\" : \"hace \" + d + \" días\";\n  }\n  function uno(t) {\n    const lejos = t.km === null ? \"\" : (en ? \", \" + t.km + \" km away\" : \", a \" + t.km + \" km\");\n    return (en ? \"magnitude \" : \"magnitud \") + t.mag.toFixed(1) + (en ? \" in \" : \" en \") + t.zona + lejos + \", \" + hace(t.cuando);\n  }\n\n  await api.reloj.marcas(en ? \"Earthquakes\" : \"Terremotos\", lista.slice(0, 20).map(function (t) {\n    return { etiqueta: \"M\" + t.mag.toFixed(1), lat: t.lat, lon: t.lon };\n  }));\n\n  const ultimo = lista[0];\n  const mayor = lista.reduce(function (a, b) { return b.mag > a.mag ? b : a; });\n  const cuantos = lista.length === 1\n    ? (en ? \"One earthquake\" : \"Un terremoto\")\n    : lista.length + (en ? \" earthquakes\" : \" terremotos\");\n  let texto = en\n    ? cuantos + \" of magnitude \" + minima + \" or more within \" + radioKm + \" km in the last \" + dias + \" days (EMSC data). The latest: \" + uno(ultimo) + \".\"\n    : cuantos + \" de magnitud \" + minima + \" o más a menos de \" + radioKm + \" km en los últimos \" + dias + \" días (datos del EMSC). El último: \" + uno(ultimo) + \".\";\n  if (mayor !== ultimo) texto += en ? \" The strongest: \" + uno(mayor) + \".\" : \" El mayor: \" + uno(mayor) + \".\";\n  if (lista.length === 50) texto += en ? \" There may be more.\" : \" Puede haber más.\";\n  return texto;\n}\n"
    }
  ]
}
