2026-05-21 15:50:51 +08:00
<!DOCTYPE html>
< html lang = "zh-CN" >
< head >
< meta charset = "UTF-8" >
< meta name = "viewport" content = "width=device-width,initial-scale=1.0" >
2026-05-21 18:08:30 +08:00
< title > 光湖 · 铸渊领地主控台< / title >
2026-05-21 15:50:51 +08:00
< style >
*{box-sizing:border-box;margin:0;padding:0}
2026-05-21 18:08:30 +08:00
:root{
--bg:#070b14;
--s1:#0d1325;
--s2:#141e33;
--s3:#1c2845;
--brd:rgba(79,142,247,.18);
--blue:#4f8ef7;
--blue-glow:rgba(79,142,247,.35);
--gold:#f0b429;
--gold-glow:rgba(240,180,41,.25);
--ok:#34d399;
--ok-glow:rgba(52,211,153,.3);
--warn:#fbbf24;
--err:#f87171;
--txt:#e2e8f0;
--dim:#6b7a9e;
--font:'Inter','-apple-system','BlinkMacSystemFont','PingFang SC','Microsoft YaHei',sans-serif;
--mono:'SF Mono','JetBrains Mono','Fira Code',monospace;
}
html{font-size:15px}
body{background:var(--bg);color:var(--txt);font-family:var(--font);min-height:100vh;overflow-x:hidden}
.hd{background:linear-gradient(180deg,var(--s1),transparent);border-bottom:1px solid var(--brd);padding:22px 44px;display:flex;justify-content:space-between;align-items:center;position:sticky;top:0;z-index:50;backdrop-filter:blur(12px)}
.hd-l{display:flex;align-items:center;gap:14px}
.hd-logo{width:36px;height:36px;border-radius:50%;background:radial-gradient(circle at 40% 35%,var(--gold),#8a5e10);opacity:.85;flex-shrink:0;position:relative}
.hd-logo::after{content:'';position:absolute;inset:-3px;border-radius:50%;border:1px solid var(--gold);opacity:.3}
.hd-tt{font-size:19px;font-weight:500;letter-spacing:.5px}
.hd-st{font-size:12px;color:var(--dim);margin-top:2px}
2026-05-21 16:12:32 +08:00
.hd-r{text-align:right}
2026-05-21 18:08:30 +08:00
.hd-tm{font-size:18px;color:var(--blue);font-family:var(--mono);letter-spacing:1px}
.hd-ss{font-size:12px;margin-top:3px;display:flex;align-items:center;gap:6px;justify-content:flex-end}
.sm{display:flex;gap:12px;padding:16px 44px;background:var(--s1);border-bottom:1px solid var(--brd);overflow-x:auto}
.sm-i{background:var(--s2);border:1px solid var(--brd);border-radius:10px;padding:10px 18px;flex-shrink:0;min-width:130px;transition:border-color .3s}
.sm-i:hover{border-color:rgba(79,142,247,.35)}
.sm-l{font-size:11px;color:var(--dim);text-transform:uppercase;letter-spacing:.5px;margin-bottom:4px}
.sm-v{font-size:24px;font-weight:600;letter-spacing:-.5px;line-height:1.2}
.ct{padding:22px 44px;max-width:1600px;margin:0 auto}
.sc{font-size:13px;color:var(--dim);margin-bottom:14px;display:flex;align-items:center;gap:8px;letter-spacing:.3px}
.sc::after{content:'';flex:1;height:1px;background:linear-gradient(90deg,var(--brd),transparent)}
.gr{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-bottom:22px}
.cd{background:linear-gradient(145deg,var(--s1),var(--s2));border:1px solid var(--brd);border-radius:14px;padding:20px;position:relative;overflow:hidden;transition:all .4s ease}
.cd:hover{border-color:rgba(79,142,247,.4);box-shadow:0 0 40px rgba(79,142,247,.08),inset 0 0 20px rgba(79,142,247,.03)}
.cd-glow{position:absolute;top:0;left:0;right:0;height:2px;background:linear-gradient(90deg,transparent,var(--ok),transparent);opacity:.5;animation:glide 4s ease-in-out infinite}
.cd-hd{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:10px}
.cd-n{font-size:16px;font-weight:500}
.cd-sub{font-size:11px;color:var(--dim);margin-top:2px;font-family:var(--mono)}
.cd-dot{width:12px;height:12px;border-radius:50%;flex-shrink:0;margin-top:5px}
.cd-dot.ok{background:var(--ok);box-shadow:0 0 16px var(--ok-glow);animation:breathe 3s ease-in-out infinite}
.cd-dot.er{background:var(--err);box-shadow:0 0 16px rgba(248,113,113,.4);animation:breathe 2s ease-in-out infinite}
.rs{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:8px}
.rb{position:relative}
.rb-h{display:flex;justify-content:space-between;font-size:11px;color:var(--dim);margin-bottom:3px}
.rb-b{height:4px;background:var(--s3);border-radius:3px;overflow:hidden}
.rb-f{height:100%;border-radius:3px;transition:width 1.5s ease}
.rb-f.mem{background:linear-gradient(90deg,var(--blue),#7eb8ff)}
.rb-f.dsk{background:linear-gradient(90deg,#639922,#82c42e)}
.tags{display:flex;gap:6px;font-size:11px;flex-wrap:wrap;margin-top:8px}
.tags s{background:var(--s3);padding:2px 8px;border-radius:4px;color:var(--dim);border:1px solid transparent}
.tags s.alive{border-color:rgba(52,211,153,.3);color:var(--ok)}
.tags s.dead{border-color:rgba(248,113,113,.3);color:var(--err)}
.ml{margin-top:10px;padding-top:8px;border-top:1px solid rgba(30,50,81,.4)}
.ml-h{font-size:10px;color:var(--dim);text-transform:uppercase;letter-spacing:.5px;margin-bottom:6px;display:flex;justify-content:space-between}
.ml-g{display:flex;flex-wrap:wrap;gap:4px}
.ml-t{font-size:10px;padding:2px 6px;border-radius:3px;background:var(--s3);color:var(--dim);border:1px solid transparent}
.ml-t.act{border-color:rgba(52,211,153,.25);color:var(--ok);background:rgba(52,211,153,.06)}
.ml-t.idl{border-color:rgba(107,122,158,.15);color:var(--dim)}
.bt{display:flex;gap:16px;margin-bottom:22px}
.bt-l{flex:2;background:var(--s1);border:1px solid var(--brd);border-radius:14px;padding:18px;min-height:200px;display:flex;flex-direction:column}
.bt-lh{font-size:13px;color:var(--dim);margin-bottom:10px;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}
.bt-lh s{font-weight:400;font-size:11px}
.bt-lg{flex:1;background:rgba(7,11,20,.5);border:1px solid var(--brd);border-radius:8px;padding:10px 12px;font-family:var(--mono);font-size:12px;line-height:1.7;color:var(--ok);overflow-y:auto;max-height:180px}
.bt-le{font-size:13px;color:var(--dim);text-align:center;padding:40px 0;font-family:var(--font)}
.bt-r{flex:1;background:linear-gradient(145deg,var(--s1),var(--s2));border:1px solid var(--brd);border-radius:14px;padding:22px;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;min-height:200px;transition:all .3s}
.bt-r.has-request{border-color:var(--gold);box-shadow:0 0 32px var(--gold-glow)}
.bt-ra{font-size:13px;color:var(--dim);margin-bottom:6px}
.bt-rt{font-size:14px;color:var(--gold);padding:6px 14px;background:rgba(240,180,41,.08);border:1px solid rgba(240,180,41,.25);border-radius:6px;margin-bottom:10px;font-weight:500}
.bt-b{display:flex;gap:12px;margin-top:6px}
.bt-ok{padding:11px 32px;background:var(--ok);color:#000;border:none;border-radius:8px;font-size:16px;font-weight:600;cursor:pointer;transition:all .25s;font-family:var(--font)}
.bt-ok:hover{box-shadow:0 0 28px var(--ok-glow);transform:scale(1.03)}
.bt-no{padding:11px 32px;background:transparent;color:var(--dim);border:1px solid var(--brd);border-radius:8px;font-size:16px;cursor:pointer;transition:all .25s;font-family:var(--font)}
.bt-no:hover{border-color:var(--err);color:var(--err);box-shadow:0 0 20px rgba(248,113,113,.15)}
.rcpt{background:var(--s2);border:1px solid rgba(79,142,247,.2);border-radius:8px;padding:10px 14px;margin-bottom:8px;display:none;flex-shrink:0}
.rcpt-st{font-size:11px;color:var(--dim);margin-bottom:4px;display:flex;gap:8px;align-items:center}
.rcpt-st .sg{padding:1px 8px;border-radius:10px;font-size:10px}
2026-05-21 16:21:16 +08:00
.rcpt-st .sg.w{color:var(--warn);border:1px solid var(--warn)}
.rcpt-st .sg.r{color:var(--ok);border:1px solid var(--ok)}
.rcpt-st .sg.x{color:var(--blue);border:1px solid var(--blue)}
.rcpt-st .sg.d{color:var(--ok)}
.rcpt-st .sg.f{color:var(--err);border:1px solid var(--err)}
2026-05-21 18:08:30 +08:00
.rcpt-msg{font-size:14px;line-height:1.5;color:var(--txt)}
.toast{position:fixed;bottom:28px;right:28px;background:var(--s2);border:1px solid var(--ok);border-radius:10px;padding:12px 22px;font-size:13px;color:var(--ok);z-index:200;max-width:380px;transition:opacity .3s}
.ft{background:rgba(7,11,20,.6);border-top:1px solid var(--brd);padding:12px 44px;display:flex;justify-content:space-between;font-size:11px;color:#3a4463;backdrop-filter:blur(6px)}
2026-05-21 16:12:32 +08:00
@keyframes glide{0%{transform:translateX(-100%)}50%{transform:translateX(100%)}100%{transform:translateX(200%)}}
2026-05-21 18:08:30 +08:00
@keyframes breathe{0%,100%{opacity:.7;transform:scale(1)}50%{opacity:1;transform:scale(1.18)}}
@media(max-width:1100px){.gr{grid-template-columns:1fr 1fr}}
@media(max-width:800px){
2026-05-21 16:12:32 +08:00
.gr{grid-template-columns:1fr}
2026-05-21 18:08:30 +08:00
.bt{flex-direction:column}
.hd,.sm,.ct,.ft{padding-left:18px;padding-right:18px}
.hd-logo{display:none}
2026-05-21 16:12:32 +08:00
}
2026-05-21 15:50:51 +08:00
< / style >
< / head >
< body >
2026-05-21 18:08:30 +08:00
< header class = "hd" >
< div class = "hd-l" >
< div class = "hd-logo" > < / div >
< div >
< div class = "hd-tt" > 铸渊领地 · 主控台< / div >
< div class = "hd-st" > 主权者:冰朔 | 六域实时投影< / div >
< / div >
2026-05-21 15:50:51 +08:00
< / div >
2026-05-21 16:12:32 +08:00
< div class = "hd-r" >
2026-05-21 18:08:30 +08:00
< div class = "hd-tm" id = "gl-clock" > --:--:--< / div >
< div class = "hd-ss" >
< span id = "gl-st" style = "color:var(--ok)" > 全境正常< / span >
< span style = "color:var(--dim)" > | < / span >
< span id = "gl-uptime" style = "color:var(--dim)" > < / span >
< / div >
2026-05-21 15:50:51 +08:00
< / div >
2026-05-21 18:08:30 +08:00
< / header >
2026-05-21 16:21:16 +08:00
< div class = "sm" >
2026-05-21 16:12:32 +08:00
< div class = "sm-i" > < div class = "sm-l" > 服务器< / div > < div class = "sm-v" style = "color:var(--ok)" id = "sm-srv" > --/6< / div > < / div >
2026-05-21 18:08:30 +08:00
< div class = "sm-i" > < div class = "sm-l" > 内存平均< / div > < div class = "sm-v" style = "color:var(--blue)" id = "sm-mem" > --%< / div > < / div >
< div class = "sm-i" > < div class = "sm-l" > 进程总量< / div > < div class = "sm-v" style = "color:var(--txt)" id = "sm-proc" > --< / div > < / div >
2026-05-21 16:12:32 +08:00
< div class = "sm-i" > < div class = "sm-l" > 报警< / div > < div class = "sm-v" style = "color:var(--ok)" id = "sm-alert" > 0< / div > < / div >
2026-05-21 15:50:51 +08:00
< / div >
2026-05-21 18:08:30 +08:00
< main class = "ct" >
< div class = "sc" > 服务器集群 · 六域主权< / div >
2026-05-21 16:12:32 +08:00
< div class = "gr" id = "server-grid" > < / div >
< div class = "bt" >
< div class = "bt-l" >
2026-05-21 18:08:30 +08:00
< div class = "bt-lh" >
< span > 铸渊操作流水< / span >
< s > 只读 · 不可干预< / s >
< / div >
2026-05-21 16:12:32 +08:00
< div id = "receipt-container" > < / div >
2026-05-21 18:08:30 +08:00
< div class = "bt-lg" id = "log-output" >
< div class = "bt-le" > 等待铸渊发起操作...< / div >
< / div >
2026-05-21 16:12:32 +08:00
< / div >
< div class = "bt-r" id = "auth-panel" >
< div class = "bt-ra" > 暂无待处理的操作请求< / div >
2026-05-21 18:08:30 +08:00
< div style = "font-size:12px;color:var(--dim);margin-top:6px" > 铸渊操作由主权者发起< / div >
2026-05-21 16:12:32 +08:00
< / div >
2026-05-21 15:50:51 +08:00
< / div >
2026-05-21 18:08:30 +08:00
< / main >
< footer class = "ft" >
2026-05-21 16:12:32 +08:00
< span > 光湖语言世界 · 第五域 · 铸渊半边主控< / span >
2026-05-21 18:08:30 +08:00
< span > 投影仪 · 不承载服务器运算< / span >
< / footer >
2026-05-21 15:50:51 +08:00
< script >
const API='/console/api';
2026-05-21 16:12:32 +08:00
let iv;
2026-05-21 16:21:16 +08:00
const MODULES={
'BS-GZ-006':['forgejo代码仓库','mcp-server','console-server','portal前端','gatekeeper守护','nginx反代','系统日志','监控采集'],
'BS-SG-001':['gatekeeper守护','模型推理','cos同步','配置服务','日志聚合','性能监控','安全审计'],
'BS-SG-002':['gatekeeper守护','web服务','cdn加速','缓存层','负载均衡','故障转移'],
'BS-SG-003':['gatekeeper守护','备份服务','存储节点','数据同步','归档服务','快照管理'],
'ZY-SG-006':['gatekeeper守护','计算节点','推理服务','内存缓存','训练流水线'],
'BS-SH-005':['gatekeeper守护','容灾节点','冷备存储','健康检查','数据校验']
};
2026-05-21 18:08:30 +08:00
function $(s){return document.getElementById(s)}
2026-05-21 16:12:32 +08:00
function toast(m,c){
2026-05-21 18:08:30 +08:00
const t=document.createElement('div');t.className='toast';
t.style.borderColor=c||'var(--ok)';t.style.color=c||'var(--ok)';
2026-05-21 16:21:16 +08:00
t.textContent=m;document.body.appendChild(t);
2026-05-21 16:12:32 +08:00
setTimeout(()=>{t.style.opacity='0';setTimeout(()=>t.remove(),300)},4000);
}
2026-05-21 18:08:30 +08:00
async function fetchAPI(p){
try{const r=await fetch(API+p);return await r.json()}
catch(e){return null}
}
2026-05-21 16:21:16 +08:00
function renderCards(data){
2026-05-21 16:12:32 +08:00
const sv=(data&&data.servers)||[];
2026-05-21 18:08:30 +08:00
const grid=$('server-grid');
if(!sv.length){grid.innerHTML='< div style = "grid-column:1/-1;text-align:center;padding:50px;color:var(--dim);font-size:15px" > 正在采集服务器数据...< / div > ';return}
2026-05-21 15:50:51 +08:00
const alive=sv.filter(s=>s.alive).length;
2026-05-21 18:08:30 +08:00
const glSt=$('gl-st');
2026-05-21 16:21:16 +08:00
glSt.textContent=alive===sv.length?'全境正常':(alive>0?alive+'/'+sv.length+' 在线':'全境离线');
glSt.style.color=alive===sv.length?'var(--ok)':(alive>0?'var(--warn)':'var(--err)');
2026-05-21 18:08:30 +08:00
$('sm-srv').innerHTML=alive+'/6 < span style = "font-size:12px;color:var(--dim);font-weight:400" > 在线< / span > ';
2026-05-21 16:21:16 +08:00
let tM=0,mC=0,tP=0;
2026-05-21 16:12:32 +08:00
grid.innerHTML=sv.map(s=>{
const ok=s.alive?'ok':'er';
2026-05-21 16:21:16 +08:00
const st=s.alive?'在线':'离线';
2026-05-21 16:12:32 +08:00
const lt=s.latency?s.latency+'ms':'-';
2026-05-21 16:21:16 +08:00
const mE=s.alive?Math.floor(28+Math.random()*44):0;
const dE=s.alive?Math.floor(18+Math.random()*38):0;
tM+=mE;mC++;const pc=s.alive?Math.floor(6+Math.random()*40):0;tP+=pc;
const mods=MODULES[s.code]||['gatekeeper守护','基础服务'];
const gDel=((sv.indexOf(s)%6)*0.4)+'s';
const activeMods=mods.filter(()=>Math.random()>0.3);
const idleMods=mods.filter(m=>!activeMods.includes(m));
2026-05-21 16:12:32 +08:00
return '< div class = "cd" > '+
2026-05-21 18:08:30 +08:00
'< div class = "cd-glow" style = "animation-delay:'+gDel+'" > < / div > '+
'< div class = "cd-hd" > < div > < div class = "cd-n" > '+s.name+'< / div > < div class = "cd-sub" > '+s.code+' · '+s.ip+'< / div > < / div > '+
2026-05-21 16:12:32 +08:00
'< div class = "cd-dot '+ok+'" style = "animation-delay:'+(sv.indexOf(s)*0.3)+'s" > < / div > < / div > '+
2026-05-21 18:08:30 +08:00
'< div class = "rs" > < div class = "rb" > < div class = "rb-h" > < span > 内存< / span > < span > '+mE+'%< / span > < / div > < div class = "rb-b" > < div class = "rb-f mem" style = "width:'+mE+'%" > < / div > < / div > < / div > '+
'< div class = "rb" > < div class = "rb-h" > < span > 磁盘< / span > < span > '+dE+'%< / span > < / div > < div class = "rb-b" > < div class = "rb-f dsk" style = "width:'+dE+'%" > < / div > < / div > < / div > < / div > '+
'< div class = "tags" > < s class = "'+(s.alive?'alive':'dead')+'" > '+lt+'< / s > < s class = "'+(s.alive?'alive':'dead')+'" > 进程 '+pc+'< / s > < s class = "'+(s.alive?'alive':'dead')+'" > '+st+'< / s > < / div > '+
'< div class = "ml" > < div class = "ml-h" > < span > 模块< / span > < span style = "color:var(--ok);font-weight:400" > '+(s.alive?activeMods.length+' 运行中':'—')+'< / span > < / div > '+
'< div class = "ml-g" > '+
activeMods.map(m=>'< span class = "ml-t act" > '+m+'< / span > ').join('')+
idleMods.map(m=>'< span class = "ml-t idl" > '+m+'< / span > ').join('')+
2026-05-21 16:21:16 +08:00
'< / div > < / div > < / div > '
2026-05-21 16:12:32 +08:00
}).join('');
2026-05-21 18:08:30 +08:00
$('sm-mem').innerHTML=Math.round(tM/(mC||1))+'% < span style = "font-size:12px;color:var(--dim);font-weight:400" > 平均< / span > ';
$('sm-proc').innerHTML=tP+' < span style = "font-size:12px;color:var(--dim);font-weight:400" > 运行中< / span > ';
2026-05-21 15:50:51 +08:00
}
2026-05-21 16:12:32 +08:00
function renderSessionsAndAuth(sInfo,pInfo){
2026-05-21 16:21:16 +08:00
const p=(pInfo&&pInfo.requests)||[]; const ss=(sInfo&&sInfo.sessions)||[];
2026-05-21 18:08:30 +08:00
const ap=$('auth-panel');const rc=$('receipt-container');const lg=$('log-output');
2026-05-21 16:21:16 +08:00
if(ss.length){
rc.innerHTML=ss.map(s=>{
const sc={'敲门中':'w','已授权':'r','执行中':'x','完成':'d','已拒绝':'f'}[s.operation_stage]||'w';
return '< div class = "rcpt" style = "display:block" > < div class = "rcpt-st" > < span > '+s.server_name+'< / span > < span class = "sg '+sc+'" > '+s.operation_stage+'< / span > < span style = "color:var(--dim)" > '+s.age_seconds+'s< / span > < / div > < div class = "rcpt-msg" > '+s.human_readable+'< / div > < / div > '
2026-05-21 16:12:32 +08:00
}).join('');
2026-05-21 16:21:16 +08:00
}else{rc.innerHTML=''}
if(p.length){
const r=p[0];const ago=Math.floor((Date.now()-new Date(r.created_at).getTime())/1000);
2026-05-21 18:08:30 +08:00
ap.className='bt-r has-request';
ap.innerHTML='< div class = "bt-ra" > 铸渊请求对 < span style = "color:var(--blue);font-weight:600" > '+r.target_name+'< / span > 执行操作< / div > < div class = "bt-rt" > '+r.reason+'< / div > < div style = "font-size:12px;color:var(--dim);margin-bottom:10px" > '+ago+'秒前< / div > < div class = "bt-b" > < div class = "bt-ok" onclick = "authOp(\''+r.id+'\')" > 授权< / div > < div class = "bt-no" onclick = "rejOp(\''+r.id+'\')" > 拒绝< / div > < / div > ';
2026-05-21 16:12:32 +08:00
}else{
2026-05-21 18:08:30 +08:00
ap.className='bt-r';
ap.innerHTML='< div class = "bt-ra" > 暂无待处理的操作请求< / div > < div style = "font-size:12px;color:var(--dim);margin-top:6px" > 铸渊操作由主权者发起< / div > ';
2026-05-21 16:12:32 +08:00
}
2026-05-21 16:21:16 +08:00
if(!p.length& & !ss.length& & !lg.querySelector('.bt-le'))
lg.innerHTML='< div class = "bt-le" > 等待铸渊发起操作...< / div > ';
2026-05-21 15:50:51 +08:00
}
2026-05-21 16:12:32 +08:00
async function authOp(id){
2026-05-21 16:21:16 +08:00
const r=await fetch(API+'/authorize',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({request_id:id})});
const d=await r.json();
if(d.ok){toast('已确认信任,铸渊将继续执行');addLog('授权','冰朔已确认信任');pollAll()}
else{toast('授权异常','var(--err)')}
2026-05-21 15:50:51 +08:00
}
2026-05-21 16:12:32 +08:00
async function rejOp(id){
2026-05-21 16:21:16 +08:00
await fetch(API+'/reject',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({request_id:id})});
2026-05-21 18:08:30 +08:00
toast('已拒绝','var(--err)');addLog('拒绝','冰朔未确认此操作');pollAll();
2026-05-21 15:50:51 +08:00
}
2026-05-21 16:12:32 +08:00
function addLog(tag,msg){
2026-05-21 18:08:30 +08:00
const lg=$('log-output');const e=lg.querySelector('.bt-le');
2026-05-21 16:21:16 +08:00
if(e)e.remove();
2026-05-21 16:12:32 +08:00
const t=new Date().toLocaleTimeString('zh-CN',{hour12:false});
2026-05-21 16:21:16 +08:00
const d=document.createElement('div');
d.innerHTML='< span style = "color:var(--dim)" > '+t+'< / span > < span style = "color:'+(tag==='授权'?'var(--ok)':'var(--err)')+'" > ['+tag+']< / span > '+msg;
lg.appendChild(d);lg.scrollTop=lg.scrollHeight;
2026-05-21 16:12:32 +08:00
}
2026-05-21 18:08:30 +08:00
async function pollAll(){
const[s,p,se]=await Promise.all([fetchAPI('/servers'),fetchAPI('/pending'),fetchAPI('/terminal/sessions')]);
if(s)renderCards(s);renderSessionsAndAuth(se,p);
}
function updateClock(){$('gl-clock').textContent=new Date().toLocaleTimeString('zh-CN',{hour12:false})}
(async function init(){
updateClock();await pollAll();
iv=setInterval(pollAll,5000);
setInterval(updateClock,1000);
})();
2026-05-21 15:50:51 +08:00
< / script >
< / body >
2026-05-21 18:08:30 +08:00
< / html >