glm-5.1 @ disabled · api

apidisabled
config
glm-5.1-eff-disabled--api--official--dev
batch
2026-07-19--unified
transport
bigmodel-openai-compat
protocol
api · metered
served model
glm-5.1
采集于
2026年7月18日 11:54 · N=4
variant
live
slot 0 · P-q · sandboxed iframe
glm-5.1 @disabled · api P-q slot 0 截图

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

similarity 邻居

限于 session 2026-07-19--unified

similarity 衡量本 session 内的趋同程度 —— 不是质量。

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

  • namematch
  • conditionmatch
  • datematch
  • max tempambiguous展示值:25.3max-equals-min
  • min tempambiguous展示值:25.3max-equals-min
  • 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=1280">
<title>Weather Card</title>
<style>
  *,*::before,*::after{margin:0;padding:0;box-sizing:border-box}
  @font-face{font-family:'Fallback';src:local('Segoe UI'),local('Helvetica Neue'),local('Helvetica'),local('Arial');size-adjust:92%}

  :root{
    --bg:#0B0F1A;
    --card:#111827;
    --card-alt:#151D2E;
    --border:#1E293B;
    --fg:#F1F5F9;
    --muted:#94A3B8;
    --dim:#475569;
    --accent:#F59E0B;
    --accent-glow:rgba(245,158,11,0.25);
    --radius:24px;
    --radius-sm:16px;
  }

  html,body{width:100%;height:100%;overflow:hidden;background:var(--bg);color:var(--fg);font-family:'Fallback',sans-serif}

  body{display:flex;align-items:center;justify-content:center;position:relative}

  /* Animated background orbs */
  .orb{position:fixed;border-radius:50%;pointer-events:none;filter:blur(90px)}
  .orb-1{width:520px;height:520px;background:rgba(245,158,11,0.10);top:-10%;left:-8%;animation:drift1 22s ease-in-out infinite}
  .orb-2{width:440px;height:440px;background:rgba(16,185,129,0.08);bottom:-12%;right:-6%;animation:drift2 26s ease-in-out infinite}
  .orb-3{width:300px;height:300px;background:rgba(139,92,246,0.06);top:50%;left:60%;animation:drift3 18s ease-in-out infinite}

  @keyframes drift1{0%,100%{transform:translate(0,0)}50%{transform:translate(60px,40px)}}
  @keyframes drift2{0%,100%{transform:translate(0,0)}50%{transform:translate(-50px,-30px)}}
  @keyframes drift3{0%,100%{transform:translate(0,0)}50%{transform:translate(-30px,50px)}}

  /* Subtle grid pattern overlay */
  .grid-overlay{position:fixed;inset:0;pointer-events:none;
    background-image:
      linear-gradient(rgba(255,255,255,0.015) 1px, transparent 1px),
      linear-gradient(90deg, rgba(255,255,255,0.015) 1px, transparent 1px);
    background-size:60px 60px}

  /* Card */
  .card{
    position:relative;z-index:1;
    width:620px;
    background:var(--card);
    border:1px solid var(--border);
    border-radius:var(--radius);
    box-shadow:0 4px 60px rgba(0,0,0,0.5),0 0 0 1px rgba(255,255,255,0.03) inset;
    overflow:hidden;
    animation:cardIn 0.7s cubic-bezier(0.16,1,0.3,1) both;
  }
  @keyframes cardIn{0%{opacity:0;transform:translateY(30px) scale(0.97)}100%{opacity:1;transform:translateY(0) scale(1)}}

  /* Top accent bar */
  .card-accent{height:3px;background:linear-gradient(90deg,var(--accent),#10B981,var(--accent));background-size:200% 100%;animation:shimmer 4s linear infinite}
  @keyframes shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}

  /* Glass overlay on card */
  .card::before{content:'';position:absolute;inset:0;background:linear-gradient(160deg,rgba(255,255,255,0.04) 0%,transparent 40%);pointer-events:none;z-index:0;border-radius:var(--radius)}

  .card-inner{position:relative;z-index:1;padding:36px 40px 32px}

  /* Header */
  .header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:8px}
  .location{font-size:28px;font-weight:800;letter-spacing:-0.5px;line-height:1.2}
  .date{font-size:14px;color:var(--muted);margin-top:4px;font-weight:500}
  .header-right{text-align:right;display:flex;flex-direction:column;align-items:flex-end;gap:2px}
  .header-right .temp-max{font-size:42px;font-weight:900;letter-spacing:-2px;line-height:1;color:var(--accent)}
  .header-right .temp-min{font-size:18px;font-weight:600;color:var(--dim);letter-spacing:-0.5px}

  /* Condition */
  .condition-row{display:flex;align-items:center;gap:12px;margin:16px 0 28px;padding:14px 18px;background:var(--card-alt);border-radius:var(--radius-sm);border:1px solid var(--border)}
  .condition-icon svg{width:36px;height:36px;flex-shrink:0}
  .condition-text{font-size:17px;font-weight:600;color:var(--fg)}
  .condition-desc{font-size:13px;color:var(--muted);margin-top:2px}

  /* Hourly section */
  .hourly-label{font-size:13px;font-weight:700;text-transform:uppercase;letter-spacing:1.5px;color:var(--dim);margin-bottom:16px}

  .chart-wrap{position:relative;height:160px;margin-bottom:8px}
  .chart-wrap canvas{width:100%;height:100%;display:block}
  .tooltip{
    position:absolute;pointer-events:none;
    background:rgba(17,24,39,0.95);border:1px solid var(--border);
    border-radius:10px;padding:6px 12px;
    font-size:12px;font-weight:600;color:var(--fg);
    transform:translate(-50%,-140%);
    opacity:0;transition:opacity 0.15s;
    white-space:nowrap;z-index:10;
    box-shadow:0 4px 12px rgba(0,0,0,0.4);
  }
  .tooltip.visible{opacity:1}
  .tooltip::after{content:'';position:absolute;bottom:-5px;left:50%;transform:translateX(-50%) rotate(45deg);width:8px;height:8px;background:rgba(17,24,39,0.95);border-right:1px solid var(--border);border-bottom:1px solid var(--border)}

  .hour-labels{display:flex;justify-content:space-between;padding:0 6px}
  .hour-labels span{font-size:11px;color:var(--dim);font-weight:500;width:0;text-align:center}

  /* Error state */
  .error-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 40px;text-align:center}
  .error-state .error-icon{width:56px;height:56px;margin-bottom:20px;opacity:0.5}
  .error-state .error-icon svg{width:100%;height:100%}
  .error-state .error-title{font-size:20px;font-weight:700;margin-bottom:8px;color:var(--fg)}
  .error-state .error-msg{font-size:14px;color:var(--muted);max-width:360px;line-height:1.6}

  /* Loading */
  .loading-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:80px 40px}
  .spinner{width:40px;height:40px;border:3px solid var(--border);border-top-color:var(--accent);border-radius:50%;animation:spin 0.8s linear infinite;margin-bottom:20px}
  @keyframes spin{to{transform:rotate(360deg)}}
  .loading-state p{font-size:14px;color:var(--muted)}

  /* Reduced motion */
  @media(prefers-reduced-motion:reduce){
    .orb,.card-accent,.spinner{animation:none!important}
    .card{animation:none!important;opacity:1;transform:none}
  }
</style>
</head>
<body>

<!-- Background effects -->
<div class="orb orb-1"></div>
<div class="orb orb-2"></div>
<div class="orb orb-3"></div>
<div class="grid-overlay"></div>

<!-- Weather Card -->
<div class="card" id="card">
  <div class="card-accent"></div>
  <div id="card-content">
    <div class="loading-state">
      <div class="spinner"></div>
      <p>Fetching weather data...</p>
    </div>
  </div>
</div>

<script>
(function(){
  /* ── Parse URL query params ── */
  var params = new URLSearchParams(window.location.search);
  var lat = parseFloat(params.get('lat')) || 52.52;
  var lon = parseFloat(params.get('lon')) || 13.405;
  var name = params.get('name') || 'Berlin';
  var dateStr = params.get('date') || new Date().toISOString().split('T')[0];

  /* ── Determine if date is past → use archive API ── */
  var today = new Date();
  today.setUTCHours(0,0,0,0);
  var requested = new Date(dateStr + 'T00:00:00Z');
  var isPast = requested < today;
  var apiBase = isPast ? '/api/om/archive' : '/api/om/forecast';

  /* ── Weather code descriptions and icons ── */
  function getWeatherInfo(code){
    var map = {
      0:  {desc:'Clear Sky',        icon:'sun',       detail:'No clouds, unobstructed visibility'},
      1:  {desc:'Mainly Clear',     icon:'sun',       detail:'Less than 20% cloud cover'},
      2:  {desc:'Partly Cloudy',    icon:'cloud-sun', detail:'Variable cloud cover'},
      3:  {desc:'Overcast',         icon:'cloud',     detail:'Complete cloud cover'},
      45: {desc:'Foggy',            icon:'fog',       detail:'Dense fog reducing visibility'},
      48: {desc:'Rime Fog',         icon:'fog',       detail:'Fog with rime ice deposits'},
      51: {desc:'Light Drizzle',    icon:'drizzle',   detail:'Slight, fine precipitation'},
      53: {desc:'Moderate Drizzle', icon:'drizzle',   detail:'Steady light drizzle'},
      55: {desc:'Dense Drizzle',    icon:'drizzle',   detail:'Intense, persistent drizzle'},
      56: {desc:'Freezing Drizzle', icon:'drizzle',   detail:'Supercooled drizzle, icy surfaces'},
      57: {desc:'Heavy Freezing Drizzle', icon:'drizzle', detail:'Dangerous icy conditions'},
      61: {desc:'Slight Rain',      icon:'rain',      detail:'Gentle rainfall'},
      63: {desc:'Moderate Rain',    icon:'rain',      detail:'Steady rainfall'},
      65: {desc:'Heavy Rain',       icon:'rain',      detail:'Intense downpour'},
      66: {desc:'Freezing Rain',    icon:'rain',      detail:'Rain freezing on contact'},
      67: {desc:'Heavy Freezing Rain', icon:'rain',   detail:'Severe freezing rain'},
      71: {desc:'Slight Snowfall',  icon:'snow',      detail:'Light snow'},
      73: {desc:'Moderate Snowfall',icon:'snow',      detail:'Steady snowfall'},
      75: {desc:'Heavy Snowfall',   icon:'snow',      detail:'Intense snowfall'},
      77: {desc:'Snow Grains',      icon:'snow',      detail:'Granular snow pellets'},
      80: {desc:'Slight Showers',   icon:'rain',      detail:'Brief rain showers'},
      81: {desc:'Moderate Showers', icon:'rain',      detail:'Intermittent heavier showers'},
      82: {desc:'Violent Showers',  icon:'rain',      detail:'Torrential downpours'},
      85: {desc:'Slight Snow Showers', icon:'snow',   detail:'Light snow showers'},
      86: {desc:'Heavy Snow Showers',  icon:'snow',   detail:'Intense snow showers'},
      95: {desc:'Thunderstorm',     icon:'thunder',   detail:'Thunder and lightning'},
      96: {desc:'Thunderstorm with Hail', icon:'thunder', detail:'Hail accompanying storm'},
      99: {desc:'Severe Thunderstorm',   icon:'thunder', detail:'Large hail, dangerous winds'}
    };
    return map[code] || {desc:'Unknown', icon:'cloud', detail:'Weather code: ' + code};
  }

  /* ── SVG icon generators ── */
  function makeIcon(type, color){
    var c = color || '#F59E0B';
    switch(type){
      case 'sun': return '<svg viewBox="0 0 40 40" fill="none"><circle cx="20" cy="20" r="7" fill="'+c+'"/><g stroke="'+c+'" stroke-width="2.5" stroke-linecap="round"><line x1="20" y1="3" x2="20" y2="9"/><line x1="20" y1="31" x2="20" y2="37"/><line x1="3" y1="20" x2="9" y2="20"/><line x1="31" y1="20" x2="37" y2="20"/><line x1="8" y1="8" x2="12.2" y2="12.2"/><line x1="27.8" y1="27.8" x2="32" y2="32"/><line x1="8" y1="32" x2="12.2" y2="27.8"/><line x1="27.8" y1="12.2" x2="32" y2="8"/></g></svg>';
      case 'cloud-sun': return '<svg viewBox="0 0 40 40" fill="none"><circle cx="15" cy="14" r="6" fill="'+c+'" opacity="0.9"/><g stroke="'+c+'" stroke-width="2" stroke-linecap="round" opacity="0.7"><line x1="15" y1="3" x2="15" y2="6"/><line x1="6" y1="14" x2="9" y2="14"/><line x1="8" y1="7" x2="10.1" y2="9.1"/><line x1="22" y1="7" x2="19.9" y2="9.1"/></g><path d="M14 30C9.6 30 6 27.3 6 23.5 6 19.7 9.6 17 14 17 14.3 17 14.6 17 14.9 17.0 15.9 13.4 19.4 11 23.5 11 28.2 11 32 14.6 32 19 32 19.3 32 19.7 31.9 20 33.5 19.8 35 21.4 35 23.5 35 26.5 32.5 29 29 29.3L14 30Z" fill="#94A3B8"/></svg>';
      case 'cloud': return '<svg viewBox="0 0 40 40" fill="none"><path d="M11 31C6.6 31 3 28.3 3 24.5 3 20.7 6.6 18 11 18 11.3 18 11.6 18 11.9 18 12.9 14.4 16.4 12 20.5 12 25.2 12 29 15.6 29 20 29 20.3 29 20.7 28.9 21 30.5 20.8 32 22.4 32 24.5 32 27.5 29.5 30 26 30.3L11 31Z" fill="#64748B"/></svg>';
      case 'fog': return '<svg viewBox="0 0 40 40" fill="none"><g stroke="#64748B" stroke-width="3" stroke-linecap="round"><line x1="6" y1="12" x2="34" y2="12" opacity="0.5"/><line x1="4" y1="18" x2="36" y2="18" opacity="0.7"/><line x1="6" y1="24" x2="34" y2="24" opacity="0.7"/><line x1="8" y1="30" x2="32" y2="30" opacity="0.5"/></g></svg>';
      case 'drizzle': return '<svg viewBox="0 0 40 40" fill="none"><path d="M11 24C6.6 24 3 21.3 3 17.5 3 13.7 6.6 11 11 11 11.3 11 11.6 11 11.9 11 12.9 7.4 16.4 5 20.5 5 25.2 5 29 8.6 29 13 29 13.3 29 13.7 28.9 14 30.5 13.8 32 15.4 32 17.5 32 20.5 29.5 23 26 23.3L11 24Z" fill="#64748B"/><g stroke="#60A5FA" stroke-width="2" stroke-linecap="round"><line x1="12" y1="28" x2="10" y2="33"/><line x1="20" y1="27" x2="18" y2="32"/><line x1="28" y1="28" x2="26" y2="33"/></g></svg>';
      case 'rain': return '<svg viewBox="0 0 40 40" fill="none"><path d="M11 22C6.6 22 3 19.3 3 15.5 3 11.7 6.6 9 11 9 11.3 9 11.6 9 11.9 9 12.9 5.4 16.4 3 20.5 3 25.2 3 29 6.6 29 11 29 11.3 29 11.7 28.9 12 30.5 11.8 32 13.4 32 15.5 32 18.5 29.5 21 26 21.3L11 22Z" fill="#64748B"/><g stroke="#3B82F6" stroke-width="2.5" stroke-linecap="round"><line x1="10" y1="26" x2="7" y2="33"/><line x1="20" y1="25" x2="17" y2="32"/><line x1="30" y1="26" x2="27" y2="33"/></g></svg>';
      case 'snow': return '<svg viewBox="0 0 40 40" fill="none"><path d="M11 22C6.6 22 3 19.3 3 15.5 3 11.7 6.6 9 11 9 11.3 9 11.6 9 11.9 9 12.9 5.4 16.4 3 20.5 3 25.2 3 29 6.6 29 11 29 11.3 29 11.7 28.9 12 30.5 11.8 32 13.4 32 15.5 32 18.5 29.5 21 26 21.3L11 22Z" fill="#64748B"/><g fill="#E2E8F0"><circle cx="11" cy="28" r="2.2"/><circle cx="20" cy="30" r="2.2"/><circle cx="29" cy="27" r="2.2"/><circle cx="15" cy="34" r="1.8"/><circle cx="25" cy="35" r="1.8"/></g></svg>';
      case 'thunder': return '<svg viewBox="0 0 40 40" fill="none"><path d="M11 20C6.6 20 3 17.3 3 13.5 3 9.7 6.6 7 11 7 11.3 7 11.6 7 11.9 7 12.9 3.4 16.4 1 20.5 1 25.2 1 29 4.6 29 9 29 9.3 29 9.7 28.9 10 30.5 9.8 32 11.4 32 13.5 32 16.5 29.5 19 26 19.3L11 20Z" fill="#64748B"/><polygon points="21,18 16,28 20,28 18,38 27,25 22,25 25,18" fill="'+c+'"/></svg>';
      default: return '<svg viewBox="0 0 40 40" fill="none"><circle cx="20" cy="20" r="8" fill="#64748B"/></svg>';
    }
  }

  /* ── Format date for display ── */
  function formatDate(dateStr){
    var d = new Date(dateStr + 'T00:00:00Z');
    var days = ['Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday'];
    var months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
    return days[d.getUTCDay()] + ', ' + months[d.getUTCMonth()] + ' ' + d.getUTCDate() + ', ' + d.getUTCFullYear();
  }

  /* ── Render error state ── */
  function renderError(msg){
    var content = document.getElementById('card-content');
    content.innerHTML =
      '<div class="error-state">' +
        '<div class="error-icon"><svg viewBox="0 0 24 24" fill="none" stroke="#94A3B8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg></div>' +
        '<div class="error-title">Unable to Load Weather</div>' +
        '<div class="error-msg">' + msg + '</div>' +
      '</div>';
  }

  /* ── Render success ── */
  function renderWeather(data){
    var tMax = data.daily.temperature_2m_max[0];
    var tMin = data.daily.temperature_2m_min[0];
    var wCode = data.daily.weather_code[0];
    var info = getWeatherInfo(wCode);
    var hours = data.hourly.time;
    var temps = data.hourly.temperature_2m;

    /* Filter to the target date */
    var targetDate = dateStr;
    var filteredHours = [];
    var filteredTemps = [];
    for(var i = 0; i < hours.length; i++){
      if(hours[i].startsWith(targetDate)){
        filteredHours.push(hours[i]);
        filteredTemps.push(temps[i]);
      }
    }

    /* Hour labels for X axis — show every 3rd */
    var hourLabels = [];
    for(var h = 0; h < 24; h++){
      hourLabels.push(h.toString().padStart(2,'0'));
    }

    var content = document.getElementById('card-content');
    content.innerHTML =
      '<div class="card-inner">' +
        '<div class="header">' +
          '<div>' +
            '<div class="location">' + escapeHtml(name) + '</div>' +
            '<div class="date">' + formatDate(dateStr) + '</div>' +
          '</div>' +
          '<div class="header-right">' +
            '<div class="temp-max">' + tMax + '°</div>' +
            '<div class="temp-min">' + tMin + '°C</div>' +
          '</div>' +
        '</div>' +
        '<div class="condition-row">' +
          '<div class="condition-icon">' + makeIcon(info.icon, '#F59E0B') + '</div>' +
          '<div>' +
            '<div class="condition-text">' + info.desc + '</div>' +
            '<div class="condition-desc">' + info.detail + '</div>' +
          '</div>' +
        '</div>' +
        '<div class="hourly-label">Hourly Temperature</div>' +
        '<div class="chart-wrap">' +
          '<canvas id="hourlyChart"></canvas>' +
          '<div class="tooltip" id="tooltip"></div>' +
        '</div>' +
        '<div class="hour-labels" id="hourLabels"></div>' +
      '</div>';

    /* Draw hourly labels */
    var labelsEl = document.getElementById('hourLabels');
    for(var h = 0; h < 24; h++){
      var span = document.createElement('span');
      span.textContent = (h % 3 === 0) ? hourLabels[h] : '';
      labelsEl.appendChild(span);
    }

    /* Draw chart */
    drawChart(filteredTemps);
  }

  function escapeHtml(s){
    var d = document.createElement('div');
    d.textContent = s;
    return d.innerHTML;
  }

  /* ── Canvas chart with interaction ── */
  function drawChart(temperatures){
    var canvas = document.getElementById('hourlyChart');
    if(!canvas || temperatures.length === 0) return;

    var dpr = window.devicePixelRatio || 1;
    var rect = canvas.getBoundingClientRect();
    canvas.width = rect.width * dpr;
    canvas.height = rect.height * dpr;
    var ctx = canvas.getContext('2d');
    ctx.scale(dpr, dpr);

    var W = rect.width;
    var H = rect.height;
    var pad = {top: 24, bottom: 28, left: 8, right: 8};
    var chartW = W - pad.left - pad.right;
    var chartH = H - pad.top - pad.bottom;

    var tMin = Math.min.apply(null, temperatures);
    var tMax = Math.max.apply(null, temperatures);
    var range = Math.max(tMax - tMin, 1);
    /* Add 10% padding above and below */
    var paddedMin = tMin - range * 0.15;
    var paddedMax = tMax + range * 0.15;
    var paddedRange = Math.max(paddedMax - paddedMin, 1);

    /* Compute points */
    var points = [];
    for(var i = 0; i < temperatures.length; i++){
      var x = pad.left + (i / Math.max(temperatures.length - 1, 1)) * chartW;
      var y = pad.top + chartH - ((temperatures[i] - paddedMin) / paddedRange) * chartH;
      points.push({x: x, y: y, temp: temperatures[i]});
    }

    /* Draw horizontal grid lines */
    var gridSteps = 4;
    ctx.save();
    ctx.strokeStyle = 'rgba(255,255,255,0.04)';
    ctx.lineWidth = 1;
    for(var g = 0; g <= gridSteps; g++){
      var gy = pad.top + (g / gridSteps) * chartH;
      ctx.beginPath();
      ctx.moveTo(pad.left, gy);
      ctx.lineTo(W - pad.right, gy);
      ctx.stroke();
    }
    ctx.restore();

    /* Draw area gradient fill */
    ctx.save();
    var areaGrad = ctx.createLinearGradient(0, pad.top, 0, H - pad.bottom);
    areaGrad.addColorStop(0, 'rgba(245,158,11,0.25)');
    areaGrad.addColorStop(0.6, 'rgba(245,158,11,0.08)');
    areaGrad.addColorStop(1, 'rgba(245,158,11,0.0)');

    ctx.beginPath();
    ctx.moveTo(points[0].x, H - pad.bottom);
    for(var i = 0; i < points.length; i++){
      if(i === 0){ctx.lineTo(points[i].x, points[i].y);}
      else{
        var cp1x = (points[i-1].x + points[i].x) / 2;
        var cp1y = points[i-1].y;
        var cp2x = cp1x;
        var cp2y = points[i].y;
        ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, points[i].x, points[i].y);
      }
    }
    ctx.lineTo(points[points.length-1].x, H - pad.bottom);
    ctx.closePath();
    ctx.fillStyle = areaGrad;
    ctx.fill();
    ctx.restore();

    /* Draw line */
    ctx.save();
    ctx.beginPath();
    for(var i = 0; i < points.length; i++){
      if(i === 0){ctx.moveTo(points[i].x, points[i].y);}
      else{
        var cp1x = (points[i-1].x + points[i].x) / 2;
        var cp1y = points[i-1].y;
        var cp2x = cp1x;
        var cp2y = points[i].y;
        ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, points[i].x, points[i].y);
      }
    }
    ctx.strokeStyle = '#F59E0B';
    ctx.lineWidth = 2.5;
    ctx.lineJoin = 'round';
    ctx.lineCap = 'round';
    ctx.shadowColor = 'rgba(245,158,11,0.4)';
    ctx.shadowBlur = 8;
    ctx.stroke();
    ctx.restore();

    /* Draw dots at each data point */
    ctx.save();
    for(var i = 0; i < points.length; i++){
      ctx.beginPath();
      ctx.arc(points[i].x, points[i].y, 3, 0, Math.PI*2);
      ctx.fillStyle = '#F59E0B';
      ctx.fill();
      ctx.beginPath();
      ctx.arc(points[i].x, points[i].y, 1.5, 0, Math.PI*2);
      ctx.fillStyle = '#111827';
      ctx.fill();
    }
    ctx.restore();

    /* Max/min labels on chart */
    var maxIdx = temperatures.indexOf(tMax);
    var minIdx = temperatures.indexOf(tMin);
    ctx.save();
    ctx.font = '600 11px "Fallback", sans-serif';
    ctx.textAlign = 'center';
    /* Max label */
    if(maxIdx >= 0 && points[maxIdx]){
      ctx.fillStyle = '#F59E0B';
      ctx.fillText(tMax + '°', points[maxIdx].x, points[maxIdx].y - 10);
    }
    /* Min label */
    if(minIdx >= 0 && points[minIdx]){
      ctx.fillStyle = '#64748B';
      ctx.fillText(tMin + '°', points[minIdx].x, points[minIdx].y + 18);
    }
    ctx.restore();

    /* Interaction: hover for tooltip */
    var tooltip = document.getElementById('tooltip');
    var chartWrap = canvas.parentElement;

    function handleMove(e){
      var bounds = canvas.getBoundingClientRect();
      var mx = e.clientX - bounds.left;
      var my = e.clientY - bounds.top;

      /* Find closest point */
      var closest = -1;
      var closestDist = Infinity;
      for(var i = 0; i < points.length; i++){
        var dx = Math.abs(points[i].x - mx);
        if(dx < closestDist){closestDist = dx; closest = i;}
      }

      if(closest >= 0 && closestDist < 20){
        tooltip.className = 'tooltip visible';
        tooltip.innerHTML = '<strong>' + points[closest].temp + '°C</strong> &nbsp;' + closest.toString().padStart(2,'0') + ':00';
        tooltip.style.left = points[closest].x + 'px';
        tooltip.style.top = points[closest].y + 'px';

        /* Redraw with highlight */
        drawHighlight(closest);
      } else {
        tooltip.className = 'tooltip';
        clearHighlight();
      }
    }

    function handleLeave(){
      tooltip.className = 'tooltip';
      clearHighlight();
    }

    var highlightCanvas = document.createElement('canvas');
    highlightCanvas.style.cssText = 'position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:5';
    chartWrap.appendChild(highlightCanvas);

    function drawHighlight(idx){
      var hDpr = window.devicePixelRatio || 1;
      highlightCanvas.width = rect.width * hDpr;
      highlightCanvas.height = rect.height * hDpr;
      var hCtx = highlightCanvas.getContext('2d');
      hCtx.scale(hDpr, hDpr);
      var p = points[idx];

      /* Vertical dashed line */
      hCtx.save();
      hCtx.strokeStyle = 'rgba(245,158,11,0.3)';
      hCtx.lineWidth = 1;
      hCtx.setLineDash([4,4]);
      hCtx.beginPath();
      hCtx.moveTo(p.x, pad.top);
      hCtx.lineTo(p.x, H - pad.bottom);
      hCtx.stroke();
      hCtx.restore();

      /* Highlight dot */
      hCtx.beginPath();
      hCtx.arc(p.x, p.y, 6, 0, Math.PI*2);
      hCtx.fillStyle = 'rgba(245,158,11,0.3)';
      hCtx.fill();
      hCtx.beginPath();
      hCtx.arc(p.x, p.y, 4, 0, Math.PI*2);
      hCtx.fillStyle = '#F59E0B';
      hCtx.fill();
    }

    function clearHighlight(){
      highlightCanvas.width = 0;
      highlightCanvas.height = 0;
    }

    canvas.addEventListener('mousemove', handleMove);
    canvas.addEventListener('mouseleave', handleLeave);
  }

  /* ── Fetch weather data ── */
  var url = apiBase +
    '?latitude=' + encodeURIComponent(lat) +
    '&longitude=' + encodeURIComponent(lon) +
    '&daily=temperature_2m_max,temperature_2m_min,weather_code' +
    '&hourly=temperature_2m' +
    '&timezone=UTC' +
    '&temperature_unit=celsius' +
    '&start_date=' + encodeURIComponent(dateStr) +
    '&end_date=' + encodeURIComponent(dateStr);

  fetch(url)
    .then(function(res){
      if(!res.ok) throw new Error('API returned status ' + res.status);
      return res.json();
    })
    .then(function(data){
      /* Validate expected fields */
      if(!data.daily || !data.hourly ||
         !data.daily.temperature_2m_max || !data.daily.temperature_2m_min ||
         !data.daily.weather_code || !data.hourly.temperature_2m || !data.hourly.time){
        throw new Error('Unexpected API response format');
      }
      if(data.daily.temperature_2m_max.length === 0 || data.hourly.temperature_2m.length === 0){
        throw new Error('No data available for the requested date');
      }
      renderWeather(data);
    })
    .catch(function(err){
      renderError(escapeHtml(err.message || 'An unexpected error occurred while fetching weather data.'));
    });

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

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

bytes 总计24,826html / css / js595 / 5,872 / 18,359
dom 节点18dom 深度6
css 规则60含 js
brightness22.3contrast9.9
colorfulness15.2留白97.8%

该 slot 的 telemetry

prompt tokens312completion tokens8,141
total tokens8,453wall113.9 s
costrequest id
config.json559 B
{
  "N": 4,
  "auth": {
    "credential_ref": "WCB_BIGMODEL_KEY",
    "method": "api-key"
  },
  "billing": "metered",
  "config_id": "glm-5.1-eff-disabled--api--official--dev",
  "effort": "disabled",
  "family": "glm",
  "m": {
    "min": 4,
    "q": 4
  },
  "model_id": "glm-5.1",
  "protocol": "api",
  "served_model": "glm-5.1",
  "telemetry": {
    "completion_tokens": 40267,
    "cost_usd": null,
    "prompt_tokens": 2464,
    "total_tokens": 42731,
    "wall_ms": 585451
  },
  "transport": "bigmodel-openai-compat",
  "vendor_sanction_ref": null
}
send-log4.6 KB
{
  "N": 4,
  "batch_id": "2026-07-20--official-glm",
  "config_id": "glm-5.1-eff-disabled--api--official--dev",
  "positions": [
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-07-20T12:54:50.723731+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T12:53:30.985805+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-07-20T12:56:50.650999+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T12:54:56.787514+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-07-20T12:58:09.299208+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T12:56:56.755761+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": null,
          "charged": true,
          "ended_at": "2026-07-20T12:59:02.591002+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T12:58:12.496425+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-07-20T13:00:57.060330+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T12:59:05.733436+00:00"
        }
      ],
      "block_index": 2,
      "model_reaching_attempt_index": 0,
      "slot_index": 2,
      "terminal_state": "valid",
      "variant": "P-q"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-07-20T13:01:45.960336+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T13:01:00.312696+00:00"
        }
      ],
      "block_index": 2,
      "model_reaching_attempt_index": 0,
      "slot_index": 2,
      "terminal_state": "valid",
      "variant": "P-min"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-07-20T13:02:38.873722+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T13:01:49.798252+00:00"
        }
      ],
      "block_index": 3,
      "model_reaching_attempt_index": 0,
      "slot_index": 3,
      "terminal_state": "valid",
      "variant": "P-min"
    },
    {
      "attempts": [
        {
          "attempt_index": 0,
          "backoff_ms": null,
          "charged": true,
          "ended_at": "2026-07-20T13:03:45.859113+00:00",
          "http_status": 200,
          "outcome": "valid",
          "reached_model": true,
          "reason": "ok",
          "request_id": null,
          "started_at": "2026-07-20T13:02:42.700390+00:00"
        }
      ],
      "block_index": 3,
      "model_reaching_attempt_index": 0,
      "slot_index": 3,
      "terminal_state": "valid",
      "variant": "P-q"
    }
  ],
  "retry_policy": {
    "max_unreachable_retries": 5,
    "rate_limit_backoff": {
      "max_attempts": 4,
      "max_total_ms": 60000
    }
  }
}