deepseek-v4-flash-vision-exp @ max · dsh

dshmax
config
deepseek-v4-flash-vision-exp-eff-max--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-vision-exp
采集于
2026年7月18日 11:54 · N=2
variant
live
slot 1 · P-q · sandboxed iframe
deepseek-v4-flash-vision-exp @max · dsh P-q slot 1 截图

截图是 similarity 通道测量时的原始像素。运行 live 会在 sandboxed iframe 中重新执行原始输出;渲染结果取决于你的浏览器和字体,不保证与测量像素一致。

similarity 邻居本 session 没有 similarity 数据 —— 这个 batch 没有计算 pairs。

Fidelity —— 卡片展示的数据对不对?

  • namematch
  • conditionmatch
  • datematch
  • max tempmatch展示值:25
  • min tempmatch展示值:16
  • 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: dark; }
  * { margin: 0; padding: 0; box-sizing: border-box; }
  html, body { height: 100%; }

  body {
    min-width: 1180px;
    font-family: "SF Pro Display", "SF Pro Text", -apple-system, BlinkMacSystemFont,
                 "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    background: #06080f;
    color: #e2e8f0;
    display: grid;
    place-items: center;
    padding: 48px 24px;
    overflow-x: hidden;
    position: relative;
  }

  /* ------- ambient backdrop ------- */
  body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -2;
    background:
      radial-gradient(1100px 760px at 14% -12%, rgba(37, 78, 141, .55), transparent 62%),
      radial-gradient(950px 720px at 90% 114%, rgba(88, 52, 148, .48), transparent 60%),
      radial-gradient(1500px 950px at 50% 46%, rgba(13, 25, 48, .95), rgba(5, 8, 16, 1) 78%);
  }
  .glow {
    position: fixed;
    border-radius: 50%;
    filter: blur(110px);
    z-index: -1;
    pointer-events: none;
  }
  .glow.g1 { width: 560px; height: 560px; left: -150px; top: -170px; background: rgba(56, 189, 248, .17); animation: drift 24s ease-in-out infinite alternate; }
  .glow.g2 { width: 520px; height: 520px; right: -130px; bottom: -150px; background: rgba(167, 139, 250, .15); animation: drift 30s ease-in-out infinite alternate-reverse; }
  @keyframes drift { from { transform: translate(0, 0); } to { transform: translate(70px, 46px); } }

  /* ------- card ------- */
  .card {
    --accent: #38bdf8;
    position: relative;
    width: min(760px, calc(100vw - 120px));
    background: linear-gradient(168deg, rgba(17, 26, 45, .93), rgba(9, 14, 28, .96) 58%);
    border: 1px solid rgba(148, 163, 184, .15);
    border-radius: 32px;
    box-shadow:
      0 60px 120px -40px rgba(0, 0, 0, .8),
      inset 0 1px 0 rgba(255, 255, 255, .05);
    padding: 40px 44px 30px;
    overflow: hidden;
    animation: rise .7s cubic-bezier(.16, 1, .3, 1) both;
    transition: box-shadow .45s ease;
  }
  .card:hover {
    box-shadow:
      0 70px 140px -40px rgba(0, 0, 0, .85),
      0 0 90px -34px color-mix(in srgb, var(--accent) 30%, transparent),
      inset 0 1px 0 rgba(255, 255, 255, .05);
  }
  @keyframes rise { from { opacity: 0; transform: translateY(26px) scale(.985); } to { opacity: 1; transform: none; } }

  .edge {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 2px;
    background: linear-gradient(90deg, var(--accent), rgba(255, 255, 255, 0) 68%);
    opacity: .9;
  }
  .watermark {
    position: absolute;
    top: 18px; right: 22px;
    width: 230px; height: 230px;
    display: grid; place-items: center;
    color: var(--accent);
    opacity: .055;
    pointer-events: none;
    z-index: 0;
  }
  .watermark svg { width: 100%; height: 100%; }

  #content { position: relative; z-index: 1; }
  .ic { display: inline-flex; }
  .ic svg { width: 100%; height: 100%; }

  .fade { animation: fadeIn .5s ease both; }
  @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }

  /* ------- header ------- */
  .head { display: flex; justify-content: space-between; align-items: flex-start; gap: 24px; }
  .loc { font-size: 34px; font-weight: 650; letter-spacing: -.022em; line-height: 1.15; }
  .date { margin-top: 7px; font-size: 14px; color: #94a3b8; letter-spacing: .01em; }
  .cond-chip {
    display: inline-flex; align-items: center; gap: 10px;
    padding: 9px 16px 9px 12px;
    border-radius: 999px;
    background: rgba(255, 255, 255, .05);
    border: 1px solid rgba(255, 255, 255, .09);
    flex: none;
    margin-top: 2px;
  }
  .cond-chip .ic { width: 21px; height: 21px; color: var(--accent); }
  .cond-chip .lbl { font-size: 14px; font-weight: 560; color: #e2e8f0; white-space: nowrap; }

  /* ------- stats ------- */
  .stats { display: grid; grid-template-columns: 1fr 1fr 1.4fr; gap: 16px; margin-top: 30px; }
  .stat {
    border-radius: 22px;
    padding: 22px 24px;
    background: linear-gradient(180deg, rgba(255, 255, 255, .048), rgba(255, 255, 255, .015));
    border: 1px solid rgba(255, 255, 255, .07);
    display: flex; flex-direction: column; gap: 12px;
    min-width: 0;
  }
  .stat-cap {
    font-size: 11px; font-weight: 650;
    letter-spacing: .17em; text-transform: uppercase;
    color: #7c8aa0;
  }
  .stat-val {
    font-size: 46px; font-weight: 650;
    letter-spacing: -.03em; line-height: 1;
    font-variant-numeric: tabular-nums;
  }
  .stat-val.hi { color: var(--accent); text-shadow: 0 0 34px color-mix(in srgb, var(--accent) 45%, transparent); }
  .stat-val.lo { color: #cbd5e1; }
  .cond-row { display: flex; align-items: center; gap: 13px; }
  .cond-row .ic { width: 38px; height: 38px; color: var(--accent); flex: none; filter: drop-shadow(0 0 12px color-mix(in srgb, var(--accent) 45%, transparent)); }
  .cond-name { display: block; font-size: 16.5px; font-weight: 620; }
  .cond-sub { display: block; font-size: 12.5px; color: #8b98ad; margin-top: 3px; }

  /* ------- hourly chart ------- */
  .hourly { margin-top: 28px; }
  .sec-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 14px; }
  .sec-title { font-size: 12px; font-weight: 650; letter-spacing: .17em; text-transform: uppercase; color: #7c8aa0; }
  .sec-sub { font-size: 12px; color: #64748b; }

  .chart-wrap { position: relative; padding-top: 38px; }
  .chart {
    position: relative;
    display: flex;
    align-items: flex-end;
    gap: 3px;
    height: 152px;
  }
  .col {
    flex: 1 1 0;
    min-width: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 8px;
  }
  .bar {
    width: clamp(8px, 58%, 20px);
    border-radius: 7px 7px 5px 5px;
    background: rgba(56, 189, 248, .5);
    background: linear-gradient(
      to top,
      color-mix(in srgb, var(--accent) 80%, transparent),
      color-mix(in srgb, var(--accent) 24%, transparent)
    );
    transition: filter .16s ease;
    animation: barIn .65s cubic-bezier(.22, 1, .36, 1) both;
    animation-delay: calc(var(--i) * 20ms + 120ms);
    transform-origin: bottom;
  }
  .bar:hover { filter: brightness(1.3); }
  .bar.peak {
    background: #38bdf8;
    background: linear-gradient(to top, var(--accent), color-mix(in srgb, var(--accent) 55%, white) 130%);
    box-shadow: 0 0 22px color-mix(in srgb, var(--accent) 52%, transparent);
  }
  .bar.miss {
    background: rgba(255, 255, 255, .08) !important;
    height: 6px !important;
    border-radius: 99px;
    animation: none;
  }
  @keyframes barIn { from { transform: scaleY(0); opacity: .2; } to { transform: scaleY(1); opacity: 1; } }
  .tick {
    font-size: 10.5px;
    line-height: 1;
    color: #5c6b81;
    min-height: 11px;
    font-variant-numeric: tabular-nums;
    user-select: none;
  }

  .tip {
    position: absolute;
    top: 0; left: 60px;
    transform: translateX(-50%);
    padding: 7px 11px;
    border-radius: 11px;
    background: rgba(15, 23, 42, .96);
    border: 1px solid rgba(255, 255, 255, .11);
    box-shadow: 0 10px 26px rgba(0, 0, 0, .55);
    font-size: 12px;
    color: #94a3b8;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity .13s ease;
    z-index: 6;
  }
  .tip b { color: var(--accent); font-weight: 650; margin-left: 6px; font-variant-numeric: tabular-nums; }
  .tip.show { opacity: 1; }

  .now {
    position: absolute;
    top: 8px; bottom: 19px;
    width: 0;
    border-left: 1.5px dashed rgba(244, 114, 182, .45);
    pointer-events: none;
    z-index: 2;
  }
  .now::before {
    content: "";
    position: absolute;
    left: -3.5px; top: -5px;
    width: 5px; height: 5px;
    border-radius: 50%;
    background: #f472b6;
    box-shadow: 0 0 10px #f472b6;
  }
  .now-label {
    position: absolute;
    top: 7px; left: 0;
    transform: translateX(-50%);
    font-size: 9.5px; font-weight: 750;
    letter-spacing: .14em;
    color: #f9a8d4;
  }
  .no-hourly {
    width: 100%;
    padding: 52px 0 44px;
    text-align: center;
    color: #64748b;
    font-size: 13.5px;
  }

  /* ------- footer ------- */
  .foot {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-top: 26px;
    padding-top: 18px;
    border-top: 1px solid rgba(255, 255, 255, .06);
  }
  .src { font-size: 12px; color: #64748b; display: inline-flex; align-items: center; gap: 9px; font-variant-numeric: tabular-nums; }
  .src .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 8px color-mix(in srgb, var(--accent) 70%, transparent); }
  .btn-icon {
    width: 36px; height: 36px;
    border-radius: 12px;
    display: grid; place-items: center;
    background: rgba(255, 255, 255, .05);
    border: 1px solid rgba(255, 255, 255, .09);
    color: #b6c2d4;
    cursor: pointer;
    transition: background .18s, color .18s, border-color .18s;
  }
  .btn-icon:hover { background: rgba(255, 255, 255, .1); color: #fff; border-color: rgba(255, 255, 255, .16); }
  .btn-icon svg { width: 16px; height: 16px; }
  .btn-icon.spin svg { animation: spin .8s linear infinite; }
  @keyframes spin { to { transform: rotate(360deg); } }

  /* ------- skeleton ------- */
  .sk {
    border-radius: 8px;
    background: linear-gradient(100deg, rgba(255, 255, 255, .055) 40%, rgba(255, 255, 255, .12) 50%, rgba(255, 255, 255, .055) 60%);
    background-size: 200% 100%;
    animation: shimmer 1.6s linear infinite;
  }
  @keyframes shimmer { from { background-position: 130% 0; } to { background-position: -70% 0; } }
  .sk.bar-sk {
    flex: 1 1 0; min-width: 0;
    align-self: flex-end;
    border-radius: 7px 7px 5px 5px;
    background: rgba(255, 255, 255, .07);
    animation: pulseSk 1.5s ease-in-out infinite alternate;
  }
  @keyframes pulseSk { from { opacity: .5; } to { opacity: .95; } }

  /* ------- error ------- */
  .err {
    padding: 72px 0 46px;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
  }
  .err .ic { width: 54px; height: 54px; color: #fb7185; margin-bottom: 18px; filter: drop-shadow(0 0 22px rgba(251, 113, 133, .35)); }
  .err h2 { font-size: 23px; font-weight: 650; letter-spacing: -.01em; }
  .err p { margin-top: 10px; font-size: 14px; color: #94a3b8; max-width: 440px; line-height: 1.6; }
  .err p code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 12.5px; color: #cbd5e1; background: rgba(255, 255, 255, .06); padding: 1px 5px; border-radius: 5px; }
  .err p b { color: #cbd5e1; font-weight: 620; }
  .err .detail { margin-top: 14px; font-size: 12px; color: #64748b; }
  .btn-retry {
    margin-top: 24px;
    display: inline-flex; align-items: center; gap: 10px;
    padding: 11px 20px;
    border-radius: 12px;
    background: rgba(255, 255, 255, .06);
    border: 1px solid rgba(255, 255, 255, .13);
    color: #e2e8f0;
    font: inherit; font-size: 14px; font-weight: 620;
    cursor: pointer;
    transition: background .18s, transform .18s;
  }
  .btn-retry:hover { background: rgba(255, 255, 255, .11); transform: translateY(-1px); }
  .btn-retry svg { width: 15px; height: 15px; }

  @media (prefers-reduced-motion: reduce) {
    *, *::before, *::after { animation: none !important; transition: none !important; }
  }
</style>
</head>
<body>
  <div class="glow g1" aria-hidden="true"></div>
  <div class="glow g2" aria-hidden="true"></div>

  <main class="card" id="card" aria-live="polite">
    <div class="edge" aria-hidden="true"></div>
    <div class="watermark" id="wm" aria-hidden="true"></div>
    <div id="content"></div>
  </main>

  <noscript><p style="position:fixed;bottom:16px;left:0;right:0;text-align:center;color:#94a3b8;font-size:13px">Please enable JavaScript to load the weather.</p></noscript>

<script>
(function () {
  'use strict';

  var card = document.getElementById('card');
  var content = document.getElementById('content');
  var wm = document.getElementById('wm');
  var $ = function (sel, el) { return (el || document).querySelector(sel); };

  /* ---------------- parameters ---------------- */
  var params = new URLSearchParams(window.location.search);

  function numParam(key, fallback, lo, hi) {
    var v = parseFloat(params.get(key));
    return (Number.isFinite(v) && v >= lo && v <= hi) ? v : fallback;
  }
  var lat = numParam('lat', 52.52, -90, 90);
  var lon = numParam('lon', 13.405, -180, 180);
  var locationName = (params.get('name') || 'Berlin').trim().slice(0, 60) || 'Berlin';

  function todayUTC() { return new Date().toISOString().slice(0, 10); }

  var rawDate = (params.get('date') || '').trim();
  var isIso = false;
  if (/^\d{4}-\d{2}-\d{2}$/.test(rawDate)) {
    var probe = new Date(rawDate + 'T00:00:00Z');
    isIso = !Number.isNaN(probe.getTime()) && probe.toISOString().slice(0, 10) === rawDate;
  }
  var badDate = rawDate !== '' && !isIso;
  var date = isIso ? rawDate : todayUTC();

  document.title = 'Weather \u00b7 ' + locationName;

  /* ---------------- icons ---------------- */
  var STROKE = 'fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"';
  var I = {
    sun: '<svg viewBox="0 0 24 24" ' + STROKE + '><circle cx="12" cy="12" r="4.2"/><path d="M12 2v2M12 20v2M4.93 4.93l1.41 1.41M17.66 17.66l1.41 1.41M2 12h2M20 12h2M6.34 17.66l-1.41 1.41M19.07 4.93l-1.41 1.41"/></svg>',
    suncloud: '<svg viewBox="0 0 24 24" ' + STROKE + '><path d="M13 2v2"/><path d="m4.93 4.93 1.41 1.41"/><path d="M20 12h2"/><path d="m19.07 4.93-1.41 1.41"/><path d="M15.95 12.65a4 4 0 0 0-5.93-4.13"/><path d="M13 22H7a5 5 0 1 1 4.9-6H13a3 3 0 0 1 0 6Z"/></svg>',
    cloud: '<svg viewBox="0 0 24 24" ' + STROKE + '><path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"/></svg>',
    fog: '<svg viewBox="0 0 24 24" ' + STROKE + '><path d="M4 14.9A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.24"/><path d="M16 17H7"/><path d="M17 21H9"/></svg>',
    drizzle: '<svg viewBox="0 0 24 24" ' + STROKE + '><path d="M4 14.9A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.24"/><path d="M8 19v1"/><path d="M8 14v1"/><path d="M16 19v1"/><path d="M16 14v1"/><path d="M12 22v1"/><path d="M12 16.5v1"/></svg>',
    rain: '<svg viewBox="0 0 24 24" ' + STROKE + '><path d="M4 14.9A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.24"/><path d="M16 13.5v6"/><path d="M8 13.5v6"/><path d="M12 17v4"/></svg>',
    snow: '<svg viewBox="0 0 24 24" ' + STROKE + '><path d="M4 14.9A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.24"/><path d="M8 20v-2"/><path d="M8 15v-2"/><path d="M12 20v-2"/><path d="M12 15v-2"/><path d="M16 20v-2"/><path d="M16 15v-2"/></svg>',
    thunder: '<svg viewBox="0 0 24 24" ' + STROKE + '><path d="M4 14.9A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 .5 8.97"/><path d="M13 12l-3 5h4l-3 5"/></svg>',
    alert: '<svg viewBox="0 0 24 24" ' + STROKE + '><path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3Z"/><path d="M12 9v4"/><path d="M12 17h.01"/></svg>',
    refresh: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.9" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/><path d="M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16"/><path d="M8 16H3v5"/></svg>'
  };

  /* ---------------- condition mapping ---------------- */
  function condInfo(code) {
    function C(label, icon, accent) { return { label: label, icon: icon, accent: accent }; }
    if (code == null) return C('Unknown', 'cloud', '#94a3b8');
    switch (true) {
      case code === 0:   return C('Clear sky', 'sun', '#fbbf24');
      case code === 1:   return C('Mainly clear', 'sun', '#fcd34d');
      case code === 2:   return C('Partly cloudy', 'suncloud', '#7dd3fc');
      case code === 3:   return C('Overcast', 'cloud', '#94a3b8');
      case code === 45 || code === 48:
                         return C(code === 45 ? 'Fog' : 'Rime fog', 'fog', '#9fb3c8');
      case code >= 51 && code <= 57:
                         return C(code === 51 ? 'Light drizzle' : code === 55 ? 'Dense drizzle' : code >= 56 ? 'Freezing drizzle' : 'Drizzle', 'drizzle', '#7dd3fc');
      case code >= 61 && code <= 67:
                         return C(code === 61 ? 'Light rain' : code === 65 ? 'Heavy rain' : code >= 66 ? 'Freezing rain' : 'Rain', 'rain', '#38bdf8');
      case code >= 71 && code <= 77:
                         return C(code === 71 ? 'Light snow' : code === 75 ? 'Heavy snow' : code === 77 ? 'Snow grains' : 'Snow', 'snow', '#a5f3fc');
      case code >= 80 && code <= 82:
                         return C(code === 80 ? 'Light showers' : code === 82 ? 'Heavy showers' : 'Showers', 'rain', '#38bdf8');
      case code >= 85 && code <= 86:
                         return C('Snow showers', 'snow', '#a5f3fc');
      case code >= 95 && code <= 99:
                         return C(code === 95 ? 'Thunderstorm' : 'Thunderstorm, hail', 'thunder', '#a78bfa');
      default:           return C('Unknown', 'cloud', '#94a3b8');
    }
  }

  /* ---------------- helpers ---------------- */
  function esc(s) {
    return String(s).replace(/[&<>"']/g, function (c) {
      return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c];
    });
  }
  function fmtTemp(v) {
    if (v == null || Number.isNaN(v)) return '\u2014';
    return Math.round(v) + '\u00b0';
  }
  function fmtDate(iso) {
    var d = new Date(iso + 'T00:00:00Z');
    if (Number.isNaN(d.getTime())) return iso;
    return d.toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', timeZone: 'UTC' });
  }
  function hourOf(t) {
    var m = String(t).match(/T(\d{2})/);
    return m ? m[1] : '--';
  }
  function coord(v, pos, neg) {
    return Math.abs(v).toFixed(2) + '\u00b0' + (v >= 0 ? pos : neg);
  }

  /* ---------------- data fetching ---------------- */
  function buildQuery(dateStr) {
    return 'latitude=' + lat +
      '&longitude=' + lon +
      '&daily=temperature_2m_max,temperature_2m_min,weather_code' +
      '&hourly=temperature_2m' +
      '&timezone=UTC' +
      '&temperature_unit=celsius' +
      '&start_date=' + dateStr +
      '&end_date=' + dateStr;
  }

  function fetchEndpoint(endpoint, dateStr) {
    var url = '/api/om/' + endpoint + '?' + buildQuery(dateStr);
    return fetch(url, { headers: { Accept: 'application/json' } }).then(function (res) {
      if (!res.ok) throw new Error('http-' + res.status);
      return res.json();
    }).then(function (j) {
      var daily = j.daily || {};
      var times = daily.time || [];
      var i = times.indexOf(dateStr);
      if (i < 0) throw new Error('no-data');
      var hTimes = (j.hourly && j.hourly.time) || [];
      var hTemps = (j.hourly && j.hourly.temperature_2m) || [];
      var hours = [];
      for (var k = 0; k < hTimes.length; k++) {
        if (String(hTimes[k]).slice(0, 10) === dateStr) {
          var v = hTemps[k];
          hours.push({ t: String(hTimes[k]), v: (v == null || Number.isNaN(v)) ? null : Number(v) });
        }
      }
      return {
        date: dateStr,
        endpoint: endpoint,
        max: daily.temperature_2m_max ? daily.temperature_2m_max[i] : null,
        min: daily.temperature_2m_min ? daily.temperature_2m_min[i] : null,
        code: daily.weather_code ? daily.weather_code[i] : null,
        hours: hours
      };
    });
  }

  function loadWeather() {
    if (badDate) return Promise.resolve({ ok: false, reason: 'invalid-date' });
    var primary = date >= todayUTC() ? 'forecast' : 'archive';
    var fallback = primary === 'forecast' ? 'archive' : 'forecast';
    var lastErr = null;
    var attempt = function (ep) {
      return fetchEndpoint(ep, date).then(
        function (data) { return { ok: true, data: data }; },
        function (e) { lastErr = e; return null; }
      );
    };
    return attempt(primary).then(function (res) {
      if (res) return res;
      return attempt(fallback).then(function (res2) {
        if (res2) return res2;
        return {
          ok: false,
          reason: (lastErr && lastErr.message === 'no-data') ? 'no-data' : 'network',
          detail: lastErr ? lastErr.message : ''
        };
      });
    });
  }

  /* ---------------- rendering ---------------- */
  function showSkeleton() {
    var heights = [22, 17, 15, 13, 13, 14, 16, 21, 27, 33, 40, 45, 47, 46, 43, 40, 37, 34, 31, 28, 26, 25, 24, 23];
    var bars = '';
    for (var i = 0; i < heights.length; i++) {
      bars += '<div class="sk bar-sk" style="height:' + heights[i] + '%;animation-delay:' + (i * 55) + 'ms"></div>';
    }
    content.innerHTML =
      '<header class="head">' +
        '<div>' +
          '<div class="sk" style="width:190px;height:30px"></div>' +
          '<div class="sk" style="width:255px;height:12px;margin-top:13px"></div>' +
        '</div>' +
        '<div class="sk" style="width:150px;height:37px;border-radius:999px"></div>' +
      '</header>' +
      '<section class="stats">' +
        '<div class="stat"><div class="sk" style="width:72px;height:11px"></div><div class="sk" style="width:104px;height:42px;margin-top:6px"></div></div>' +
        '<div class="stat"><div class="sk" style="width:72px;height:11px"></div><div class="sk" style="width:88px;height:42px;margin-top:6px"></div></div>' +
        '<div class="stat"><div class="sk" style="width:80px;height:11px"></div><div class="sk" style="width:170px;height:38px;margin-top:6px"></div></div>' +
      '</section>' +
      '<section class="hourly">' +
        '<div class="sec-head"><span class="sk" style="width:160px;height:11px"></span><span class="sk" style="width:62px;height:11px"></span></div>' +
        '<div class="chart" style="align-items:flex-end">' + bars + '</div>' +
      '</section>' +
      '<footer class="foot">' +
        '<span class="sk" style="width:250px;height:11px"></span>' +
        '<span class="sk" style="width:36px;height:36px;border-radius:12px"></span>' +
      '</footer>';
  }

  function buildDataView(d) {
    var info = condInfo(d.code);
    var condLabel = d.code == null ? 'Unavailable' : info.label;
    return (
      '<header class="head">' +
        '<div>' +
          '<h1 class="loc">' + esc(locationName) + '</h1>' +
          '<p class="date">' + esc(fmtDate(d.date)) + '</p>' +
        '</div>' +
        '<div class="cond-chip" title="WMO weather code ' + (d.code == null ? 'n/a' : d.code) + '">' +
          '<span class="ic">' + I[info.icon] + '</span>' +
          '<span class="lbl">' + esc(condLabel) + '</span>' +
        '</div>' +
      '</header>' +
      '<section class="stats">' +
        '<div class="stat">' +
          '<span class="stat-cap">Maximum</span>' +
          '<span class="stat-val hi">' + fmtTemp(d.max) + '</span>' +
        '</div>' +
        '<div class="stat">' +
          '<span class="stat-cap">Minimum</span>' +
          '<span class="stat-val lo">' + fmtTemp(d.min) + '</span>' +
        '</div>' +
        '<div class="stat">' +
          '<span class="stat-cap">Condition</span>' +
          '<div class="cond-row">' +
            '<span class="ic">' + I[info.icon] + '</span>' +
            '<span>' +
              '<span class="cond-name">' + esc(condLabel) + '</span>' +
              (d.code != null ? '<span class="cond-sub">WMO code ' + d.code + '</span>' : '') +
            '</span>' +
          '</div>' +
        '</div>' +
      '</section>' +
      '<section class="hourly" aria-label="Hourly temperatures">' +
        '<div class="sec-head">' +
          '<span class="sec-title">Hourly temperatures</span>' +
          '<span class="sec-sub">\u00b0C \u00b7 UTC</span>' +
        '</div>' +
        '<div class="chart-wrap">' +
          '<div class="chart" id="chart"></div>' +
          '<div class="tip" id="tip" role="status"></div>' +
          nowMarker(d) +
        '</div>' +
      '</section>' +
      '<footer class="foot">' +
        '<span class="src"><span class="dot"></span>Open-Meteo \u00b7 ' + esc(d.endpoint) + ' API \u00b7 UTC \u00b7 ' +
          coord(lat, 'N', 'S') + ' ' + coord(lon, 'E', 'W') + '</span>' +
        '<button class="btn-icon" id="refresh" type="button" title="Refresh weather" aria-label="Refresh weather">' + I.refresh + '</button>' +
      '</footer>'
    );
  }

  function nowMarker(d) {
    if (d.date !== todayUTC()) return '';
    var nowHour = new Date().getUTCHours();
    for (var i = 0; i < d.hours.length; i++) {
      if (Number(hourOf(d.hours[i].t)) === nowHour) {
        var left = (i + 0.5) * (100 / d.hours.length);
        return '<div class="now" style="left:' + left + '%"><span class="now-label">NOW</span></div>';
      }
    }
    return '';
  }

  function buildChart(d) {
    var chart = $('#chart', content);
    var tip = $('#tip', content);
    var values = [];
    for (var i = 0; i < d.hours.length; i++) {
      if (d.hours[i].v != null) values.push(d.hours[i].v);
    }
    if (values.length === 0) {
      chart.innerHTML = '<div class="no-hourly">Hourly data is not available for this day.</div>';
      return;
    }
    var min = Math.min.apply(null, values);
    var max = Math.max.apply(null, values);
    var flat = (max - min) < 0.5;
    var html = '';
    for (var k = 0; k < d.hours.length; k++) {
      var h = d.hours[k];
      var pct = 0;
      if (h.v != null) pct = flat ? 52 : 14 + ((h.v - min) / (max - min)) * 70;
      var peak = !flat && h.v != null && h.v === max;
      var lbl = k % 3 === 0 ? hourOf(h.t) : '';
      html +=
        '<div class="col" style="--i:' + k + '">' +
          '<div class="bar' + (peak ? ' peak' : '') + (h.v == null ? ' miss' : '') +
            '" style="height:' + pct + '%" data-i="' + k + '" role="img" aria-label="' +
            (h.v == null ? (hourOf(h.t) + ':00, no data') : (hourOf(h.t) + ':00, ' + h.v.toFixed(1) + ' degrees Celsius')) + '"></div>' +
          '<span class="tick">' + lbl + '</span>' +
        '</div>';
    }
    chart.innerHTML = html;

    chart.addEventListener('mousemove', function (e) {
      var bar = e.target.closest ? e.target.closest('.bar') : null;
      if (!bar) { tip.classList.remove('show'); return; }
      var h = d.hours[Number(bar.getAttribute('data-i'))];
      if (!h) return;
      tip.innerHTML = esc(hourOf(h.t)) + ':00<b>' + (h.v == null ? 'no data' : h.v.toFixed(1) + ' \u00b0C') + '</b>';
      var cr = chart.getBoundingClientRect();
      var br = bar.getBoundingClientRect();
      var x = br.left - cr.left + br.width / 2;
      x = Math.min(cr.width - 60, Math.max(60, x));
      tip.style.left = x + 'px';
      tip.classList.add('show');
    });
    chart.addEventListener('mouseleave', function () { tip.classList.remove('show'); });
  }

  function showError(reason, detail) {
    card.style.setProperty('--accent', '#38bdf8');
    wm.innerHTML = '';
    var msg;
    if (reason === 'invalid-date') {
      msg = ['Invalid date', 'The <code>date</code> parameter must be a valid date in <b>YYYY-MM-DD</b> format.'];
    } else if (reason === 'no-data') {
      msg = ['No data for this day', 'The weather service returned no data for <b>' + esc(date) + '</b>.'];
    } else {
      msg = ["Couldn't load the weather", 'The weather data could not be loaded. Check your connection and make sure the weather API is available from this page, then try again.'];
    }
    content.innerHTML =
      '<div class="err">' +
        '<div class="ic">' + I.alert + '</div>' +
        '<h2>' + msg[0] + '</h2>' +
        '<p>' + msg[1] + '</p>' +
        (detail ? '<p class="detail">' + esc(detail) + '</p>' : '') +
        '<button class="btn-retry" id="retry" type="button">' + I.refresh + 'Try again</button>' +
      '</div>';
  }

  function render(d) {
    var info = condInfo(d.code);
    card.style.setProperty('--accent', info.accent);
    wm.innerHTML = I[info.icon];
    content.innerHTML = buildDataView(d);
    buildChart(d);
  }

  function load(spinBtn) {
    if (spinBtn && spinBtn.id === 'refresh') spinBtn.classList.add('spin');
    showSkeleton();
    return loadWeather().then(function (res) {
      if (spinBtn && spinBtn.id === 'refresh') spinBtn.classList.remove('spin');
      if (res.ok) {
        render(res.data);
      } else {
        showError(res.reason, res.detail);
      }
    });
  }

  content.addEventListener('click', function (e) {
    var btn = e.target.closest ? e.target.closest('#refresh, #retry') : null;
    if (btn) load(btn);
  });

  load();
})();
</script>
</body>
</html>

L1 —— 廉价的确定性描述量

bytes 总计28,765html / css / js692 / 11,379 / 16,694
dom 节点16dom 深度4
css 规则93含 js
brightness26.8contrast19.9
colorfulness23.6留白79.4%

该 slot 的 telemetry

prompt tokens51,107completion tokens65,199
total tokens116,306wall540.7 s
costrequest id
config.json625 B
{
  "N": 2,
  "auth": {
    "credential_ref": "WCB_DEEPSEEK_KEY",
    "method": "api-key"
  },
  "billing": "api",
  "config_id": "deepseek-v4-flash-vision-exp-eff-max--cli--dsh--dev",
  "effort": "max",
  "family": "deepseek",
  "m": {
    "min": 1,
    "q": 1
  },
  "model_id": "deepseek-v4-flash-vision-exp",
  "protocol": "cli",
  "served_model": "deepseek-v4-flash-vision-exp",
  "telemetry": {
    "completion_tokens": 92026,
    "cost_usd": null,
    "prompt_tokens": 70605,
    "total_tokens": 162631,
    "wall_ms": 775056
  },
  "transport": "dsh-0.1.0-rc.8-headless-isolated-home",
  "vendor_sanction_ref": null
}
send-log3.7 KB
{
  "N": 2,
  "batch_id": "2026-08-22--dsh-vision-s1",
  "config_id": "deepseek-v4-flash-vision-exp-eff-max--cli--dsh--dev",
  "positions": [
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-21T17:00:58.547020+00:00",
          "http_status": null,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-21T16:57:04.164398+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-21T17:26:02.992715+00:00",
          "http_status": null,
          "outcome": "infra-failed",
          "reached_model": true,
          "reason": "mid-stream-death",
          "request_id": null,
          "started_at": "2026-08-21T17:01:02.611886+00:00"
        }
      ],
      "block_index": 0,
      "model_reaching_attempt_index": 0,
      "slot_index": 0,
      "terminal_state": "infra-failed",
      "variant": "P-q"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-08-21T17:35:03.692524+00:00",
          "http_status": null,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-08-21T17:26:02.993761+00:00"
        }
      ],
      "block_index": 1,
      "model_reaching_attempt_index": 0,
      "slot_index": 1,
      "terminal_state": "valid",
      "variant": "P-q"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": 500,
          "charged": false,
          "ended_at": "2026-08-21T17:35:09.169991+00:00",
          "http_status": null,
          "outcome": "rate-limited",
          "reached_model": false,
          "reason": "http-429",
          "request_id": null,
          "started_at": "2026-08-21T17:35:07.501774+00:00"
        },
        {
          "attempt_index": 1,
          "backoff_ms": 1000,
          "charged": false,
          "ended_at": "2026-08-21T17:35:10.831445+00:00",
          "http_status": null,
          "outcome": "rate-limited",
          "reached_model": false,
          "reason": "http-429",
          "request_id": null,
          "started_at": "2026-08-21T17:35:09.675069+00:00"
        },
        {
          "attempt_index": 2,
          "backoff_ms": 2000,
          "charged": false,
          "ended_at": "2026-08-21T17:35:12.995277+00:00",
          "http_status": null,
          "outcome": "rate-limited",
          "reached_model": false,
          "reason": "http-429",
          "request_id": null,
          "started_at": "2026-08-21T17:35:11.836556+00:00"
        },
        {
          "attempt_index": 3,
          "backoff_ms": null,
          "charged": false,
          "ended_at": "2026-08-21T17:35:16.154538+00:00",
          "http_status": null,
          "outcome": "rate-limited",
          "reached_model": false,
          "reason": "http-429",
          "request_id": null,
          "started_at": "2026-08-21T17:35:14.995519+00:00"
        }
      ],
      "block_index": 1,
      "model_reaching_attempt_index": null,
      "slot_index": 1,
      "terminal_state": "rate-limited-exhausted",
      "variant": "P-min"
    }
  ],
  "retry_policy": {
    "max_unreachable_retries": 5,
    "rate_limit_backoff": {
      "max_attempts": 4,
      "max_total_ms": 60000
    }
  }
}