```dataviewjs const CACHE_KEY = "divisas-cache"; async function getRates() { let cache = null; try { cache = JSON.parse(localStorage.getItem(CACHE_KEY)); } catch (e) {} if (cache && Date.now() - cache.t < 6 * 3600 * 1000) return cache; try { const url = "https://open.er-api.com/v6/latest/USD"; let json; try { const { requestUrl } = require("obsidian"); json = (await requestUrl(url)).json; } catch (e) { json = await (await fetch(url)).json(); } if (json.result !== "success") throw new Error("Respuesta inválida"); const data = { t: Date.now(), rates: json.rates, updated: json.time_last_update_utc }; localStorage.setItem(CACHE_KEY, JSON.stringify(data)); return data; } catch (e) { if (cache) return cache; // sin conexión: usa la última caché throw e; } } const { rates, updated } = await getRates(); const codes = Object.keys(rates).sort(); const nombres = new Intl.DisplayNames(["es"], { type: "currency" }); const label = c => { try { return `${c} – ${nombres.of(c)}`; } catch { return c; } }; const root = dv.container.createEl("div"); root.style.cssText = "display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:8px"; const monto = root.createEl("input", { type: "number", value: "100" }); monto.style.width = "110px"; const de = root.createEl("select"); root.createEl("span", { text: "→" }); const a = root.createEl("select"); for (const c of codes) { de.createEl("option", { text: label(c), value: c }); a.createEl("option", { text: label(c), value: c }); } de.value = "DZD"; a.value = "CRC"; const out = dv.container.createEl("p"); out.style.cssText = "font-size:1.3em;font-weight:bold;margin:4px 0"; const info = dv.container.createEl("small"); info.style.opacity = "0.6"; function calcular() { const x = parseFloat(monto.value) || 0; const r = x / rates[de.value] * rates[a.value]; const fmt = (n, c) => { try { return new Intl.NumberFormat("es", { style: "currency", currency: c }).format(n); } catch { return `${n.toFixed(2)} ${c}`; } }; out.setText(`${fmt(x, de.value)} = ${fmt(r, a.value)}`); info.setText(`1 ${de.value} = ${(rates[a.value] / rates[de.value]).toFixed(4)} ${a.value} · Actualizado: ${updated ?? "caché"}`); } [monto, de, a].forEach(el => el.addEventListener("input", calcular)); calcular(); ``` # Dinar argelino (DZA) >[!grid] ![[Pasted image 20240426154633.png]]![[Pasted image 20240426154643.png]] >[!grid] ![[Pasted image 20240426154712.png]]![[Pasted image 20240426154722.png]] >[!grid] ![[Pasted image 20240426154610.png]]