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

截图是 similarity 通道测量时的原始像素。运行 live 会在 sandboxed iframe 中重新执行原始输出;渲染结果取决于你的浏览器和字体,不保证与测量像素一致。
similarity 邻居本 session 没有 similarity 数据 —— 这个 batch 没有计算 pairs。
Fidelity —— 卡片展示的数据对不对?
- namematch
- conditionmatch
- datematch
- max tempmismatch展示值:52.52
- min tempmismatch展示值:13.4
- 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{
color-scheme:light;
--surface:#fcfcfb;
--ink:#0b0b0b; --ink-2:#52514e; --ink-3:#898781;
--grid:#e1e0d9; --axis:#c3c2b7; --border:rgba(11,11,11,.10);
--series:#2a78d6; --series-rgb:42,120,214;
--chip:rgba(11,11,11,.05); --chip-ink:#52514e;
--tip-bg:#0b0b0b; --tip-ink:#fcfcfb;
--sky-a:#eaeef3; --sky-b:#dfe4ea; --glow:transparent;
--ic-cloud:#d3d8de; --ic-cloud-2:#a7b0bb; --ic-sun:#f2b322; --ic-rain:#3987e5;
--ic-snow:#8dbbe9; --ic-bolt:#f0a500; --ic-fog:#aab3bd;
--shadow:0 1px 2px rgba(11,11,11,.05), 0 28px 70px -28px rgba(11,11,11,.28);
--sk:rgba(11,11,11,.06);
}
body[data-sky="clear"]{--sky-a:#fbefd9;--sky-b:#d3e4f6;--glow:rgba(255,190,70,.38)}
body[data-sky="cloudy"]{--sky-a:#edf1f5;--sky-b:#dde3ea;--glow:rgba(255,205,110,.18)}
body[data-sky="overcast"]{--sky-a:#e5e7ea;--sky-b:#cfd3d8}
body[data-sky="fog"]{--sky-a:#ebebe8;--sky-b:#d7d7d3}
body[data-sky="rain"]{--sky-a:#dfe6ee;--sky-b:#c2cedb}
body[data-sky="snow"]{--sky-a:#f0f4f9;--sky-b:#dbe3ec}
body[data-sky="storm"]{--sky-a:#d4d9e1;--sky-b:#adb6c3}
@media (prefers-color-scheme:dark){
:root{
color-scheme:dark;
--surface:#1a1a19;
--ink:#ffffff; --ink-2:#c3c2b7; --ink-3:#898781;
--grid:#2c2c2a; --axis:#383835; --border:rgba(255,255,255,.10);
--series:#3987e5; --series-rgb:57,135,229;
--chip:rgba(255,255,255,.07); --chip-ink:#c3c2b7;
--tip-bg:#f4f4f2; --tip-ink:#0b0b0b;
--sky-a:#1a1d24; --sky-b:#0b0c0f;
--ic-cloud:#9aa3ae; --ic-cloud-2:#6a7481; --ic-sun:#f6bb2e; --ic-rain:#5fa1ee;
--ic-snow:#a9cdf2; --ic-bolt:#f5b31c; --ic-fog:#7d8792;
--shadow:0 1px 2px rgba(0,0,0,.4), 0 28px 70px -28px rgba(0,0,0,.8);
--sk:rgba(255,255,255,.07);
}
body[data-sky="clear"]{--sky-a:#1f2538;--sky-b:#0a0c12;--glow:rgba(255,170,60,.16)}
body[data-sky="cloudy"]{--sky-a:#1b2028;--sky-b:#0b0d10;--glow:rgba(255,170,60,.08)}
body[data-sky="overcast"]{--sky-a:#1a1c20;--sky-b:#0c0d0f}
body[data-sky="fog"]{--sky-a:#1c1c1b;--sky-b:#0d0d0c}
body[data-sky="rain"]{--sky-a:#161d27;--sky-b:#090c11}
body[data-sky="snow"]{--sky-a:#1b2029;--sky-b:#0c0e12}
body[data-sky="storm"]{--sky-a:#14161c;--sky-b:#08090b}
}
*{box-sizing:border-box}
html{height:100%}
body{
margin:0; min-height:100%; padding:24px;
font-family:system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
color:var(--ink);
background:linear-gradient(135deg,var(--sky-a),var(--sky-b)) fixed;
display:grid; place-items:center;
-webkit-font-smoothing:antialiased;
}
body::before{
content:""; position:fixed; inset:0; pointer-events:none;
background:radial-gradient(680px 440px at 86% 6%, var(--glow), transparent 70%);
}
.card{
position:relative; z-index:1;
width:100%; max-width:1160px;
background:var(--surface);
border:1px solid var(--border); border-radius:24px;
box-shadow:var(--shadow);
padding:32px 40px 26px;
}
/* Header */
.head{display:flex; justify-content:space-between; align-items:flex-start; gap:24px}
.place{
margin:0; font-size:32px; font-weight:650; letter-spacing:-.022em; line-height:1.1;
max-width:760px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}
.date{margin:8px 0 0; font-size:16px; color:var(--ink-2)}
.meta{display:flex; align-items:center; gap:14px; margin-top:8px; font-size:13px; color:var(--ink-3); font-variant-numeric:tabular-nums}
.meta .dot{width:3px;height:3px;border-radius:50%;background:var(--axis)}
.chips{display:flex; gap:8px; flex:none; padding-top:6px}
.chip{
display:inline-flex; align-items:center; gap:6px; padding:6px 11px; border-radius:999px;
background:var(--chip); color:var(--chip-ink); font-size:12.5px; font-weight:600; letter-spacing:.01em; white-space:nowrap;
}
.chip.accent{color:var(--surface); background:var(--ink)}
/* Body states */
.body{min-height:440px; position:relative}
[hidden]{display:none !important}
/* Hero */
.hero{
display:flex; justify-content:space-between; align-items:center; gap:32px;
margin-top:24px; padding:22px 0; border-top:1px solid var(--grid); border-bottom:1px solid var(--grid);
}
.cond{display:flex; align-items:center; gap:20px; min-width:0}
.icon{width:96px; height:96px; flex:none}
.icon svg{width:100%; height:100%; display:block; overflow:visible}
.cond-name{margin:0; font-size:28px; font-weight:600; letter-spacing:-.015em; line-height:1.15}
.cond-sub{margin:5px 0 0; font-size:14px; color:var(--ink-3)}
.stats{display:flex; flex:none}
.stat{padding:2px 36px 0; border-left:1px solid var(--grid)}
.stat:first-child{border-left:0; padding-left:0}
.stat:last-child{padding-right:8px}
.stat-label{display:flex; align-items:center; gap:6px; font-size:12px; font-weight:600; letter-spacing:.08em; text-transform:uppercase; color:var(--ink-3)}
.stat-label svg{width:12px;height:12px}
.stat-value{margin-top:6px; font-size:54px; font-weight:600; letter-spacing:-.035em; line-height:1; white-space:nowrap}
.stat-value .unit{font-size:20px; font-weight:500; color:var(--ink-2); letter-spacing:0; margin-left:4px; vertical-align:top; position:relative; top:9px}
/* Chart section */
.section{margin-top:22px}
.section-head{display:flex; justify-content:space-between; align-items:baseline}
.section-title{margin:0; font-size:15px; font-weight:600}
.section-note{font-size:13px; color:var(--ink-3)}
.chart{position:relative; margin-top:6px; height:220px}
.chart svg{display:block; overflow:visible; outline:none; border-radius:8px}
.chart svg:focus-visible{box-shadow:0 0 0 2px var(--surface), 0 0 0 4px var(--series)}
.chart .empty{position:absolute; inset:0; display:grid; place-items:center; color:var(--ink-3); font-size:14px}
.tip{
position:absolute; z-index:2; pointer-events:none; opacity:0; transition:opacity .12s;
transform:translate(-50%,0); white-space:nowrap;
background:var(--tip-bg); color:var(--tip-ink); padding:8px 11px; border-radius:9px;
font-size:12px; line-height:1.3; box-shadow:0 6px 18px rgba(0,0,0,.18);
}
.tip.on{opacity:1}
.tip-value{font-size:15px; font-weight:650; letter-spacing:-.01em}
.tip-label{opacity:.72; margin-top:2px; font-variant-numeric:tabular-nums}
.tip-label::before{content:""; display:inline-block; width:10px; height:2px; background:var(--series); vertical-align:middle; margin-right:6px; border-radius:1px}
/* Hourly strip (table view) */
.strip{margin-top:20px; width:100%; border-collapse:separate; border-spacing:2px 0; table-layout:fixed; font-variant-numeric:tabular-nums}
.strip caption{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0)}
.strip th{padding:0 0 5px; font-size:11.5px; font-weight:500; color:var(--ink-3); text-align:center}
.strip td{
padding:8px 0; text-align:center; font-size:13.5px; font-weight:500; color:var(--ink);
border-radius:8px; cursor:default; transition:box-shadow .1s;
}
.strip td.na{color:var(--ink-3)}
.strip td.is-active{box-shadow:inset 0 0 0 1.5px var(--series)}
.foot{display:flex; justify-content:space-between; margin-top:18px; font-size:12.5px; color:var(--ink-3)}
/* Loading */
.loading{padding-top:24px}
.sk{background:var(--sk); border-radius:12px; animation:pulse 1.4s ease-in-out infinite}
.sk-hero{height:140px}
.sk-chart{height:220px; margin-top:22px; border-radius:16px}
.loading p{margin:18px 0 0; text-align:center; color:var(--ink-3); font-size:14px}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.55}}
@media (prefers-reduced-motion:reduce){.sk{animation:none}.tip{transition:none}}
/* Error */
.error{display:grid; place-items:center; text-align:center; min-height:440px; padding:20px 0}
.error-inner{max-width:560px}
.error svg{width:64px; height:64px; margin-bottom:8px}
.error h2{margin:0; font-size:22px; font-weight:600; letter-spacing:-.01em}
.error p{margin:10px 0 0; color:var(--ink-2); font-size:15px; line-height:1.5; overflow-wrap:anywhere}
.error .hint{font-size:13px; color:var(--ink-3)}
.btn{
margin-top:18px; padding:10px 18px; border-radius:999px; border:1px solid var(--border);
background:var(--ink); color:var(--surface); font:inherit; font-size:14px; font-weight:600; cursor:pointer;
}
.btn:hover{opacity:.9}
.btn:focus-visible{outline:2px solid var(--series); outline-offset:3px}
</style>
</head>
<body data-sky="cloudy">
<main class="card">
<header class="head">
<div>
<h1 class="place" id="place">Berlin</h1>
<p class="date" id="dateLong"></p>
<div class="meta">
<span id="dateIso"></span><span class="dot"></span>
<span id="coords"></span><span class="dot"></span>
<span>All times UTC</span>
</div>
</div>
<div class="chips">
<span class="chip accent" id="chipRel"></span>
<span class="chip" id="chipSrc"></span>
</div>
</header>
<div class="body" aria-live="polite">
<div id="loading" class="loading">
<div class="sk sk-hero"></div>
<div class="sk sk-chart"></div>
<p>Loading weather data…</p>
</div>
<div id="error" class="error" hidden role="alert">
<div class="error-inner">
<svg viewBox="0 0 64 64" aria-hidden="true">
<g transform="translate(3,6)"><path d="M45 25h-3.15A20 20 0 1 0 22.5 50h22.5a12.5 12.5 0 0 0 0-25z" style="fill:var(--ic-cloud)"/></g>
<line x1="14" y1="54" x2="50" y2="12" style="stroke:var(--ink-2);stroke-width:3.5;stroke-linecap:round"/>
</svg>
<h2>Weather data couldn't be loaded</h2>
<p id="errorDetail"></p>
<p class="hint" id="errorHint"></p>
<button class="btn" id="retry" type="button">Try again</button>
</div>
</div>
<div id="content" hidden>
<section class="hero">
<div class="cond">
<div class="icon" id="icon" aria-hidden="true"></div>
<div>
<h2 class="cond-name" id="condName"></h2>
<p class="cond-sub" id="condSub"></p>
</div>
</div>
<div class="stats">
<div class="stat">
<div class="stat-label"><svg viewBox="0 0 12 12" aria-hidden="true"><path d="M6 10V2M2.5 5.5 6 2l3.5 3.5" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>High</div>
<div class="stat-value"><span id="tmax">—</span><span class="unit">°C</span></div>
</div>
<div class="stat">
<div class="stat-label"><svg viewBox="0 0 12 12" aria-hidden="true"><path d="M6 2v8M2.5 6.5 6 10l3.5-3.5" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round"/></svg>Low</div>
<div class="stat-value"><span id="tmin">—</span><span class="unit">°C</span></div>
</div>
</div>
</section>
<section class="section">
<div class="section-head">
<h3 class="section-title">Hourly temperature</h3>
<span class="section-note">°C · hover or use arrow keys for exact values</span>
</div>
<div class="chart" id="chart">
<div class="tip" id="tip"><div class="tip-value" id="tipValue"></div><div class="tip-label" id="tipLabel"></div></div>
</div>
<table class="strip" id="strip">
<caption>Hourly temperature in degrees Celsius, UTC</caption>
<thead><tr id="stripHours"></tr></thead>
<tbody><tr id="stripTemps"></tr></tbody>
</table>
</section>
<footer class="foot">
<span id="footSrc"></span>
<span id="footNote"></span>
</footer>
</div>
</div>
</main>
<noscript><p style="text-align:center;font-family:system-ui,sans-serif">This weather card needs JavaScript to load its data.</p></noscript>
<script>
(function () {
'use strict';
var $ = function (id) { return document.getElementById(id); };
var SVG_NS = 'http://www.w3.org/2000/svg';
var DAYS = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
var MONTHS = ['January','February','March','April','May','June','July','August','September','October','November','December'];
/* ---------- Parameters ---------- */
var params = new URLSearchParams(location.search);
function toNum(v, def, min, max) {
if (v == null || String(v).trim() === '') return def;
var n = Number(v);
return (Number.isFinite(n) && n >= min && n <= max) ? n : def;
}
function validDate(s) {
if (!s || !/^\d{4}-\d{2}-\d{2}$/.test(s)) return null;
var d = new Date(s + 'T00:00:00Z');
return (!isNaN(d.getTime()) && d.toISOString().slice(0, 10) === s) ? s : null;
}
var lat = toNum(params.get('lat'), 52.52, -90, 90);
var lon = toNum(params.get('lon'), 13.405, -180, 180);
var nameParam = (params.get('name') || '').trim();
var name = nameParam ? nameParam.slice(0, 120) : 'Berlin';
var todayISO = new Date().toISOString().slice(0, 10);
var date = validDate(params.get('date')) || todayISO;
var isPast = date < todayISO;
var endpoint = isPast ? '/api/om/archive' : '/api/om/forecast';
var dayDiff = Math.round((Date.parse(date + 'T00:00:00Z') - Date.parse(todayISO + 'T00:00:00Z')) / 86400000);
/* ---------- Formatting ---------- */
function pad2(n) { return (n < 10 ? '0' : '') + n; }
function fmtLongDate(iso) {
var d = new Date(iso + 'T00:00:00Z');
return DAYS[d.getUTCDay()] + ', ' + d.getUTCDate() + ' ' + MONTHS[d.getUTCMonth()] + ' ' + d.getUTCFullYear();
}
function fmtCoords(la, lo) {
return Math.abs(la).toFixed(2) + '° ' + (la >= 0 ? 'N' : 'S') + ', ' + Math.abs(lo).toFixed(2) + '° ' + (lo >= 0 ? 'E' : 'W');
}
function fmtTemp(v) {
if (v == null || !Number.isFinite(v)) return '—';
var r = Math.round(v * 10) / 10;
if (r === 0) r = 0;
return r.toFixed(1);
}
function relLabel() {
if (dayDiff === 0) return 'Today';
if (dayDiff === 1) return 'Tomorrow';
if (dayDiff === -1) return 'Yesterday';
if (dayDiff > 1) return 'In ' + dayDiff + ' days';
return Math.abs(dayDiff) + ' days ago';
}
/* ---------- Weather codes ---------- */
var WMO = {
0: ['Clear sky', 'clear', 'sun'],
1: ['Mainly clear', 'clear', 'mainlyClear'],
2: ['Partly cloudy', 'cloudy', 'partly'],
3: ['Overcast', 'overcast', 'overcast'],
45: ['Fog', 'fog', 'fog'],
48: ['Depositing rime fog', 'fog', 'fog'],
51: ['Light drizzle', 'rain', 'drizzle'],
53: ['Moderate drizzle', 'rain', 'drizzle'],
55: ['Dense drizzle', 'rain', 'drizzle'],
56: ['Light freezing drizzle', 'rain', 'drizzle'],
57: ['Dense freezing drizzle', 'rain', 'drizzle'],
61: ['Slight rain', 'rain', 'rain'],
63: ['Moderate rain', 'rain', 'rain'],
65: ['Heavy rain', 'rain', 'rain'],
66: ['Light freezing rain', 'rain', 'rain'],
67: ['Heavy freezing rain', 'rain', 'rain'],
71: ['Slight snowfall', 'snow', 'snow'],
73: ['Moderate snowfall', 'snow', 'snow'],
75: ['Heavy snowfall', 'snow', 'snow'],
77: ['Snow grains', 'snow', 'snow'],
80: ['Slight rain showers', 'rain', 'rain'],
81: ['Moderate rain showers', 'rain', 'rain'],
82: ['Violent rain showers', 'rain', 'rain'],
85: ['Slight snow showers', 'snow', 'snow'],
86: ['Heavy snow showers', 'snow', 'snow'],
95: ['Thunderstorm', 'storm', 'storm'],
96: ['Thunderstorm with slight hail', 'storm', 'storm'],
99: ['Thunderstorm with heavy hail', 'storm', 'storm']
};
/* ---------- Icons (static markup, never user data) ---------- */
var CLOUD = 'M45 25h-3.15A20 20 0 1 0 22.5 50h22.5a12.5 12.5 0 0 0 0-25z';
function cloud(tx, ty, s, fillVar, ring) {
var style = 'fill:var(' + fillVar + ')' + (ring ? ';stroke:var(--surface);stroke-width:5;stroke-linejoin:round;paint-order:stroke' : '');
return '<g transform="translate(' + tx + ',' + ty + ') scale(' + s + ')"><path d="' + CLOUD + '" style="' + style + '"/></g>';
}
function sun(cx, cy, r, ray) {
var out = '<circle cx="' + cx + '" cy="' + cy + '" r="' + r + '" style="fill:var(--ic-sun)"/>' +
'<g style="stroke:var(--ic-sun);stroke-width:3.2;stroke-linecap:round">';
for (var k = 0; k < 8; k++) {
var a = k * Math.PI / 4, r1 = r + 4.5, r2 = r + 4.5 + ray;
out += '<line x1="' + (cx + Math.cos(a) * r1).toFixed(1) + '" y1="' + (cy + Math.sin(a) * r1).toFixed(1) +
'" x2="' + (cx + Math.cos(a) * r2).toFixed(1) + '" y2="' + (cy + Math.sin(a) * r2).toFixed(1) + '"/>';
}
return out + '</g>';
}
function precip(kind) {
var xs = [22, 32, 42], out = '';
if (kind === 'rain') {
out += '<g style="stroke:var(--ic-rain);stroke-width:3.2;stroke-linecap:round">';
xs.forEach(function (x, i) { var y = 45 + (i === 1 ? 4 : 0); out += '<line x1="' + (x + 2) + '" y1="' + y + '" x2="' + (x - 1.5) + '" y2="' + (y + 11) + '"/>'; });
return out + '</g>';
}
if (kind === 'drizzle') {
out += '<g style="stroke:var(--ic-rain);stroke-width:3.2;stroke-linecap:round">';
xs.forEach(function (x, i) { var y = 46 + (i === 1 ? 5 : 0); out += '<line x1="' + (x + 1) + '" y1="' + y + '" x2="' + (x - 0.5) + '" y2="' + (y + 5) + '"/>'; });
return out + '</g>';
}
if (kind === 'snow') {
out += '<g style="stroke:var(--ic-snow);stroke-width:2.4;stroke-linecap:round">';
xs.forEach(function (x, i) {
var y = 50 + (i === 1 ? 5 : 0);
for (var k = 0; k < 3; k++) {
var a = k * Math.PI / 3;
out += '<line x1="' + (x - Math.cos(a) * 4).toFixed(1) + '" y1="' + (y - Math.sin(a) * 4).toFixed(1) +
'" x2="' + (x + Math.cos(a) * 4).toFixed(1) + '" y2="' + (y + Math.sin(a) * 4).toFixed(1) + '"/>';
}
});
return out + '</g>';
}
if (kind === 'fog') {
return '<g style="stroke:var(--ic-fog);stroke-width:3.4;stroke-linecap:round">' +
'<line x1="14" y1="47" x2="44" y2="47"/><line x1="22" y1="54" x2="50" y2="54"/><line x1="17" y1="61" x2="38" y2="61"/></g>';
}
return '';
}
var ICONS = {
sun: function () { return sun(32, 32, 11, 5); },
mainlyClear: function () { return sun(28, 27, 10.5, 4.5) + cloud(22, 26, 0.55, '--ic-cloud', true); },
partly: function () { return sun(23, 23, 9, 4) + cloud(12.2, 16.8, 0.72, '--ic-cloud', true); },
overcast: function () { return cloud(20.5, 1.8, 0.62, '--ic-cloud-2', false) + cloud(2.05, 12.2, 0.78, '--ic-cloud', true); },
fog: function () { return cloud(8.6, -4, 0.78, '--ic-cloud', false) + precip('fog'); },
drizzle: function () { return cloud(8.6, -1.8, 0.78, '--ic-cloud', false) + precip('drizzle'); },
rain: function () { return cloud(8.6, -1.8, 0.78, '--ic-cloud-2', false) + precip('rain'); },
snow: function () { return cloud(8.6, -1.8, 0.78, '--ic-cloud', false) + precip('snow'); },
storm: function () { return cloud(8.6, -1.8, 0.78, '--ic-cloud-2', false) + '<path d="M36 40 25 55h8l-3 9 13-15h-8l4-9z" style="fill:var(--ic-bolt)"/>'; },
unknown: function () { return cloud(3, 6, 0.9, '--ic-cloud', false); }
};
function iconSvg(key) {
return '<svg viewBox="0 0 64 64" aria-hidden="true">' + (ICONS[key] || ICONS.unknown)() + '</svg>';
}
/* ---------- Header (known before any fetch) ---------- */
$('place').textContent = name;
$('dateLong').textContent = fmtLongDate(date);
$('dateIso').textContent = date;
$('coords').textContent = fmtCoords(lat, lon);
$('chipRel').textContent = relLabel();
$('chipSrc').textContent = isPast ? 'Historical · archive' : 'Forecast';
document.title = name + ' · ' + date + ' · Weather';
/* ---------- State handling ---------- */
var model = null;
function show(which) {
['loading', 'error', 'content'].forEach(function (id) { $(id).hidden = id !== which; });
}
function showError(message) {
$('errorDetail').textContent = message;
$('errorHint').textContent = 'Requested from ' + endpoint + ' for ' + date + ' at ' + fmtCoords(lat, lon) + '.';
document.body.dataset.sky = 'overcast';
show('error');
}
/* ---------- Fetch ---------- */
function buildUrl() {
var pairs = [
['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 endpoint + '?' + pairs.map(function (p) {
return p[0] + '=' + encodeURIComponent(p[1]).replace(/%2C/g, ',');
}).join('&');
}
function load() {
show('loading');
var ctrl = new AbortController();
var timer = setTimeout(function () { ctrl.abort(); }, 15000);
fetch(buildUrl(), { signal: ctrl.signal, headers: { accept: 'application/json' } })
.catch(function (err) {
if (err && err.name === 'AbortError') throw new Error('The request timed out after 15 seconds.');
throw new Error('The weather service could not be reached (network error).');
})
.then(function (res) {
if (!res.ok) {
return res.text().then(function (txt) {
var reason = '';
try { var j = JSON.parse(txt); if (j && j.reason) reason = String(j.reason); } catch (e) { /* not JSON */ }
throw new Error('The weather service responded with HTTP ' + res.status + (reason ? ': ' + reason : '') + '.');
});
}
return res.json().catch(function () { throw new Error('The weather service returned a response that is not valid JSON.'); });
})
.then(function (data) {
if (!data || typeof data !== 'object') throw new Error('The weather service returned an empty response.');
if (data.error) throw new Error(data.reason ? String(data.reason) : 'The weather service reported an error.');
model = normalize(data);
render(model);
})
.catch(function (err) {
showError((err && err.message) ? err.message : 'An unknown error occurred.');
})
.then(function () { clearTimeout(timer); });
}
function normalize(data) {
var daily = data.daily || {};
var hourly = data.hourly || {};
var di = Array.isArray(daily.time) ? daily.time.findIndex(function (t) { return typeof t === 'string' && t.slice(0, 10) === date; }) : -1;
if (di < 0) di = 0;
function pick(arr) { return (Array.isArray(arr) && Number.isFinite(arr[di])) ? arr[di] : null; }
var tmax = pick(daily.temperature_2m_max);
var tmin = pick(daily.temperature_2m_min);
var code = pick(daily.weather_code);
var hours = [];
if (Array.isArray(hourly.time) && Array.isArray(hourly.temperature_2m)) {
hourly.time.forEach(function (t, i) {
if (typeof t !== 'string' || t.slice(0, 10) !== date) return;
var m = /T(\d{2}):(\d{2})/.exec(t);
var v = hourly.temperature_2m[i];
hours.push({
label: m ? m[1] + ':' + m[2] : pad2(hours.length) + ':00',
short: m ? m[1] : pad2(hours.length),
v: Number.isFinite(v) ? v : null
});
});
if (hours.length === 0 && hourly.time.length > 0) {
hourly.time.slice(0, 24).forEach(function (t, i) {
var v = hourly.temperature_2m[i];
hours.push({ label: pad2(i) + ':00', short: pad2(i), v: Number.isFinite(v) ? v : null });
});
}
}
var hourVals = hours.map(function (h) { return h.v; }).filter(function (v) { return v != null; });
var hasHourly = hourVals.length > 0;
if (tmax == null && tmin == null && code == null && !hasHourly) {
throw new Error(isPast
? 'The archive returned no values for ' + date + '. Historical data usually becomes available a few days after the fact.'
: 'The service returned no values for ' + date + '.');
}
var derived = false;
if ((tmax == null || tmin == null) && hasHourly) {
if (tmax == null) tmax = Math.max.apply(null, hourVals);
if (tmin == null) tmin = Math.min.apply(null, hourVals);
derived = true;
}
return { tmax: tmax, tmin: tmin, code: code, hours: hours, hasHourly: hasHourly, derived: derived };
}
/* ---------- Render ---------- */
function render(m) {
var info = (m.code != null && WMO[m.code]) ? WMO[m.code] : null;
document.body.dataset.sky = info ? info[1] : 'cloudy';
$('icon').innerHTML = iconSvg(info ? info[2] : 'unknown');
$('condName').textContent = info ? info[0] : (m.code == null ? 'Conditions unavailable' : 'Unknown conditions');
$('condSub').textContent = m.code == null ? 'No weather code reported for this date' : 'WMO weather code ' + m.code;
$('tmax').textContent = fmtTemp(m.tmax);
$('tmin').textContent = fmtTemp(m.tmin);
$('footSrc').textContent = 'Source: Open-Meteo ' + (isPast ? 'historical archive' : 'forecast') + ' · ' + fmtCoords(lat, lon);
$('footNote').textContent = m.derived
? 'High and low derived from hourly values'
: (m.hasHourly ? m.hours.length + ' hourly readings' : 'Hourly data unavailable');
show('content'); /* visible first so the chart can measure its width */
buildStrip(m.hours);
buildChart(m.hours);
}
/* ---------- Hourly strip (table view) ---------- */
var stripCells = [];
function buildStrip(hours) {
var hRow = $('stripHours'), tRow = $('stripTemps');
hRow.textContent = ''; tRow.textContent = '';
stripCells = [];
var vals = hours.map(function (h) { return h.v; }).filter(function (v) { return v != null; });
var lo = vals.length ? Math.min.apply(null, vals) : 0;
var hi = vals.length ? Math.max.apply(null, vals) : 1;
var span = (hi - lo) || 1;
var dark = !!(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches);
hours.forEach(function (h, i) {
var th = document.createElement('th');
th.setAttribute('scope', 'col');
th.textContent = h.short;
hRow.appendChild(th);
var td = document.createElement('td');
td.textContent = h.v == null ? '—' : fmtTemp(h.v) + '°';
if (h.v == null) {
td.className = 'na';
} else {
var a = (dark ? 0.06 : 0.04) + (dark ? 0.30 : 0.20) * ((h.v - lo) / span);
td.style.background = 'rgba(var(--series-rgb),' + a.toFixed(3) + ')';
}
td.addEventListener('pointerenter', function () { setActive(i); });
tRow.appendChild(td);
stripCells.push(td);
});
$('strip').hidden = hours.length === 0;
}
/* ---------- Chart ---------- */
var chart = null, svgFocused = false, activeIdx = -1;
function el(tag, attrs, parent) {
var e = document.createElementNS(SVG_NS, tag);
var style = attrs.style || '';
for (var k in attrs) {
if (!Object.prototype.hasOwnProperty.call(attrs, k) || k === 'style') continue;
var v = attrs[k];
if (k === 'font-variant-numeric' || (typeof v === 'string' && v.indexOf('var(') >= 0)) style += ';' + k + ':' + v;
else e.setAttribute(k, v);
}
if (style) e.setAttribute('style', style);
if (parent) parent.appendChild(e);
return e;
}
function niceScale(lo, hi, target) {
var span = (hi - lo) || 1;
var rough = span / target;
var p = Math.pow(10, Math.floor(Math.log10(rough)));
var steps = [1, 2, 5, 10], step = 10 * p;
for (var i = 0; i < steps.length; i++) { if (span / (steps[i] * p) <= target + 0.5) { step = steps[i] * p; break; } }
var min = Math.floor(lo / step) * step, max = Math.ceil(hi / step) * step;
var ticks = [];
for (var v = min; v <= max + step * 1e-6; v += step) ticks.push(Math.round(v * 1000) / 1000);
return { min: min, max: max, ticks: ticks };
}
function tickLabel(t) { return (Number.isInteger(t) ? t : t.toFixed(1)) + '°'; }
function buildChart(hours) {
var wrap = $('chart');
var old = wrap.querySelector('svg'); if (old) old.remove();
var oldEmpty = wrap.querySelector('.empty'); if (oldEmpty) oldEmpty.remove();
chart = null; activeIdx = -1;
var n = hours.length;
var valid = hours.map(function (h, i) { return { v: h.v, i: i }; }).filter(function (d) { return d.v != null; });
if (n === 0 || valid.length === 0) {
var em = document.createElement('div');
em.className = 'empty';
em.textContent = 'No hourly temperatures were returned for this date.';
wrap.appendChild(em);
return;
}
var W = Math.max(480, Math.round(wrap.clientWidth || 1080)), H = 220;
var padL = 46, padR = 22, padT = 30, padB = 30;
var innerW = W - padL - padR, innerH = H - padT - padB;
var vals = valid.map(function (d) { return d.v; });
var vmin = Math.min.apply(null, vals), vmax = Math.max.apply(null, vals);
var pad = Math.max(1, (vmax - vmin) * 0.22);
var sc = niceScale(vmin - pad, vmax + pad, 4);
var x = function (i) { return n === 1 ? padL + innerW / 2 : padL + i * innerW / (n - 1); };
var y = function (v) { return padT + (sc.max - v) / (sc.max - sc.min) * innerH; };
var yBase = padT + innerH;
var svg = el('svg', {
width: W, height: H, viewBox: '0 0 ' + W + ' ' + H, role: 'img', tabindex: '0',
'aria-label': 'Hourly temperature line chart, ' + n + ' readings from ' + fmtTemp(vmin) + ' to ' + fmtTemp(vmax) + ' degrees Celsius'
});
var defs = el('defs', {}, svg);
var grad = el('linearGradient', { id: 'areaFill', x1: 0, y1: 0, x2: 0, y2: 1 }, defs);
el('stop', { offset: '0%', 'stop-color': 'var(--series)', 'stop-opacity': 0.16 }, grad);
el('stop', { offset: '100%', 'stop-color': 'var(--series)', 'stop-opacity': 0 }, grad);
/* Gridlines + y ticks */
sc.ticks.forEach(function (t, k) {
var yy = y(t);
el('line', { x1: padL, x2: W - padR, y1: yy, y2: yy, stroke: k === 0 ? 'var(--axis)' : 'var(--grid)', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }, svg);
var tx = el('text', { x: padL - 10, y: yy, 'text-anchor': 'end', 'dominant-baseline': 'middle', fill: 'var(--ink-3)', 'font-size': 11.5, 'font-variant-numeric': 'tabular-nums' }, svg);
tx.textContent = tickLabel(t);
});
/* x ticks every 3 hours */
hours.forEach(function (h, i) {
if (i % 3 !== 0) return;
var tx = el('text', { x: x(i), y: H - padB + 19, 'text-anchor': 'middle', fill: 'var(--ink-3)', 'font-size': 11.5, 'font-variant-numeric': 'tabular-nums' }, svg);
tx.textContent = h.short;
});
/* Area wash + line, broken at gaps */
var segs = [], cur = [];
hours.forEach(function (h, i) { if (h.v == null) { if (cur.length) segs.push(cur); cur = []; } else cur.push(i); });
if (cur.length) segs.push(cur);
segs.forEach(function (seg) {
if (seg.length < 2) return;
var line = seg.map(function (i, k) { return (k ? 'L' : 'M') + x(i).toFixed(1) + ' ' + y(hours[i].v).toFixed(1); }).join('');
var area = line + 'L' + x(seg[seg.length - 1]).toFixed(1) + ' ' + yBase + 'L' + x(seg[0]).toFixed(1) + ' ' + yBase + 'Z';
el('path', { d: area, fill: 'url(#areaFill)' }, svg);
el('path', { d: line, fill: 'none', stroke: 'var(--series)', 'stroke-width': 2, 'stroke-linejoin': 'round', 'stroke-linecap': 'round' }, svg);
});
segs.forEach(function (seg) {
if (seg.length !== 1) return;
el('circle', { cx: x(seg[0]), cy: y(hours[seg[0]].v), r: 4, fill: 'var(--series)', stroke: 'var(--surface)', 'stroke-width': 2 }, svg);
});
/* Direct labels on the two extremes only */
var iMax = valid.reduce(function (a, d) { return d.v > hours[a].v ? d.i : a; }, valid[0].i);
var iMin = valid.reduce(function (a, d) { return d.v < hours[a].v ? d.i : a; }, valid[0].i);
function mark(i, above) {
var px = x(i), py = y(hours[i].v);
el('circle', { cx: px, cy: py, r: 4.5, fill: 'var(--series)', stroke: 'var(--surface)', 'stroke-width': 2 }, svg);
var anchor = i === 0 ? 'start' : (i === n - 1 ? 'end' : 'middle');
var t = el('text', {
x: px, y: above ? py - 12 : py + 20, 'text-anchor': anchor, fill: 'var(--ink)', 'font-size': 12, 'font-weight': 600,
stroke: 'var(--surface)', 'stroke-width': 3, 'paint-order': 'stroke', 'stroke-linejoin': 'round'
}, svg);
t.textContent = fmtTemp(hours[i].v) + '°';
}
mark(iMax, true);
if (iMin !== iMax) mark(iMin, false);
/* Crosshair layer */
var cross = el('g', { opacity: 0, 'pointer-events': 'none' }, svg);
var cLine = el('line', { y1: padT - 6, y2: yBase, stroke: 'var(--axis)', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }, cross);
var cDot = el('circle', { r: 5.5, fill: 'var(--series)', stroke: 'var(--surface)', 'stroke-width': 2 }, cross);
/* Hit area covers the whole plot, wider than any mark */
var hit = el('rect', { x: padL - 14, y: 0, width: innerW + 28, height: H, fill: 'transparent', style: 'cursor:crosshair' }, svg);
var stepX = n === 1 ? innerW : innerW / (n - 1);
hit.addEventListener('pointermove', function (ev) {
var r = svg.getBoundingClientRect();
var i = Math.round((ev.clientX - r.left - padL) / stepX);
setActive(Math.max(0, Math.min(n - 1, i)));
});
hit.addEventListener('pointerleave', function () { if (!svgFocused) clearActive(); });
svg.addEventListener('focus', function () { svgFocused = true; setActive(activeIdx >= 0 ? activeIdx : iMax); });
svg.addEventListener('blur', function () { svgFocused = false; clearActive(); });
svg.addEventListener('keydown', function (ev) {
var i = activeIdx >= 0 ? activeIdx : iMax;
if (ev.key === 'ArrowLeft') i -= 1;
else if (ev.key === 'ArrowRight') i += 1;
else if (ev.key === 'Home') i = 0;
else if (ev.key === 'End') i = n - 1;
else if (ev.key === 'Escape') { clearActive(); return; }
else return;
ev.preventDefault();
setActive(Math.max(0, Math.min(n - 1, i)));
});
wrap.insertBefore(svg, wrap.firstChild);
chart = { hours: hours, x: x, y: y, W: W, cross: cross, cLine: cLine, cDot: cDot, padT: padT };
}
function setActive(i) {
if (!chart) return;
var h = chart.hours[i];
activeIdx = i;
var px = chart.x(i);
chart.cross.setAttribute('opacity', 1);
chart.cLine.setAttribute('x1', px); chart.cLine.setAttribute('x2', px);
if (h.v != null) {
chart.cDot.setAttribute('cx', px); chart.cDot.setAttribute('cy', chart.y(h.v)); chart.cDot.setAttribute('opacity', 1);
} else {
chart.cDot.setAttribute('opacity', 0);
}
var tip = $('tip');
$('tipValue').textContent = h.v == null ? 'No data' : fmtTemp(h.v) + ' °C';
$('tipLabel').textContent = h.label + ' UTC';
var py = h.v == null ? chart.padT + 20 : chart.y(h.v);
var tw = tip.offsetWidth || 90;
var left = Math.max(tw / 2 + 2, Math.min(chart.W - tw / 2 - 2, px));
var top = py - 62;
if (top < 0) top = py + 16;
tip.style.left = left + 'px'; tip.style.top = top + 'px';
tip.classList.add('on');
stripCells.forEach(function (td, k) { td.classList.toggle('is-active', k === i); });
}
function clearActive() {
if (!chart) return;
chart.cross.setAttribute('opacity', 0);
$('tip').classList.remove('on');
stripCells.forEach(function (td) { td.classList.remove('is-active'); });
}
/* ---------- Wiring ---------- */
$('retry').addEventListener('click', load);
$('strip').addEventListener('pointerleave', function () { if (!svgFocused) clearActive(); });
var resizeRaf = 0;
window.addEventListener('resize', function () {
if (!model || !model.hours.length) return;
cancelAnimationFrame(resizeRaf);
resizeRaf = requestAnimationFrame(function () { buildChart(model.hours); });
});
if (window.matchMedia) {
var mq = window.matchMedia('(prefers-color-scheme: dark)');
if (mq.addEventListener) mq.addEventListener('change', function () { if (model) buildStrip(model.hours); });
}
load();
})();
</script>
</body>
</html>L1 —— 廉价的确定性描述量
| bytes 总计 | 36,175 | html / css / js | 3,644 / 8,437 / 24,094 |
|---|---|---|---|
| dom 节点 | 78 | dom 深度 | 10 |
| css 规则 | 86 | 含 js | 是 |
| brightness | 237.1 | contrast | 23.1 |
| colorfulness | 10.7 | 留白 | 94.0% |
该 slot 的 telemetry
| prompt tokens | 426 | completion tokens | 85,339 |
|---|---|---|---|
| total tokens | 85,765 | wall | 892.8 s |
| cost | — | request id | — |
config.json583 B
{
"N": 2,
"auth": {
"credential_ref": "WCB_NONE",
"method": "oauth-login"
},
"billing": "plan",
"config_id": "claude-fable-5-1-eff-xhigh--cli--claude-code--dev",
"effort": "xhigh",
"family": "claude",
"m": {
"min": 2,
"q": 2
},
"model_id": "claude-fable-5-1",
"protocol": "cli",
"served_model": "claude-fable-5-1",
"telemetry": {
"completion_tokens": 191920,
"cost_usd": null,
"prompt_tokens": 970,
"total_tokens": 192890,
"wall_ms": 2042919
},
"transport": "claude-code-cli-headless",
"vendor_sanction_ref": null
}send-log2.5 KB
{
"N": 2,
"batch_id": "2026-09-02--cc-fable51-s1",
"config_id": "claude-fable-5-1-eff-xhigh--cli--claude-code--dev",
"positions": [
{
"attempts": [
{
"attempt_index": 0,
"backoff_ms": null,
"charged": true,
"ended_at": "2026-09-02T01:40:03.617656+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-09-02T01:25:10.865527+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-02T01:43:06.263239+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-09-02T01:40:08.034309+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-02T01:46:36.404784+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-09-02T01:43:09.605986+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-02T01:59:24.443646+00:00",
"http_status": null,
"outcome": "valid",
"reached_model": true,
"reason": "ok",
"request_id": null,
"started_at": "2026-09-02T01:46:39.302199+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
}
}
}