claude-opus-5-5 @ medium · CC
CCmedium
- config
- claude-opus-5-5-eff-medium--cli--claude-code--dev
- batch
- 2026-07-19--unified
- transport
- claude-code-cli-headless
- protocol
- cli · plan
- served model
- claude-opus-5-5
- 采集于
- 2026年7月18日 11:54 · N=2
variant
live
slot 0 · P-q · sandboxed iframe

截图是 similarity 通道测量时的原始像素。运行 live 会在 sandboxed iframe 中重新执行原始输出;渲染结果取决于你的浏览器和字体,不保证与测量像素一致。
similarity 邻居
最近
claude-fable-5-1 @high · CC0.71claude-opus-5 @xhigh · CC0.70claude-fable-5 @low · cursor-xl0.70kimi-k2.7-code · go0.69claude-opus-4-8-thinking @medium · cursor-xl0.69最远
north-mini-code-free · api0.51qwen3.5-plus · go0.52minimax-m2.5 · go0.53qwen3.6-plus · go0.53deepseek-v4-pro @high · api0.53限于 session 2026-07-19--unified
similarity 衡量本 session 内的趋同程度 —— 不是质量。
Fidelity —— 卡片展示的数据对不对?
- namematch
- conditionmatch
- datematch
- max tempmismatch展示值:13.4
- min tempmismatch展示值:52.52
- hourlyambiguouscoverage · 0 命中 · 0 不符 · 24 未展示
- request sidematch0 处违规
extractor fidelity-extractor-v1+Berlin-2026-07-15
源码 —— 原始模型输出,一字节未改
下载 card.html<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Weather</title>
<style>
:root {
--bg1: #1b5fbf;
--bg2: #3d9be9;
--accent: #ffcf5a;
--line: #ffffff;
--glass: rgba(255, 255, 255, 0.09);
--glass-strong: rgba(255, 255, 255, 0.14);
--muted: rgba(255, 255, 255, 0.68);
--faint: rgba(255, 255, 255, 0.42);
}
* { box-sizing: border-box; }
html, body { height: 100%; }
body {
margin: 0;
min-height: 100vh;
display: grid;
place-items: center;
padding: 24px;
font-family: -apple-system, BlinkMacSystemFont, "SF Pro Display", "Segoe UI", Inter, Roboto, "Helvetica Neue", Arial, sans-serif;
color: #fff;
background:
radial-gradient(900px 600px at 15% 0%, rgba(80, 120, 190, 0.35), transparent 70%),
radial-gradient(800px 600px at 100% 100%, rgba(120, 80, 170, 0.22), transparent 70%),
#0b1220;
-webkit-font-smoothing: antialiased;
font-feature-settings: "tnum" 1;
}
.card {
position: relative;
width: 1040px;
border-radius: 30px;
padding: 32px 44px 34px;
background: linear-gradient(150deg, var(--bg1) 0%, var(--bg2) 100%);
box-shadow:
0 50px 100px -30px rgba(0, 0, 0, 0.7),
0 0 0 1px rgba(255, 255, 255, 0.08),
inset 0 1px 0 rgba(255, 255, 255, 0.22);
overflow: hidden;
transition: background 0.6s ease;
isolation: isolate;
}
.card::before {
content: "";
position: absolute;
width: 620px; height: 620px;
right: -180px; top: -300px;
border-radius: 50%;
background: radial-gradient(circle, rgba(255, 255, 255, 0.22), transparent 65%);
z-index: -1;
pointer-events: none;
}
.card::after {
content: "";
position: absolute;
width: 520px; height: 520px;
left: -220px; bottom: -320px;
border-radius: 50%;
background: radial-gradient(circle, rgba(0, 0, 0, 0.22), transparent 65%);
z-index: -1;
pointer-events: none;
}
/* Header */
.top {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 24px;
}
.eyebrow {
font-size: 12px;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--muted);
font-weight: 600;
display: flex;
align-items: center;
gap: 8px;
}
.eyebrow svg { width: 14px; height: 14px; opacity: 0.85; }
h1 {
margin: 6px 0 4px;
font-size: 40px;
line-height: 1.1;
font-weight: 700;
letter-spacing: -0.02em;
max-width: 620px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.coords { font-size: 14px; color: var(--muted); }
.date-block { text-align: right; padding-top: 2px; }
.weekday { font-size: 14px; color: var(--muted); font-weight: 500; }
.date { display: block; font-size: 22px; font-weight: 600; margin-top: 4px; letter-spacing: -0.01em; }
.tag {
display: inline-block;
margin-top: 10px;
padding: 5px 12px;
border-radius: 999px;
font-size: 11px;
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
background: var(--glass-strong);
border: 1px solid rgba(255, 255, 255, 0.18);
}
/* Summary */
.summary {
margin-top: 26px;
display: grid;
grid-template-columns: 1.15fr 1fr 1fr;
gap: 16px;
}
.panel {
background: var(--glass);
border: 1px solid rgba(255, 255, 255, 0.12);
border-radius: 22px;
backdrop-filter: blur(6px);
}
.cond {
display: flex;
align-items: center;
gap: 18px;
padding: 18px 22px;
}
.icon { width: 104px; height: 104px; flex: none; filter: drop-shadow(0 8px 16px rgba(0,0,0,0.18)); animation: float 6s ease-in-out infinite; }
.icon svg { width: 100%; height: 100%; display: block; }
@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
.label { font-size: 12px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); font-weight: 600; }
.cond-text { font-size: 24px; font-weight: 650; line-height: 1.2; margin-top: 6px; letter-spacing: -0.01em; }
.cond-code { font-size: 13px; color: var(--faint); margin-top: 6px; }
.temps {
display: grid;
grid-template-columns: 1fr 1fr;
padding: 18px 8px;
}
.temp { padding: 0 16px; display: flex; flex-direction: column; justify-content: center; }
.temp + .temp { border-left: 1px solid rgba(255, 255, 255, 0.14); }
.temp .label { display: flex; align-items: center; gap: 6px; }
.temp .label svg { width: 12px; height: 12px; }
.temp-val { font-size: 46px; font-weight: 700; letter-spacing: -0.035em; line-height: 1; margin-top: 10px; white-space: nowrap; }
.temp-val .unit { font-size: 20px; font-weight: 500; color: var(--muted); letter-spacing: 0; margin-left: 2px; vertical-align: 18px; }
.temp.low .temp-val { color: rgba(255, 255, 255, 0.82); }
.stats {
padding: 16px 22px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px 18px;
align-content: center;
}
.stat .label { font-size: 11px; }
.stat-val { font-size: 19px; font-weight: 650; margin-top: 4px; letter-spacing: -0.01em; }
.stat-val small { font-size: 13px; font-weight: 500; color: var(--muted); }
/* Hourly */
.hourly { margin-top: 16px; padding: 18px 22px 20px; }
.hourly-head { display: flex; justify-content: space-between; align-items: baseline; }
.hourly-head h2 { margin: 0; font-size: 15px; font-weight: 650; letter-spacing: -0.005em; }
.hourly-head span { font-size: 12px; color: var(--muted); }
.chart { display: block; width: 100%; height: auto; margin-top: 8px; overflow: visible; }
.chart text { font-family: inherit; }
.grid {
margin-top: 10px;
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 6px;
}
.cell {
border-radius: 12px;
padding: 7px 0 8px;
text-align: center;
background: rgba(255, 255, 255, 0.05);
border: 1px solid transparent;
position: relative;
}
.cell .t { font-size: 11px; color: var(--muted); font-weight: 500; }
.cell .v { font-size: 15px; font-weight: 650; margin-top: 3px; letter-spacing: -0.01em; }
.cell.max { background: rgba(255, 255, 255, 0.16); border-color: rgba(255, 255, 255, 0.28); }
.cell.min { background: rgba(0, 0, 0, 0.14); border-color: rgba(255, 255, 255, 0.14); }
.cell.now { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.cell.now .t { color: var(--accent); font-weight: 700; }
.cell .v.na { color: var(--faint); }
/* Loading */
.skeleton { margin-top: 26px; }
.sk-row { display: grid; grid-template-columns: 1.15fr 1fr 1fr; gap: 16px; }
.sk {
border-radius: 22px;
background: linear-gradient(90deg, rgba(255,255,255,0.07) 0%, rgba(255,255,255,0.16) 50%, rgba(255,255,255,0.07) 100%);
background-size: 200% 100%;
animation: shimmer 1.4s linear infinite;
}
.sk-row .sk { height: 140px; }
.sk.big { height: 330px; margin-top: 16px; }
@keyframes shimmer { from { background-position: 200% 0; } to { background-position: -200% 0; } }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
/* Error */
.error {
margin-top: 26px;
padding: 48px 40px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 10px;
}
.error svg { width: 64px; height: 64px; opacity: 0.9; }
.error h2 { margin: 8px 0 0; font-size: 24px; font-weight: 700; letter-spacing: -0.01em; }
.error p { margin: 0; color: var(--muted); font-size: 15px; max-width: 560px; line-height: 1.5; }
.error .detail { font-size: 13px; color: var(--faint); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.btn {
margin-top: 14px;
font: inherit;
font-size: 14px;
font-weight: 600;
color: #fff;
padding: 10px 22px;
border-radius: 999px;
border: 1px solid rgba(255, 255, 255, 0.3);
background: rgba(255, 255, 255, 0.14);
cursor: pointer;
transition: background 0.2s;
}
.btn:hover { background: rgba(255, 255, 255, 0.24); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
[hidden] { display: none !important; }
.footer { margin-top: 14px; font-size: 11px; color: var(--faint); text-align: right; letter-spacing: 0.02em; }
</style>
</head>
<body>
<main class="card" id="card" aria-busy="true">
<header class="top">
<div>
<div class="eyebrow">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 21s-7-6.2-7-11.5A7 7 0 0 1 19 9.5C19 14.8 12 21 12 21z"/><circle cx="12" cy="9.5" r="2.5"/></svg>
<span>Daily weather</span>
</div>
<h1 id="loc">Berlin</h1>
<div class="coords" id="coords"></div>
</div>
<div class="date-block">
<div class="weekday" id="weekday"></div>
<time class="date" id="date"></time>
<span class="tag" id="tag">Forecast</span>
</div>
</header>
<section class="skeleton" id="loading" aria-live="polite">
<span class="sr-only">Loading weather data…</span>
<div class="sk-row"><div class="sk"></div><div class="sk"></div><div class="sk"></div></div>
<div class="sk big"></div>
</section>
<section id="error" class="panel error" role="alert" hidden>
<svg viewBox="0 0 64 64" fill="none" aria-hidden="true">
<path d="M20 44h26a10 10 0 0 0 0-20 14 14 0 0 0-27-3A11.5 11.5 0 0 0 20 44z" fill="rgba(255,255,255,0.9)"/>
<path d="M22 52l20-20M42 52L22 32" stroke="#ff7a7a" stroke-width="0" />
<circle cx="46" cy="46" r="11" fill="#ff6b6b"/>
<path d="M46 40v7" stroke="#fff" stroke-width="3" stroke-linecap="round"/>
<circle cx="46" cy="51.5" r="1.8" fill="#fff"/>
</svg>
<h2>Weather data could not be loaded</h2>
<p id="error-msg">We couldn’t retrieve the weather for this location and date. Please check your connection or try again.</p>
<div class="detail" id="error-detail"></div>
<button class="btn" id="retry" type="button">Try again</button>
</section>
<section id="content" hidden>
<div class="summary">
<div class="panel cond">
<div class="icon" id="icon" aria-hidden="true"></div>
<div>
<div class="label">Condition</div>
<div class="cond-text" id="cond">—</div>
<div class="cond-code" id="cond-code"></div>
</div>
</div>
<div class="panel temps">
<div class="temp high">
<div class="label">
<svg viewBox="0 0 12 12" aria-hidden="true"><path d="M6 1.5l4 5H2z" fill="currentColor"/></svg>
High
</div>
<div class="temp-val" id="tmax">—</div>
</div>
<div class="temp low">
<div class="label">
<svg viewBox="0 0 12 12" aria-hidden="true"><path d="M6 10.5l4-5H2z" fill="currentColor"/></svg>
Low
</div>
<div class="temp-val" id="tmin">—</div>
</div>
</div>
<div class="panel stats">
<div class="stat"><div class="label">Daily range</div><div class="stat-val" id="s-range">—</div></div>
<div class="stat"><div class="label">Hourly avg</div><div class="stat-val" id="s-avg">—</div></div>
<div class="stat"><div class="label">Warmest</div><div class="stat-val" id="s-warm">—</div></div>
<div class="stat"><div class="label">Coolest</div><div class="stat-val" id="s-cool">—</div></div>
</div>
</div>
<div class="panel hourly">
<div class="hourly-head">
<h2>Hourly temperature</h2>
<span>°C · times in UTC</span>
</div>
<svg class="chart" id="chart" viewBox="0 0 952 170" role="img" aria-label="Hourly temperature chart"></svg>
<div class="grid" id="grid"></div>
</div>
</section>
<div class="footer" id="footer"></div>
</main>
<script>
(function () {
'use strict';
// ---------- Parameters ----------
var DEFAULTS = { lat: 52.52, lon: 13.405, name: 'Berlin' };
var params = new URLSearchParams(window.location.search);
function todayUTC() { return new Date().toISOString().slice(0, 10); }
function parseNum(v, min, max, def) {
if (v === null || v.trim() === '') return def;
var n = Number(v);
return (isFinite(n) && n >= min && n <= max) ? n : def;
}
function validDate(s) {
if (!s || !/^\d{4}-\d{2}-\d{2}$/.test(s)) return false;
var d = new Date(s + 'T00:00:00Z');
return !isNaN(d.getTime()) && d.toISOString().slice(0, 10) === s;
}
var lat = parseNum(params.get('lat'), -90, 90, DEFAULTS.lat);
var lon = parseNum(params.get('lon'), -180, 180, DEFAULTS.lon);
var rawName = params.get('name');
var name = (rawName && rawName.trim()) ? rawName.trim() : DEFAULTS.name;
var today = todayUTC();
var rawDate = params.get('date');
var date = validDate(rawDate) ? rawDate : today;
// ---------- Elements ----------
var $ = function (id) { return document.getElementById(id); };
var card = $('card');
// ---------- Header ----------
$('loc').textContent = name;
$('loc').title = name;
document.title = name + ' · Weather · ' + date;
$('coords').textContent =
Math.abs(lat).toFixed(2) + '°' + (lat >= 0 ? 'N' : 'S') + ', ' +
Math.abs(lon).toFixed(2) + '°' + (lon >= 0 ? 'E' : 'W');
var dateObj = new Date(date + 'T00:00:00Z');
$('weekday').textContent = dateObj.toLocaleDateString('en-GB', { weekday: 'long', timeZone: 'UTC' });
$('date').textContent = dateObj.toLocaleDateString('en-GB', { day: 'numeric', month: 'long', year: 'numeric', timeZone: 'UTC' });
$('date').setAttribute('datetime', date);
$('tag').textContent = date === today ? 'Today' : (date < today ? 'Historical' : 'Forecast');
// ---------- Formatting ----------
function fmt(v) {
var s = (Math.round(v * 10) / 10).toFixed(1);
return s === '-0.0' ? '0.0' : s;
}
function isNum(v) { return typeof v === 'number' && isFinite(v); }
// ---------- Weather codes ----------
var WMO = {
0: ['Clear sky', 'clear'], 1: ['Mainly clear', 'clear'], 2: ['Partly cloudy', 'partly'], 3: ['Overcast', 'cloudy'],
45: ['Fog', 'fog'], 48: ['Depositing rime fog', 'fog'],
51: ['Light drizzle', 'drizzle'], 53: ['Moderate drizzle', 'drizzle'], 55: ['Dense drizzle', 'drizzle'],
56: ['Light freezing drizzle', 'drizzle'], 57: ['Dense freezing drizzle', 'drizzle'],
61: ['Slight rain', 'rain'], 63: ['Moderate rain', 'rain'], 65: ['Heavy rain', 'rain'],
66: ['Light freezing rain', 'rain'], 67: ['Heavy freezing rain', 'rain'],
71: ['Slight snowfall', 'snow'], 73: ['Moderate snowfall', 'snow'], 75: ['Heavy snowfall', 'snow'], 77: ['Snow grains', 'snow'],
80: ['Slight rain showers', 'showers'], 81: ['Moderate rain showers', 'showers'], 82: ['Violent rain showers', 'showers'],
85: ['Slight snow showers', 'snow'], 86: ['Heavy snow showers', 'snow'],
95: ['Thunderstorm', 'storm'], 96: ['Thunderstorm with slight hail', 'storm'], 99: ['Thunderstorm with heavy hail', 'storm']
};
var THEMES = {
clear: ['#1b5fbf', '#3f9fea', '#ffcf5a'],
partly: ['#2a5a93', '#6a9dcc', '#ffd772'],
cloudy: ['#37475b', '#6c7d92', '#dfe8f2'],
fog: ['#4a5561', '#8a96a4', '#e9eef3'],
drizzle: ['#234565', '#557a9e', '#8fd6ff'],
rain: ['#1a3050', '#3c6187', '#7fd0ff'],
showers: ['#1f3a5c', '#4a79a6', '#8fd6ff'],
snow: ['#45658a', '#9bb8d6', '#ffffff'],
storm: ['#1c1937', '#4a3f74', '#ffd84a'],
unknown: ['#25364c', '#4a6283', '#ffd772']
};
function applyTheme(kind) {
var t = THEMES[kind] || THEMES.unknown;
card.style.setProperty('--bg1', t[0]);
card.style.setProperty('--bg2', t[1]);
card.style.setProperty('--accent', t[2]);
}
// ---------- Icons ----------
function sun(cx, cy, r) {
var rays = '';
for (var i = 0; i < 8; i++) {
var a = i * Math.PI / 4;
var c = Math.cos(a), s = Math.sin(a);
rays += '<line x1="' + (cx + c * (r + 4.5)).toFixed(1) + '" y1="' + (cy + s * (r + 4.5)).toFixed(1) +
'" x2="' + (cx + c * (r + 9)).toFixed(1) + '" y2="' + (cy + s * (r + 9)).toFixed(1) + '"/>';
}
return '<g stroke="#FFC94A" stroke-width="3" stroke-linecap="round">' + rays + '</g>' +
'<circle cx="' + cx + '" cy="' + cy + '" r="' + r + '" fill="#FFC94A"/>' +
'<circle cx="' + (cx - r * 0.3) + '" cy="' + (cy - r * 0.3) + '" r="' + (r * 0.45) + '" fill="#FFE08A" opacity=".7"/>';
}
function cloud(fill, transform) {
return '<path transform="' + (transform || '') + '" d="M20 50h26a10 10 0 0 0 0-20 14 14 0 0 0-27-3A11.5 11.5 0 0 0 20 50z" fill="' + fill + '"/>';
}
function drops(color, short) {
var out = '';
[[22, 0], [32, 3], [42, 0]].forEach(function (p) {
var x = p[0], dy = p[1];
out += short
? '<line x1="' + x + '" y1="' + (51 + dy) + '" x2="' + (x - 1.5) + '" y2="' + (55 + dy) + '"/>'
: '<line x1="' + (x + 2) + '" y1="' + (49 + dy) + '" x2="' + (x - 2) + '" y2="' + (58 + dy) + '"/>';
});
return '<g stroke="' + color + '" stroke-width="3" stroke-linecap="round">' + out + '</g>';
}
function flakes() {
var out = '';
[[21, 52], [32, 57], [43, 52]].forEach(function (p) {
out += '<g transform="translate(' + p[0] + ' ' + p[1] + ')"><line x1="-3.5" y1="0" x2="3.5" y2="0"/><line x1="-1.75" y1="-3" x2="1.75" y2="3"/><line x1="-1.75" y1="3" x2="1.75" y2="-3"/></g>';
});
return '<g stroke="#ffffff" stroke-width="1.8" stroke-linecap="round">' + out + '</g>';
}
function icon(kind) {
var s = '<svg viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg">';
switch (kind) {
case 'clear': s += sun(32, 32, 12); break;
case 'partly': s += sun(24, 22, 9) + cloud('#ffffff', 'translate(6 7)'); break;
case 'cloudy': s += cloud('#b9c6d4', 'translate(12 -6) scale(.85)') + cloud('#eef3f8', 'translate(0 4)'); break;
case 'fog':
s += cloud('#e3e9ef', 'translate(0 -8)') +
'<g stroke="#e3e9ef" stroke-width="3" stroke-linecap="round" opacity=".85"><line x1="12" y1="49" x2="52" y2="49"/><line x1="18" y1="56" x2="46" y2="56"/></g>';
break;
case 'drizzle': s += cloud('#f2f6fa', 'translate(0 -6)') + drops('#8fd6ff', true); break;
case 'rain': s += cloud('#e6edf4', 'translate(0 -6)') + drops('#7fd0ff', false); break;
case 'showers': s += sun(22, 16, 7) + cloud('#f2f6fa', 'translate(2 -3)') + drops('#8fd6ff', false); break;
case 'snow': s += cloud('#ffffff', 'translate(0 -6)') + flakes(); break;
case 'storm':
s += cloud('#cfd3e6', 'translate(0 -7)') +
'<path d="M34 40l-9 12h6l-4 10 12-14h-6l4-8z" fill="#FFD84A" stroke="#FFD84A" stroke-width="1" stroke-linejoin="round"/>';
break;
default:
s += cloud('rgba(255,255,255,.75)', 'translate(0 2)') +
'<text x="33" y="45" font-size="16" font-weight="700" text-anchor="middle" fill="#3a4a60" font-family="sans-serif">?</text>';
}
return s + '</svg>';
}
// ---------- Chart ----------
var SVGNS = 'http://www.w3.org/2000/svg';
function monotonePath(pts) {
var n = pts.length;
if (n === 0) return '';
if (n === 1) return 'M' + pts[0][0] + ',' + pts[0][1];
var dx = [], m = [], t = [], i;
for (i = 0; i < n - 1; i++) {
dx[i] = pts[i + 1][0] - pts[i][0];
m[i] = (pts[i + 1][1] - pts[i][1]) / dx[i];
}
t[0] = m[0]; t[n - 1] = m[n - 2];
for (i = 1; i < n - 1; i++) t[i] = (m[i - 1] * m[i] <= 0) ? 0 : (m[i - 1] + m[i]) / 2;
for (i = 0; i < n - 1; i++) {
if (m[i] === 0) { t[i] = 0; t[i + 1] = 0; continue; }
var a = t[i] / m[i], b = t[i + 1] / m[i], s = a * a + b * b;
if (s > 9) { var tau = 3 / Math.sqrt(s); t[i] = tau * a * m[i]; t[i + 1] = tau * b * m[i]; }
}
var d = 'M' + pts[0][0].toFixed(2) + ',' + pts[0][1].toFixed(2);
for (i = 0; i < n - 1; i++) {
var h = dx[i] / 3;
d += 'C' + (pts[i][0] + h).toFixed(2) + ',' + (pts[i][1] + t[i] * h).toFixed(2) + ' ' +
(pts[i + 1][0] - h).toFixed(2) + ',' + (pts[i + 1][1] - t[i + 1] * h).toFixed(2) + ' ' +
pts[i + 1][0].toFixed(2) + ',' + pts[i + 1][1].toFixed(2);
}
return d;
}
function niceStep(range) {
var raw = range / 4;
var steps = [0.5, 1, 2, 2.5, 5, 10, 20];
for (var i = 0; i < steps.length; i++) if (steps[i] >= raw) return steps[i];
return 20;
}
function el(tag, attrs, text) {
var e = document.createElementNS(SVGNS, tag);
for (var k in attrs) e.setAttribute(k, attrs[k]);
if (text != null) e.textContent = text;
return e;
}
function drawChart(hours, nowHour) {
var svg = $('chart');
while (svg.firstChild) svg.removeChild(svg.firstChild);
var W = 952, H = 170, pl = 40, pr = 16, pt = 26, pb = 26;
var valid = hours.filter(function (h) { return isNum(h.temp); });
if (!valid.length) return;
var lo = Math.min.apply(null, valid.map(function (h) { return h.temp; }));
var hi = Math.max.apply(null, valid.map(function (h) { return h.temp; }));
var step = niceStep(Math.max(hi - lo, 2));
var yMin = Math.floor((lo - step * 0.25) / step) * step;
var yMax = Math.ceil((hi + step * 0.25) / step) * step;
if (yMax === yMin) yMax = yMin + step;
var x = function (hr) { return pl + hr * (W - pl - pr) / 23; };
var y = function (v) { return pt + (yMax - v) * (H - pt - pb) / (yMax - yMin); };
var defs = el('defs', {});
var grad = el('linearGradient', { id: 'area', x1: 0, y1: 0, x2: 0, y2: 1 });
grad.appendChild(el('stop', { offset: '0%', 'stop-color': '#ffffff', 'stop-opacity': '0.34' }));
grad.appendChild(el('stop', { offset: '100%', 'stop-color': '#ffffff', 'stop-opacity': '0' }));
defs.appendChild(grad);
svg.appendChild(defs);
// Gridlines + y labels
for (var v = yMin; v <= yMax + 1e-9; v += step) {
var yy = y(v);
svg.appendChild(el('line', { x1: pl, x2: W - pr, y1: yy, y2: yy, stroke: 'rgba(255,255,255,0.12)', 'stroke-width': 1, 'stroke-dasharray': '2 5' }));
svg.appendChild(el('text', { x: pl - 10, y: yy + 4, 'text-anchor': 'end', 'font-size': 11, fill: 'rgba(255,255,255,0.55)' },
(Math.round(v * 10) / 10) + '°'));
}
// X labels
for (var hr = 0; hr < 24; hr += 3) {
svg.appendChild(el('text', { x: x(hr), y: H - 6, 'text-anchor': 'middle', 'font-size': 11, fill: 'rgba(255,255,255,0.55)' },
(hr < 10 ? '0' : '') + hr + ':00'));
}
// Now marker
if (nowHour != null) {
var nx = x(nowHour);
svg.appendChild(el('line', { x1: nx, x2: nx, y1: pt - 10, y2: H - pb, stroke: 'var(--accent)', 'stroke-width': 1.5, 'stroke-dasharray': '3 4', opacity: 0.9 }));
svg.appendChild(el('text', { x: nx, y: pt - 14, 'text-anchor': 'middle', 'font-size': 10, 'font-weight': 700, fill: 'var(--accent)', 'letter-spacing': '0.08em' }, 'NOW'));
}
// Segments (break on missing values)
var segs = [], cur = [];
hours.forEach(function (h) {
if (isNum(h.temp)) cur.push([x(h.hour), y(h.temp)]);
else if (cur.length) { segs.push(cur); cur = []; }
});
if (cur.length) segs.push(cur);
var base = H - pb;
segs.forEach(function (pts) {
var line = monotonePath(pts);
if (pts.length > 1) {
svg.appendChild(el('path', {
d: line + 'L' + pts[pts.length - 1][0] + ',' + base + 'L' + pts[0][0] + ',' + base + 'Z',
fill: 'url(#area)'
}));
}
svg.appendChild(el('path', { d: line, fill: 'none', stroke: '#ffffff', 'stroke-width': 3, 'stroke-linecap': 'round', 'stroke-linejoin': 'round' }));
});
// Small dots for each hour
valid.forEach(function (h) {
svg.appendChild(el('circle', { cx: x(h.hour), cy: y(h.temp), r: 2.2, fill: 'rgba(255,255,255,0.75)' }));
});
// Max / min markers
var maxH = valid.reduce(function (a, b) { return b.temp > a.temp ? b : a; });
var minH = valid.reduce(function (a, b) { return b.temp < a.temp ? b : a; });
function marker(h, above) {
var cx = x(h.hour), cy = y(h.temp);
svg.appendChild(el('circle', { cx: cx, cy: cy, r: 9, fill: 'rgba(255,255,255,0.18)' }));
svg.appendChild(el('circle', { cx: cx, cy: cy, r: 5, fill: above ? 'var(--accent)' : '#ffffff', stroke: 'rgba(0,0,0,0.15)', 'stroke-width': 1 }));
var anchor = h.hour <= 1 ? 'start' : (h.hour >= 22 ? 'end' : 'middle');
svg.appendChild(el('text', {
x: cx, y: above ? cy - 14 : cy + 22, 'text-anchor': anchor,
'font-size': 13, 'font-weight': 700, fill: '#ffffff'
}, fmt(h.temp) + '°'));
}
if (maxH !== minH) { marker(maxH, true); marker(minH, false); }
else marker(maxH, true);
svg.setAttribute('aria-label', 'Hourly temperature chart, from ' + fmt(lo) + ' to ' + fmt(hi) + ' degrees Celsius');
}
// ---------- Render ----------
function hourLabel(h) { return (h < 10 ? '0' : '') + h + ':00'; }
function render(data) {
var kind = data.code != null && WMO[data.code] ? WMO[data.code][1] : 'unknown';
applyTheme(kind);
$('icon').innerHTML = icon(kind);
$('cond').textContent = data.code != null && WMO[data.code] ? WMO[data.code][0]
: (data.code != null ? 'Weather code ' + data.code : 'Condition unavailable');
$('cond-code').textContent = data.code != null ? 'WMO code ' + data.code : '';
function setTemp(id, v) {
var node = $(id);
node.textContent = '';
if (!isNum(v)) { node.textContent = '—'; return; }
node.appendChild(document.createTextNode(fmt(v)));
var u = document.createElement('span');
u.className = 'unit';
u.textContent = '°C';
node.appendChild(u);
}
setTemp('tmax', data.max);
setTemp('tmin', data.min);
var valid = data.hours.filter(function (h) { return isNum(h.temp); });
if (isNum(data.max) && isNum(data.min)) $('s-range').innerHTML = fmt(data.max - data.min) + '<small> °C</small>';
if (valid.length) {
var avg = valid.reduce(function (s, h) { return s + h.temp; }, 0) / valid.length;
$('s-avg').innerHTML = fmt(avg) + '<small> °C</small>';
var w = valid.reduce(function (a, b) { return b.temp > a.temp ? b : a; });
var c = valid.reduce(function (a, b) { return b.temp < a.temp ? b : a; });
$('s-warm').innerHTML = hourLabel(w.hour) + '<small> · ' + fmt(w.temp) + '°</small>';
$('s-cool').innerHTML = hourLabel(c.hour) + '<small> · ' + fmt(c.temp) + '°</small>';
}
var nowHour = date === todayUTC() ? new Date().getUTCHours() : null;
drawChart(data.hours, nowHour);
var grid = $('grid');
grid.textContent = '';
var maxT = valid.length ? Math.max.apply(null, valid.map(function (h) { return h.temp; })) : null;
var minT = valid.length ? Math.min.apply(null, valid.map(function (h) { return h.temp; })) : null;
data.hours.forEach(function (h) {
var cell = document.createElement('div');
cell.className = 'cell';
if (isNum(h.temp) && h.temp === maxT && maxT !== minT) cell.classList.add('max');
if (isNum(h.temp) && h.temp === minT && maxT !== minT) cell.classList.add('min');
if (nowHour === h.hour) cell.classList.add('now');
var t = document.createElement('div');
t.className = 't';
t.textContent = nowHour === h.hour ? 'Now' : hourLabel(h.hour);
var v = document.createElement('div');
v.className = 'v';
if (isNum(h.temp)) v.textContent = fmt(h.temp) + '°';
else { v.textContent = '—'; v.classList.add('na'); }
cell.title = hourLabel(h.hour) + ' UTC: ' + (isNum(h.temp) ? fmt(h.temp) + ' °C' : 'no data');
cell.appendChild(t);
cell.appendChild(v);
grid.appendChild(cell);
});
$('footer').textContent = 'Source: ' + (data.source === 'archive' ? 'historical archive' : 'forecast model') + ' · all values in °C';
show('content');
}
function show(which) {
$('loading').hidden = which !== 'loading';
$('content').hidden = which !== 'content';
$('error').hidden = which !== 'error';
card.setAttribute('aria-busy', which === 'loading' ? 'true' : 'false');
if (which !== 'content') $('footer').textContent = '';
}
function showError(detail) {
applyTheme('unknown');
$('error-detail').textContent = detail || '';
show('error');
}
// ---------- Data ----------
function buildUrl(endpoint) {
var q = new URLSearchParams({
latitude: String(lat),
longitude: String(lon),
daily: 'temperature_2m_max,temperature_2m_min,weather_code',
hourly: 'temperature_2m',
timezone: 'UTC',
temperature_unit: 'celsius',
start_date: date,
end_date: date
});
return '/api/om/' + endpoint + '?' + q.toString();
}
function fetchJson(url) {
var ctrl = typeof AbortController !== 'undefined' ? new AbortController() : null;
var timer = ctrl ? setTimeout(function () { ctrl.abort(); }, 15000) : null;
return fetch(url, { signal: ctrl ? ctrl.signal : undefined, headers: { Accept: 'application/json' } })
.then(function (res) {
return res.text().then(function (text) {
var json = null;
try { json = JSON.parse(text); } catch (e) { /* not JSON */ }
if (!res.ok) {
throw new Error((json && json.reason) ? json.reason : 'Server responded with HTTP ' + res.status);
}
if (!json) throw new Error('Invalid response from server');
if (json.error) throw new Error(json.reason || 'The weather service returned an error');
return json;
});
}, function (err) {
throw new Error(err && err.name === 'AbortError' ? 'Request timed out' : 'Network error');
})
.finally(function () { if (timer) clearTimeout(timer); });
}
function extract(json, source) {
var daily = json.daily, hourly = json.hourly;
if (!daily || !Array.isArray(daily.time)) throw new Error('Response contains no daily data');
var idx = daily.time.indexOf(date);
if (idx < 0) throw new Error('No data for ' + date + ' in response');
var pick = function (arr) { return Array.isArray(arr) && isNum(arr[idx]) ? arr[idx] : null; };
var max = pick(daily.temperature_2m_max);
var min = pick(daily.temperature_2m_min);
var code = pick(daily.weather_code);
var hours = [];
if (hourly && Array.isArray(hourly.time)) {
var temps = Array.isArray(hourly.temperature_2m) ? hourly.temperature_2m : [];
hourly.time.forEach(function (t, i) {
if (typeof t === 'string' && t.slice(0, 10) === date) {
hours.push({ hour: parseInt(t.slice(11, 13), 10) || 0, temp: isNum(temps[i]) ? temps[i] : null });
}
});
}
hours.sort(function (a, b) { return a.hour - b.hour; });
var validTemps = hours.filter(function (h) { return isNum(h.temp); }).map(function (h) { return h.temp; });
if (max === null && validTemps.length) max = Math.max.apply(null, validTemps);
if (min === null && validTemps.length) min = Math.min.apply(null, validTemps);
if (max === null && min === null && !validTemps.length) {
throw new Error('No temperature data available for ' + date);
}
return { max: max, min: min, code: code, hours: hours, source: source };
}
function load() {
show('loading');
var now = todayUTC();
var primary = date < now ? 'archive' : 'forecast';
// Recent past days may not yet be in the archive; the forecast API covers them.
var fallback = date < now ? 'forecast' : null;
fetchJson(buildUrl(primary))
.then(function (json) { return extract(json, primary); })
.catch(function (err) {
if (!fallback) throw err;
return fetchJson(buildUrl(fallback))
.then(function (json) { return extract(json, fallback); })
.catch(function () { throw err; });
})
.then(render)
.catch(function (err) { showError(err && err.message ? err.message : 'Unknown error'); });
}
$('retry').addEventListener('click', load);
load();
})();
</script>
</body>
</html>L1 —— 廉价的确定性描述量
| bytes 总计 | 32,204 | html / css / js | 3,813 / 8,209 / 20,182 |
|---|---|---|---|
| dom 节点 | 79 | dom 深度 | 9 |
| css 规则 | 73 | 含 js | 是 |
| brightness | 82.3 | contrast | 42.4 |
| colorfulness | 31.2 | 留白 | 42.7% |
该 slot 的 telemetry
| prompt tokens | 2 | completion tokens | 21,465 |
|---|---|---|---|
| total tokens | 21,467 | wall | 173.2 s |
| cost | — | request id | — |
config.json577 B
{
"N": 2,
"auth": {
"credential_ref": "WCB_NONE",
"method": "oauth-login"
},
"billing": "plan",
"config_id": "claude-opus-5-5-eff-medium--cli--claude-code--dev",
"effort": "medium",
"family": "claude",
"m": {
"min": 2,
"q": 2
},
"model_id": "claude-opus-5-5",
"protocol": "cli",
"served_model": "claude-opus-5-5",
"telemetry": {
"completion_tokens": 48063,
"cost_usd": null,
"prompt_tokens": 8,
"total_tokens": 48071,
"wall_ms": 367510
},
"transport": "claude-code-cli-headless",
"vendor_sanction_ref": null
}send-log2.5 KB
{
"N": 2,
"batch_id": "2026-09-23--cc-opus55",
"config_id": "claude-opus-5-5-eff-medium--cli--claude-code--dev",
"positions": [
{
"attempts": [
{
"attempt_index": 0,
"backoff_ms": null,
"charged": true,
"ended_at": "2026-09-23T03:59:51.082952+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-09-23T03:56:57.856356+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-09-23T04:00:46.997974+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-09-23T03:59:54.807128+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-09-23T04:01:33.144633+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-09-23T04:00:50.163322+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-09-23T04:03:15.768578+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-09-23T04:01:36.657936+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
}
}
}