deepseek-v4-flash-0731 @ high · dsh
dshhigh
- config
- deepseek-v4-flash-0731-eff-high--cli--dsh--dev
- batch
- 2026-07-19--unified
- transport
- dsh-0.1.0-rc.8-headless-isolated-home
- protocol
- cli · api
- served model
- deepseek-v4-flash
- captured
- Jul 18, 2026, 11:54 AM · N=2
variant
live
slot 0 · P-q · sandboxed iframe

delivered in a markdown fence — the model wrapped its HTML in a code fence; extraction stripped it. Recorded here for traceability.
The screenshot is the exact frozen pixels the similarity channels measured. Run live re-executes the raw output in a sandboxed iframe; its rendering depends on your browser and fonts and is not guaranteed to match the measured pixels.
similarity neighbors
nearest
claude-opus-5 @xhigh · CC0.73claude-opus-5-thinking @medium · cursor-xl0.71deepseek-v4.1-flash @max · api0.71claude-fable-5 @xhigh · CC0.71gpt-5.6-sol @high · cursor0.70farthest
north-mini-code-free · api0.48claude-sonnet-4 · cursor0.50qwen3.5-plus · go0.51claude-sonnet-4 · kiro0.51claude-haiku-4-5 @max · CC0.52within session 2026-07-19--unified
similarity measures convergence within this session — not quality.
Fidelity — does the card show the right data?
- namematch
- conditionmatch
- datematch
- max tempambiguousinsufficient-distinct-temperature-nodes
- min tempambiguousinsufficient-distinct-temperature-nodes
- hourlyambiguouscoverage · 0 match · 0 mismatch · 24 not shown
- request sidematch0 violation(s)
extractor fidelity-extractor-v1+Berlin-2026-07-15
Source — raw model output, one byte unchanged
download card.html<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=1280">
<meta name="color-scheme" content="dark">
<title>Weather</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>⛅</text></svg>">
<style>
:root{
--ink:#eef2ff;
--muted:#8ea0b8;
--accent:#7dd3fc;
--card-bg:rgba(13,18,34,.62);
}
*{box-sizing:border-box;margin:0;padding:0}
[hidden]{display:none!important}
html,body{height:100%}
body{
font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
color:var(--ink);
background:
radial-gradient(1000px 640px at 88% -12%, rgba(99,102,241,.30), transparent 62%),
radial-gradient(860px 600px at -12% 112%, rgba(14,165,233,.22), transparent 60%),
radial-gradient(720px 520px at 52% 125%, rgba(168,85,247,.18), transparent 62%),
linear-gradient(180deg,#0b1022,#070b16);
min-height:100vh;
display:grid;
place-items:center;
overflow:hidden;
-webkit-font-smoothing:antialiased;
text-rendering:optimizeLegibility;
}
.scene{position:relative;z-index:2;display:flex;flex-direction:column;align-items:center;gap:22px}
.stars{
position:fixed;inset:0;z-index:0;pointer-events:none;
width:2px;height:2px;border-radius:50%;
background:rgba(255,255,255,.55);
animation:twinkle 5s ease-in-out infinite alternate;
}
@keyframes twinkle{from{opacity:.25}to{opacity:.9}}
.card{
position:relative;z-index:1;
width:min(1180px,calc(100vw - 96px));
height:640px;
display:flex;
border-radius:36px;
overflow:hidden;
background:var(--card-bg);
border:1px solid rgba(255,255,255,.10);
box-shadow:0 60px 120px -45px rgba(0,0,0,.85), 0 2px 0 rgba(255,255,255,.06) inset;
backdrop-filter:blur(28px) saturate(1.25);
-webkit-backdrop-filter:blur(28px) saturate(1.25);
animation:rise .9s cubic-bezier(.16,1,.3,1) both;
}
@keyframes rise{from{opacity:0;transform:translateY(26px) scale(.985)}to{opacity:1;transform:none}}
/* ---------- hero (left panel) ---------- */
.hero{
flex:0 0 388px;
padding:46px 42px 42px;
display:flex;flex-direction:column;justify-content:space-between;
position:relative;overflow:hidden;
background-image:linear-gradient(163deg,#334155 0%,#1e293b 55%,#0f172a 100%);
transition:background 1.2s ease;
}
.hero::before{
content:"";position:absolute;inset:0;pointer-events:none;
background:
radial-gradient(520px 300px at 18% -8%, rgba(255,255,255,.16), transparent 60%),
radial-gradient(420px 300px at 110% 120%, rgba(255,255,255,.10), transparent 60%);
}
.hero>*{position:relative}
.loc-row{display:flex;align-items:center;gap:10px;min-width:0}
.loc-row svg{opacity:.92;flex:0 0 auto;filter:drop-shadow(0 2px 6px rgba(0,0,0,.35))}
.loc{font-size:27px;font-weight:650;letter-spacing:-.01em;line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.date{margin-top:8px;font-size:13.5px;letter-spacing:.06em;color:rgba(255,255,255,.78)}
.hero-mid{display:flex;flex-direction:column;align-items:center;text-align:center;margin:14px 0 10px}
.icon{width:108px;height:108px;filter:drop-shadow(0 14px 26px rgba(0,0,0,.35))}
.icon svg{width:100%;height:100%;display:block}
.temp{
font-size:118px;font-weight:200;letter-spacing:-.02em;line-height:1;
font-variant-numeric:tabular-nums;margin-top:8px;
text-shadow:0 18px 40px rgba(0,0,0,.28);
}
.cond{font-size:20px;font-weight:560;margin-top:14px;letter-spacing:.01em;opacity:.95}
.chips{display:flex;gap:12px}
.chip{
display:flex;align-items:center;gap:11px;padding:10px 18px;border-radius:999px;
background:rgba(255,255,255,.13);border:1px solid rgba(255,255,255,.17);
backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
box-shadow:0 10px 24px -12px rgba(0,0,0,.5);
}
.chip-k{font-size:10.5px;font-weight:650;letter-spacing:.14em;text-transform:uppercase;opacity:.7}
.chip-v{font-size:21px;font-weight:620;font-variant-numeric:tabular-nums;line-height:1}
.unit{font-size:11.5px;color:rgba(255,255,255,.62);letter-spacing:.05em;margin-top:16px;font-variant-numeric:tabular-nums}
.hero-top{animation:fadeUp .7s .05s ease both}
.hero-mid{animation:fadeUp .8s .15s ease both}
.hero-bottom{animation:fadeUp .7s .28s ease both}
@keyframes fadeUp{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
.card.is-error .hero{filter:saturate(.55) brightness(.72)}
/* ---------- detail (right panel) ---------- */
.detail{flex:1;min-width:0;padding:44px 46px 40px;display:flex;flex-direction:column}
.detail-head{display:flex;align-items:baseline;justify-content:space-between;gap:16px}
.title{font-size:12.5px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}
.range{display:flex;align-items:center;gap:9px;font-size:13.5px;color:rgba(238,242,255,.78);font-variant-numeric:tabular-nums}
.range .dot{width:7px;height:7px;border-radius:50%;background:var(--accent);box-shadow:0 0 12px var(--accent)}
.chart{flex:1;min-height:0;margin-top:16px;position:relative;display:flex;flex-direction:column;justify-content:center;gap:16px}
.chart-body{position:relative;width:100%;max-width:724px;margin:0 auto;aspect-ratio:660/360}
.svgwrap{position:absolute;inset:0}
.svgwrap svg{width:100%;height:100%;display:block}
.chart-meta{display:flex;justify-content:center;gap:28px;font-size:12.5px;color:rgba(226,232,240,.72);font-variant-numeric:tabular-nums}
.chart-meta b{font-weight:700}
.chart-meta .hi{color:#fcd34d}
.chart-meta .lo{color:#67e8f9}
/* chart svg elements */
.gridline{stroke:rgba(255,255,255,.08);stroke-dasharray:2 6}
.glabel{fill:rgba(148,163,184,.5);font-size:10.5px;font-variant-numeric:tabular-nums}
.tlabel{fill:rgba(148,163,184,.82);font-size:10.5px;letter-spacing:.05em;font-variant-numeric:tabular-nums}
.vlabel{fill:rgba(226,232,240,.88);font-size:10.5px;font-weight:600;font-variant-numeric:tabular-nums}
.pt{fill:#0a0f1e;stroke:rgba(226,232,240,.92);stroke-width:1.6;opacity:0;animation:pop .45s ease forwards}
@keyframes pop{from{opacity:0}to{opacity:1}}
.draw{stroke-dasharray:2400;stroke-dashoffset:2400;animation:draw 1.6s .2s cubic-bezier(.4,0,.2,1) forwards}
@keyframes draw{to{stroke-dashoffset:0}}
.hl{opacity:0;animation:pop .5s .95s ease forwards}
.badge-text{font-size:11px;font-weight:700;stroke:rgba(9,13,26,.95);stroke-width:4px;paint-order:stroke}
/* tooltip */
.tip{position:absolute;inset:0;pointer-events:none;z-index:3;opacity:0;transition:opacity .18s}
.tip.on{opacity:1}
.tip .guide{
position:absolute;top:6px;bottom:70px;width:1.5px;
background:linear-gradient(180deg,rgba(255,255,255,.5),rgba(255,255,255,.12));
border-radius:2px;transform:translateX(-50%);
}
.tip .bubble{
position:absolute;padding:7px 12px;border-radius:11px;
background:rgba(9,13,26,.94);border:1px solid rgba(255,255,255,.16);
font-size:12.5px;font-weight:600;font-variant-numeric:tabular-nums;
white-space:nowrap;transform:translate(-50%,-135%);
box-shadow:0 12px 28px -10px rgba(0,0,0,.7);letter-spacing:.02em;
}
/* states */
.spinner{
position:absolute;inset:0;z-index:2;display:flex;flex-direction:column;
align-items:center;justify-content:center;gap:18px;
color:var(--muted);font-size:13.5px;letter-spacing:.04em;
}
.spinner .ring{
width:46px;height:46px;border-radius:50%;
border:3px solid rgba(255,255,255,.12);border-top-color:var(--accent);
animation:spin 1s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}
.err{
position:absolute;inset:0;z-index:2;display:flex;flex-direction:column;
align-items:center;justify-content:center;text-align:center;
gap:10px;padding:30px;
}
.err-ico{width:54px;height:54px;margin-bottom:6px;opacity:.95}
.err h3{font-size:19px;font-weight:600;letter-spacing:.01em}
.err p{font-size:13.5px;color:var(--muted);max-width:430px;line-height:1.6}
.btn-retry{
margin-top:16px;padding:10px 22px;border-radius:999px;
border:1px solid rgba(255,255,255,.22);background:rgba(255,255,255,.08);
color:var(--ink);font-size:13px;font-weight:600;cursor:pointer;letter-spacing:.03em;
font-family:inherit;transition:background .2s, transform .15s;
}
.btn-retry:hover{background:rgba(255,255,255,.16)}
.btn-retry:active{transform:scale(.97)}
.foot{font-size:11.5px;color:rgba(148,163,184,.65);letter-spacing:.06em;text-align:center}
@media (prefers-reduced-motion:reduce){
.card,.stars,.hero-top,.hero-mid,.hero-bottom{animation:none}
.pt,.hl,.draw{animation:none!important;opacity:1!important;stroke-dashoffset:0!important}
.tip{transition:none}
}
</style>
</head>
<body>
<main class="scene">
<div class="stars" aria-hidden="true"></div>
<div class="card" id="card">
<!-- left: hero -->
<section class="hero" id="hero" aria-label="Current conditions">
<div class="hero-top">
<div class="loc-row">
<svg width="19" height="19" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z"/>
<circle cx="12" cy="10" r="3"/>
</svg>
<h1 class="loc" id="loc">…</h1>
</div>
<p class="date" id="date"></p>
</div>
<div class="hero-mid">
<div class="icon" id="icon" aria-hidden="true"></div>
<div class="temp" id="temp">–°</div>
<div class="cond" id="cond"></div>
</div>
<div class="hero-bottom">
<div class="chips">
<span class="chip"><span class="chip-k">Max</span><span class="chip-v" id="maxV">–°</span></span>
<span class="chip"><span class="chip-k">Min</span><span class="chip-v" id="minV">–°</span></span>
</div>
<p class="unit" id="coords"></p>
</div>
</section>
<!-- right: hourly chart -->
<section class="detail" aria-label="Hourly temperatures">
<div class="detail-head">
<h2 class="title">Hourly temperatures</h2>
<span class="range" id="range"><span class="dot"></span>–</span>
</div>
<div class="chart" id="chart">
<div class="spinner" id="spinner" hidden>
<div class="ring"></div>
<span>Loading weather…</span>
</div>
<div class="err" id="errBox" hidden role="alert" aria-live="polite">
<svg class="err-ico" viewBox="0 0 96 96" fill="none" aria-hidden="true">
<path d="M48 12 86 78 H10 Z" fill="#fbbf24" opacity=".9"/>
<path d="M48 36 v18" stroke="#0f172a" stroke-width="6" stroke-linecap="round"/>
<circle cx="48" cy="68" r="4" fill="#0f172a"/>
</svg>
<h3 id="errTitle">…</h3>
<p id="errSub">…</p>
<button class="btn-retry" id="retryBtn" type="button">Try again</button>
</div>
<div class="chart-body" id="chartBody" hidden>
<div class="svgwrap" id="svgwrap"></div>
<div class="tip" id="tip" hidden>
<div class="guide"></div>
<div class="bubble" id="bubble"></div>
</div>
</div>
<p class="chart-meta" id="chartMeta" hidden></p>
</div>
</section>
</div>
<p class="foot">Open-Meteo API · same-origin · no key · timezone UTC · temperatures in °C</p>
</main>
<noscript><p style="color:#e2e8f0;padding:24px;text-align:center">This page needs JavaScript to load the weather data.</p></noscript>
<script>
(() => {
'use strict';
/* ================= helpers ================= */
const $ = (s, r = document) => r.querySelector(s);
const todayUTC = () => new Date().toISOString().slice(0, 10);
const q = new URLSearchParams(location.search);
const numParam = (key, def, lo, hi) => {
const n = Number(q.get(key));
return Number.isFinite(n) && n >= lo && n <= hi ? n : def;
};
let dateParam = q.get('date') || '';
if (!/^\d{4}-\d{2}-\d{2}$/.test(dateParam)) dateParam = todayUTC();
const CFG = {
lat: numParam('lat', 52.52, -90, 90),
lon: numParam('lon', 13.405, -180, 180),
name: String(q.get('name') || 'Berlin').trim().slice(0, 80) || 'Berlin',
date: dateParam
};
document.title = CFG.name + ' · Weather';
const fmtCoord = (v, pos, neg) => Math.abs(v).toFixed(2) + '°' + (v >= 0 ? pos : neg);
const HOUR_NOW = new Date().getUTCHours();
const isNight = CFG.date === todayUTC() && (HOUR_NOW < 6 || HOUR_NOW >= 18);
/* ================= weather codes (WMO) ================= */
function describe(code) {
if (code === 0) return { label: 'Clear sky', group: 'clear' };
if (code === 1) return { label: 'Mainly clear', group: 'partly' };
if (code === 2) return { label: 'Partly cloudy', group: 'partly' };
if (code === 3) return { label: 'Overcast', group: 'cloudy' };
if (code === 45 || code === 48) return { label: 'Fog', group: 'fog' };
if (code >= 51 && code <= 57) return { label: 'Drizzle', group: 'rain' };
if (code >= 61 && code <= 67) return { label: 'Rain', group: 'rain' };
if (code >= 71 && code <= 77) return { label: 'Snow', group: 'snow' };
if (code >= 80 && code <= 82) return { label: 'Rain showers', group: 'rain' };
if (code >= 85 && code <= 86) return { label: 'Snow showers', group: 'snow' };
if (code >= 95) return { label: 'Thunderstorm', group: 'thunder' };
return { label: 'Cloudy', group: 'cloudy' };
}
/* ================= themes ================= */
const THEMES = {
clear: { g: ['#0ea5e9', '#3b82f6', '#4f46e5'], accent: '#7dd3fc', soft: 'rgba(125,211,252,.20)' },
clearN: { g: ['#1e1b4b', '#312e81', '#4c1d95'], accent: '#a5b4fc', soft: 'rgba(165,180,252,.20)' },
partly: { g: ['#38bdf8', '#6366f1', '#4338ca'], accent: '#fcd34d', soft: 'rgba(252,211,77,.16)' },
partlyN: { g: ['#0f172a', '#3730a3', '#4c1d95'], accent: '#c4b5fd', soft: 'rgba(196,181,253,.16)' },
cloudy: { g: ['#475569', '#334155', '#1e293b'], accent: '#cbd5e1', soft: 'rgba(203,213,225,.14)' },
fog: { g: ['#64748b', '#475569', '#334155'], accent: '#e2e8f0', soft: 'rgba(226,232,240,.14)' },
rain: { g: ['#3b82f6', '#1d4ed8', '#172554'], accent: '#93c5fd', soft: 'rgba(147,197,253,.18)' },
snow: { g: ['#7dd3fc', '#60a5fa', '#3b82f6'], accent: '#f0f9ff', soft: 'rgba(240,249,255,.22)' },
thunder: { g: ['#4c1d95', '#312e81', '#0f172a'], accent: '#fde047', soft: 'rgba(253,224,71,.18)' }
};
/* ================= SVG icons ================= */
const SUN_GRAD = '<linearGradient id="sunG" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#fde68a"/><stop offset="1" stop-color="#f59e0b"/></linearGradient>';
const MOON_GRAD = '<linearGradient id="moonG" x1="0" y1="0" x2="1" y2="1"><stop offset="0" stop-color="#eef2ff"/><stop offset="1" stop-color="#a5b4fc"/></linearGradient>';
const CLOUD_GRAD = '<linearGradient id="clG" x1="0" y1="0" x2="0" y2="1"><stop offset="0" stop-color="#e2e8f0"/><stop offset="1" stop-color="#94a3b8"/></linearGradient>';
const cloudShape = (fill) =>
'<g fill="' + fill + '">' +
'<circle cx="33" cy="57" r="14"/>' +
'<circle cx="49" cy="49" r="17"/>' +
'<circle cx="65" cy="57" r="13"/>' +
'<rect x="24" y="53" width="50" height="16" rx="8"/>' +
'</g>';
const ICONS = {
sun: '<svg viewBox="0 0 96 96" fill="none"><defs>' + SUN_GRAD + '</defs>' +
'<g stroke="url(#sunG)" stroke-width="5" stroke-linecap="round">' +
'<line x1="48" y1="6" x2="48" y2="17"/><line x1="48" y1="79" x2="48" y2="90"/>' +
'<line x1="6" y1="48" x2="17" y2="48"/><line x1="79" y1="48" x2="90" y2="48"/>' +
'<line x1="18.3" y1="18.3" x2="26" y2="26"/><line x1="70" y1="70" x2="77.7" y2="77.7"/>' +
'<line x1="18.3" y1="77.7" x2="26" y2="70"/><line x1="70" y1="26" x2="77.7" y2="18.3"/>' +
'</g><circle cx="48" cy="48" r="21" fill="url(#sunG)"/></svg>',
moon: '<svg viewBox="0 0 96 96" fill="none"><defs>' + MOON_GRAD + '</defs>' +
'<path d="M58 14 A34 34 0 1 0 82 50 A26 26 0 0 1 58 14 Z" fill="url(#moonG)"/>' +
'<g fill="#c7d2fe"><circle cx="22" cy="22" r="1.8"/><circle cx="31" cy="14" r="1.2"/><circle cx="12" cy="32" r="1.2"/></g></svg>',
partlyDay: '<svg viewBox="0 0 96 96" fill="none"><defs>' + SUN_GRAD + CLOUD_GRAD + '</defs>' +
'<g stroke="url(#sunG)" stroke-width="4.5" stroke-linecap="round">' +
'<line x1="63" y1="11" x2="63" y2="17"/><line x1="63" y1="41" x2="63" y2="47"/>' +
'<line x1="73" y1="21" x2="76.5" y2="24.5"/><line x1="73" y1="37" x2="76.5" y2="33.5"/>' +
'<line x1="49.5" y1="21" x2="46" y2="24.5"/><line x1="49.5" y1="37" x2="46" y2="33.5"/>' +
'</g>' +
'<circle cx="63" cy="29" r="10" fill="url(#sunG)"/>' +
'<g fill="url(#clG)"><circle cx="34" cy="58" r="13"/><circle cx="49" cy="51" r="16"/><circle cx="63" cy="58" r="12"/><rect x="26" y="54" width="46" height="15" rx="7.5"/></g></svg>',
partlyNight: '<svg viewBox="0 0 96 96" fill="none"><defs>' + MOON_GRAD + CLOUD_GRAD + '</defs>' +
'<path d="M64 20 A16 16 0 1 0 76 34 A12 12 0 0 1 64 20 Z" fill="url(#moonG)"/>' +
'<g fill="#c7d2fe"><circle cx="40" cy="18" r="1.4"/><circle cx="34" cy="30" r="1.1"/></g>' +
'<g fill="url(#clG)"><circle cx="34" cy="58" r="13"/><circle cx="49" cy="51" r="16"/><circle cx="63" cy="58" r="12"/><rect x="26" y="54" width="46" height="15" rx="7.5"/></g></svg>',
cloudy: '<svg viewBox="0 0 96 96" fill="none"><defs>' + CLOUD_GRAD + '</defs>' + cloudShape('url(#clG)') + '</svg>',
fog: '<svg viewBox="0 0 96 96" fill="none"><defs>' + CLOUD_GRAD + '</defs>' + cloudShape('url(#clG)') +
'<g stroke="#e2e8f0" stroke-width="4" stroke-linecap="round">' +
'<line x1="26" y1="77" x2="70" y2="77"/><line x1="32" y1="85" x2="63" y2="85"/>' +
'</g></svg>',
rain: '<svg viewBox="0 0 96 96" fill="none"><defs>' + CLOUD_GRAD + '</defs>' + cloudShape('url(#clG)') +
'<g stroke="#7dd3fc" stroke-width="4" stroke-linecap="round">' +
'<line x1="31" y1="72" x2="25" y2="84"/><line x1="46" y1="72" x2="40" y2="84"/><line x1="61" y1="72" x2="55" y2="84"/>' +
'</g></svg>',
snow: '<svg viewBox="0 0 96 96" fill="none"><defs>' + CLOUD_GRAD + '</defs>' + cloudShape('url(#clG)') +
'<g stroke="#e0f2fe" stroke-width="2.6" stroke-linecap="round">' +
'<line x1="31" y1="72" x2="31" y2="84"/><line x1="25" y1="78" x2="37" y2="78"/>' +
'<line x1="46" y1="72" x2="46" y2="84"/><line x1="40" y1="78" x2="52" y2="78"/>' +
'<line x1="61" y1="72" x2="61" y2="84"/><line x1="55" y1="78" x2="67" y2="78"/>' +
'</g></svg>',
thunder: '<svg viewBox="0 0 96 96" fill="none"><defs>' + CLOUD_GRAD + '</defs>' + cloudShape('url(#clG)') +
'<polygon points="50,56 36,72 45,72 38,90 62,68 52,68 58,56" fill="#fde047"/>' +
'</svg>'
};
/* ================= smooth line ================= */
function smoothPath(pts) {
if (pts.length < 2) return '';
let d = 'M ' + pts[0][0].toFixed(1) + ',' + pts[0][1].toFixed(1);
for (let i = 0; i < pts.length - 1; i++) {
const p0 = pts[Math.max(0, i - 1)], p1 = pts[i], p2 = pts[i + 1], p3 = pts[Math.min(pts.length - 1, i + 2)];
const c1x = p1[0] + (p2[0] - p0[0]) / 6, c1y = p1[1] + (p2[1] - p0[1]) / 6;
const c2x = p2[0] - (p3[0] - p1[0]) / 6, c2y = p2[1] - (p3[1] - p1[1]) / 6;
d += ' C ' + c1x.toFixed(1) + ',' + c1y.toFixed(1) + ' ' + c2x.toFixed(1) + ',' + c2y.toFixed(1) + ' ' + p2[0].toFixed(1) + ',' + p2[1].toFixed(1);
}
return d;
}
/* ================= chart renderer ================= */
function renderChart(wrap, times, temps, theme, extremes) {
const n = times.length;
const W = 660, H = 360, L = 48, R = 652, T = 34, B = 236;
const minT = Math.min.apply(null, temps), maxT = Math.max.apply(null, temps);
const span = (maxT - minT) || 1;
const pad = span * 0.16;
const lo = minT - pad, hi = maxT + pad;
const X = i => L + (R - L) * (n === 1 ? 0.5 : i / (n - 1));
const Y = v => T + (B - T) * (1 - (v - lo) / (hi - lo));
const pts = times.map((t, i) => ({ x: X(i), y: Y(temps[i]), t: temps[i], hour: parseInt(t.slice(11, 13), 10) }));
const linePath = smoothPath(pts.map(p => [p.x, p.y]));
const areaPath = linePath + ' L' + pts[n - 1].x.toFixed(1) + ',' + B + ' L' + pts[0].x.toFixed(1) + ',' + B + ' Z';
/* gridlines */
let grid = '';
[0.25, 0.5, 0.75].forEach(f => {
const v = lo + (hi - lo) * f;
const y = Y(v);
grid += '<line class="gridline" x1="' + L + '" y1="' + y.toFixed(1) + '" x2="' + R + '" y2="' + y.toFixed(1) + '"/>' +
'<text class="glabel" x="' + (L - 10) + '" y="' + (y + 3.5).toFixed(1) + '" text-anchor="end">' + Math.round(v) + '°</text>';
});
/* time labels every 3 h */
let tlabels = '';
for (let i = 0; i < n; i += 3) {
tlabels += '<text class="tlabel" x="' + pts[i].x.toFixed(1) + '" y="' + (B + 26) + '" text-anchor="middle">' +
String(pts[i].hour).padStart(2, '0') + ':00</text>';
}
/* value labels every 6 h */
let vlabels = '';
for (let i = 0; i < n; i += 6) {
vlabels += '<text class="vlabel" x="' + pts[i].x.toFixed(1) + '" y="' + (pts[i].y - 13).toFixed(1) + '" text-anchor="middle">' + Math.round(pts[i].t) + '°</text>';
}
/* dots */
let dots = '';
for (let i = 0; i < n; i++) {
dots += '<circle class="pt" cx="' + pts[i].x.toFixed(1) + '" cy="' + pts[i].y.toFixed(1) + '" r="3.6" style="animation-delay:' + (0.3 + i * 0.035).toFixed(2) + 's"/>';
}
/* max / min badges */
const clampX = (x, padX) => Math.min(Math.max(x, padX), W - padX);
const hiP = pts[extremes.peakIdx], loP = pts[extremes.lowIdx];
const badge = (p, color, above) =>
'<g class="hl">' +
'<circle cx="' + p.x.toFixed(1) + '" cy="' + p.y.toFixed(1) + '" r="7" fill="rgba(9,13,26,.9)" stroke="' + color + '" stroke-width="2"/>' +
'<text class="badge-text" x="' + p.x.toFixed(1) + '" y="' + (p.y + (above ? -14 : 20)).toFixed(1) + '" text-anchor="middle" fill="' + color + '">' +
Math.round(p.t) + '°' +
'</text>' +
'</g>';
const extras =
badge({ x: clampX(hiP.x, 40), y: hiP.y }, '#fcd34d', true) +
badge({ x: clampX(loP.x, 44), y: loP.y }, '#67e8f9', false);
/* "now" marker when the requested date is today */
let nowMark = '';
if (CFG.date === todayUTC()) {
const i = Math.min(Math.max(HOUR_NOW, 0), n - 1);
const nx = pts[i].x;
nowMark =
'<g>' +
'<line x1="' + nx.toFixed(1) + '" y1="' + (T - 4) + '" x2="' + nx.toFixed(1) + '" y2="' + B + '" stroke="rgba(255,255,255,.35)" stroke-dasharray="3 5"/>' +
'<rect x="' + (nx - 21).toFixed(1) + '" y="' + (T - 27) + '" width="42" height="17" rx="8.5" fill="rgba(255,255,255,.16)"/>' +
'<text x="' + nx.toFixed(1) + '" y="' + (T - 15) + '" text-anchor="middle" fill="#fff" style="font-size:10px;font-weight:700;letter-spacing:.08em">NOW</text>' +
'</g>';
}
const svg =
'<svg viewBox="0 0 ' + W + ' ' + H + '" preserveAspectRatio="xMidYMid meet" role="img" aria-label="Hourly temperatures for ' + CFG.date + '">' +
'<defs>' +
'<linearGradient id="areaG" x1="0" y1="0" x2="0" y2="1">' +
'<stop offset="0" stop-color="' + theme.soft + '"/>' +
'<stop offset="1" stop-color="rgba(0,0,0,0)"/>' +
'</linearGradient>' +
'<linearGradient id="lineG" x1="0" y1="0" x2="1" y2="0">' +
'<stop offset="0" stop-color="' + theme.accent + '"/>' +
'<stop offset="1" stop-color="#a5b4fc"/>' +
'</linearGradient>' +
'</defs>' +
grid + tlabels + vlabels +
'<path class="area" d="' + areaPath + '" fill="url(#areaG)"/>' +
'<path class="draw" d="' + linePath + '" fill="none" stroke="url(#lineG)" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>' +
dots + extras + nowMark +
'</svg>';
wrap.innerHTML = svg;
/* hover tooltip */
const tip = document.getElementById('tip');
const bubble = document.getElementById('bubble');
const guide = tip.querySelector('.guide');
wrap.addEventListener('mousemove', e => {
const rect = wrap.getBoundingClientRect();
const frac = (e.clientX - rect.left) / rect.width;
const i = Math.max(0, Math.min(n - 1, Math.round(frac * (n - 1))));
const p = pts[i];
const xpct = (p.x / W) * 100, ypct = (p.y / H) * 100;
guide.style.left = xpct + '%';
bubble.style.left = xpct + '%';
bubble.style.top = ypct + '%';
bubble.textContent = String(p.hour).padStart(2, '0') + ':00 · ' + Math.round(p.t) + '°C';
tip.classList.add('on');
});
wrap.addEventListener('mouseleave', () => tip.classList.remove('on'));
}
/* ================= DOM refs ================= */
const cardEl = document.getElementById('card');
const heroEl = document.getElementById('hero');
const heroIcon = document.getElementById('icon');
const heroTemp = document.getElementById('temp');
const heroCond = document.getElementById('cond');
const maxV = document.getElementById('maxV');
const minV = document.getElementById('minV');
const locEl = document.getElementById('loc');
const dateEl = document.getElementById('date');
const coordsEl = document.getElementById('coords');
const rangeEl = document.getElementById('range');
const metaEl = document.getElementById('chartMeta');
const spinner = document.getElementById('spinner');
const errBox = document.getElementById('errBox');
const errTitle = document.getElementById('errTitle');
const errSub = document.getElementById('errSub');
const chartBody = document.getElementById('chartBody');
const svgwrap = document.getElementById('svgwrap');
const tip = document.getElementById('tip');
/* ================= view state ================= */
const dateLine = (() => {
const d = new Date(CFG.date + 'T00:00:00Z');
const fmt = d.toLocaleDateString('en-US', { weekday: 'long', month: 'long', day: 'numeric', year: 'numeric', timeZone: 'UTC' });
const diff = Math.round((Date.parse(CFG.date + 'T00:00:00Z') - Date.parse(todayUTC() + 'T00:00:00Z')) / 864e5);
const when = diff === 0 ? 'Today' : diff === 1 ? 'Tomorrow' : diff === -1 ? 'Yesterday' : '';
return when ? when + ' · ' + fmt : fmt;
})();
const coordsLine = fmtCoord(CFG.lat, 'N', 'S') + ' · ' + fmtCoord(CFG.lon, 'E', 'W') + ' · UTC · °C';
function setLoading() {
locEl.textContent = CFG.name;
dateEl.textContent = dateLine;
coordsEl.textContent = coordsLine;
heroTemp.textContent = '–°';
heroCond.textContent = 'Loading…';
maxV.textContent = '–°';
minV.textContent = '–°';
spinner.hidden = false;
errBox.hidden = true;
chartBody.hidden = true;
metaEl.hidden = true;
tip.hidden = true;
}
function paint({ max, min, code, hours }) {
spinner.hidden = true;
const desc = describe(code);
const nightKey =
desc.group === 'clear' ? (isNight ? 'clearN' : 'clear') :
desc.group === 'partly' ? (isNight ? 'partlyN' : 'partly') : desc.group;
const theme = THEMES[nightKey];
heroEl.style.backgroundImage = 'linear-gradient(163deg, ' + theme.g[0] + ' 0%, ' + theme.g[1] + ' 55%, ' + theme.g[2] + ' 100%)';
document.documentElement.style.setProperty('--accent', theme.accent);
const iconKey = {
clear: isNight ? 'moon' : 'sun',
partly: isNight ? 'partlyNight' : 'partlyDay',
cloudy: 'cloudy', fog: 'fog', rain: 'rain', snow: 'snow', thunder: 'thunder'
}[desc.group];
heroIcon.innerHTML = ICONS[iconKey];
const hh = t => t.slice(11, 13) + ':00';
const hMax = Math.max.apply(null, hours.map(p => p.v));
const hMin = Math.min.apply(null, hours.map(p => p.v));
const peakIdx = hours.findIndex(p => p.v === hMax);
const lowIdx = hours.findIndex(p => p.v === hMin);
heroTemp.textContent = Math.round(max) + '°';
heroCond.textContent = desc.label;
maxV.textContent = Math.round(max) + '°';
minV.textContent = Math.round(min) + '°';
rangeEl.innerHTML = '<span class="dot"></span>' + Math.round(hMin) + '° – ' + Math.round(hMax) + '°';
metaEl.innerHTML =
'Peak <b class="hi">' + Math.round(hMax) + '°</b> at ' + hh(hours[peakIdx].t) +
' · Low <b class="lo">' + Math.round(hMin) + '°</b> at ' + hh(hours[lowIdx].t);
chartBody.hidden = false;
metaEl.hidden = false;
tip.hidden = false;
renderChart(svgwrap, hours.map(p => p.t), hours.map(p => p.v), theme, { peakIdx, lowIdx });
}
function fail(title, sub) {
cardEl.classList.add('is-error');
heroEl.style.backgroundImage = 'linear-gradient(163deg, #334155 0%, #1e293b 60%, #0f172a 100%)';
heroTemp.textContent = '—';
heroCond.textContent = 'Unavailable';
maxV.textContent = '–°';
minV.textContent = '–°';
rangeEl.innerHTML = '<span class="dot"></span>–';
spinner.hidden = true;
chartBody.hidden = true;
metaEl.hidden = true;
errTitle.textContent = title;
errSub.textContent = sub;
errBox.hidden = false;
}
/* ================= data ================= */
async function load() {
const kind = CFG.date < todayUTC() ? 'archive' : 'forecast';
const url = '/api/om/' + kind + '?' + new URLSearchParams({
latitude: CFG.lat,
longitude: CFG.lon,
daily: 'temperature_2m_max,temperature_2m_min,weather_code',
hourly: 'temperature_2m',
timezone: 'UTC',
temperature_unit: 'celsius',
start_date: CFG.date,
end_date: CFG.date
});
const res = await fetch(url, { headers: { Accept: 'application/json' } });
if (!res.ok) throw new Error('The weather service responded with HTTP ' + res.status + '.');
const data = await res.json();
const d = data.daily || {}, h = data.hourly || {};
const dTime = d.time || [], dMax = d.temperature_2m_max || [], dMin = d.temperature_2m_min || [], dCode = d.weather_code || [];
const hTime = h.time || [], hTemp = h.temperature_2m || [];
const idx = dTime.findIndex(t => String(t).slice(0, 10) === CFG.date);
if (idx === -1) throw new Error('no-data');
const hours = [];
for (let i = 0; i < hTime.length; i++) {
if (String(hTime[i]).slice(0, 10) === CFG.date && Number.isFinite(hTemp[i])) {
hours.push({ t: hTime[i], v: hTemp[i] });
}
}
if (hours.length < 2) throw new Error('no-data');
const fallbackMax = Math.max.apply(null, hours.map(p => p.v));
const fallbackMin = Math.min.apply(null, hours.map(p => p.v));
return {
max: Number.isFinite(dMax[idx]) ? dMax[idx] : fallbackMax,
min: Number.isFinite(dMin[idx]) ? dMin[idx] : fallbackMin,
code: dCode[idx],
hours
};
}
/* ================= boot ================= */
function boot() {
/* starfield */
const stars = [];
for (let i = 0; i < 70; i++) {
const x = (Math.random() * 100).toFixed(2), y = (Math.random() * 100).toFixed(2);
const s = (Math.random() * 1.8 + 0.6).toFixed(2), o = (Math.random() * 0.45 + 0.25).toFixed(2);
stars.push(x + 'vw ' + y + 'vh 0 ' + s + 'px rgba(255,255,255,' + o + ')');
}
document.querySelector('.stars').style.boxShadow = stars.join(', ');
setLoading();
load()
.then(paint)
.catch(err => {
if (err && err.message === 'no-data') {
fail('No weather data for this date',
'The weather service returned no readings for ' + CFG.date + '. This date may be outside the supported range.');
} else {
fail('We couldn\u2019t load the weather data',
(err && err.message ? err.message + ' ' : '') + 'Please check the connection and try again.');
}
});
}
document.getElementById('retryBtn').addEventListener('click', () => location.reload());
boot();
})();
</script>
</body>
</html>L1 — cheap deterministic descriptors
| bytes total | 31,805 | html / css / js | 3,379 / 8,538 / 19,888 |
|---|---|---|---|
| dom nodes | 60 | dom depth | 9 |
| css rules | 84 | js present | yes |
| brightness | 35.3 | contrast | 33.2 |
| colorfulness | 69.1 | whitespace | 71.8% |
This slot's telemetry
| prompt tokens | 8,449 | completion tokens | 53,882 |
|---|---|---|---|
| total tokens | 62,331 | wall | 315.9 s |
| cost | — | request id | — |
config.json606 B
{
"N": 2,
"auth": {
"credential_ref": "WCB_DEEPSEEK_KEY",
"method": "api-key"
},
"billing": "api",
"config_id": "deepseek-v4-flash-0731-eff-high--cli--dsh--dev",
"effort": "high",
"family": "deepseek",
"m": {
"min": 2,
"q": 2
},
"model_id": "deepseek-v4-flash-0731",
"protocol": "cli",
"served_model": "deepseek-v4-flash",
"telemetry": {
"completion_tokens": 158003,
"cost_usd": null,
"prompt_tokens": 62140,
"total_tokens": 220143,
"wall_ms": 1433234
},
"transport": "dsh-0.1.0-rc.8-headless-isolated-home",
"vendor_sanction_ref": null
}send-log2.5 KB
{
"N": 2,
"batch_id": "2026-08-21--dsh-s1",
"config_id": "deepseek-v4-flash-0731-eff-high--cli--dsh--dev",
"positions": [
{
"attempts": [
{
"attempt_index": 0,
"backoff_ms": null,
"charged": true,
"ended_at": "2026-08-21T13:39:12.624375+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-21T13:33:56.726642+00:00"
}
],
"block_index": 0,
"model_reaching_attempt_index": 0,
"slot_index": 0,
"terminal_state": "valid",
"variant": "P-q"
},
{
"attempts": [
{
"attempt_index": 0,
"backoff_ms": null,
"charged": true,
"ended_at": "2026-08-21T13:50:09.754864+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-21T13:39:16.459464+00:00"
}
],
"block_index": 0,
"model_reaching_attempt_index": 0,
"slot_index": 0,
"terminal_state": "valid",
"variant": "P-min"
},
{
"attempts": [
{
"attempt_index": 0,
"backoff_ms": null,
"charged": true,
"ended_at": "2026-08-21T13:52:03.385941+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-21T13:50:13.135783+00:00"
}
],
"block_index": 1,
"model_reaching_attempt_index": 0,
"slot_index": 1,
"terminal_state": "valid",
"variant": "P-min"
},
{
"attempts": [
{
"attempt_index": 0,
"backoff_ms": null,
"charged": true,
"ended_at": "2026-08-21T13:58:01.050677+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-08-21T13:52:07.303064+00:00"
}
],
"block_index": 1,
"model_reaching_attempt_index": 0,
"slot_index": 1,
"terminal_state": "valid",
"variant": "P-q"
}
],
"retry_policy": {
"max_unreachable_retries": 5,
"rate_limit_backoff": {
"max_attempts": 4,
"max_total_ms": 60000
}
}
}