opencode-claude-code-ua 0.0.0-stage → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,75 @@
1
+ /* 基础层:本页自带主题变量、基础元素与共用控件,不再依赖已退场的 ui/styles.css。 */
2
+ :root{color-scheme:light;--ink:#171717;--muted:#525252;--canvas:#ffffff;--paper:#ffffff;--panel:#f7f7f7;--line:#e5e5e5;--accent:#b45a3c;--accent-soft:#faf0eb;--blue:#b45a3c;--soft:#faf0eb;--positive:#28654d;--negative:#b13c45;--success:#28654d;--error:#b13c45;--danger:#b13c45;--error-bg:#fff5f5;--error-border:#e8c9cc;--warning-bg:#fffaf0;--warning-border:#e7d8b8;--warning-ink:#795516;--input:#ffffff;--input-border:#d4d4d4;--placeholder:#737373;--focus:#b45a3c;--focus-ring:#b45a3c33;--button:#b45a3c;--button-hover:#96472e;--button-ink:#ffffff;--brand-bg:#3b2b24;--brand-ink:#ffffff;--table-head:#f5f5f5;--shadow:#0000001f;--backdrop:#00000066}
3
+ :root[data-theme=dark],:root:not([data-theme=light]){color-scheme:dark;--ink:#ededed;--muted:#a3a3a3;--canvas:#000000;--paper:#000000;--panel:#0d0d0d;--line:#262626;--accent:#e6a184;--accent-soft:#241813;--blue:#e6a184;--soft:#241813;--positive:#8fd4b5;--negative:#f0a4ad;--success:#8fd4b5;--error:#f0a4ad;--danger:#f0a4ad;--error-bg:#1a0f11;--error-border:#5a353b;--warning-bg:#1a1409;--warning-border:#5e4d2e;--warning-ink:#e3c286;--input:#0d0d0d;--input-border:#333333;--placeholder:#8f8f8f;--focus:#e6a184;--focus-ring:#e6a18440;--button:#9a5236;--button-hover:#ac6244;--button-ink:#ffffff;--brand-bg:#3b2b24;--brand-ink:#ffffff;--table-head:#0d0d0d;--shadow:#000000cc;--backdrop:#000000cc}
4
+ *,*::before,*::after{box-sizing:border-box}
5
+ [hidden]{display:none!important}
6
+ body{margin:0;min-height:100vh;overflow-x:clip;background:var(--canvas);color:var(--ink);font-family:\"Segoe UI\",\"Microsoft YaHei\",sans-serif;font-synthesis:none;font-size:14px;line-height:1.6}
7
+ h1,h2,h3,p{margin-top:0}
8
+ h1{margin-bottom:8px;font-size:25px;line-height:1.25;letter-spacing:-.3px}
9
+ h2{margin-bottom:10px;font-size:17px;line-height:1.35}
10
+ p{margin-bottom:10px;line-height:1.65}
11
+ a{color:var(--accent);text-underline-offset:2px}
12
+ a:hover{color:var(--button-hover)}
13
+ nav{display:flex;flex-direction:column;gap:4px;margin:0 0 16px}
14
+ nav a{display:inline-flex;align-items:center;padding:6px 10px;border-radius:6px;color:var(--muted);font-size:13px;text-decoration:none}
15
+ nav a:hover{background:var(--panel);color:var(--ink)}
16
+ nav a[aria-current=page]{color:var(--accent);font-weight:600}
17
+ .brand{display:inline-flex;align-items:center;gap:12px;color:var(--ink);font-size:13px;line-height:1.35;text-decoration:none}
18
+ .brand strong{font-weight:650}
19
+ .brand-icon{flex:none;width:44px;height:44px;border-radius:11px;background:var(--brand-bg)}
20
+ .theme-control{display:inline-flex;flex:none;align-items:center;gap:8px;color:var(--muted);font-size:12px}.theme-control label{white-space:nowrap}
21
+ :focus-visible{outline:2px solid var(--focus);outline-offset:2px}
22
+ button{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:36px;padding:8px 13px;border:1px solid var(--line);border-radius:7px;background:var(--input);color:var(--ink);font:inherit;font-size:13px;font-weight:550;cursor:pointer;text-decoration:none;transition:background-color .15s ease,border-color .15s ease,color .15s ease}
23
+ button:hover:not(:disabled){border-color:var(--input-border);background:var(--accent-soft);color:var(--accent)}
24
+ button:disabled{opacity:.48;cursor:not-allowed}
25
+ .primary{border-color:var(--button);background:var(--button);color:var(--button-ink);font-weight:650}
26
+ .primary:hover:not(:disabled){border-color:var(--button-hover);background:var(--button-hover);color:var(--button-ink)}
27
+ .secondary{border-color:var(--line);background:transparent;color:var(--ink)}
28
+ .secondary:hover:not(:disabled){border-color:var(--input-border);background:var(--accent-soft);color:var(--accent)}
29
+ input,select,textarea{font:inherit;color:var(--ink)}
30
+ input:not([type=checkbox]):not([type=radio]),select,textarea{width:100%;min-width:0;min-height:38px;padding:9px 11px;border:1px solid var(--input-border);border-radius:6px;background:var(--input);font-size:13px;line-height:1.4}
31
+ input::placeholder,textarea::placeholder{color:var(--placeholder)}
32
+ input:not([type=checkbox]):not([type=radio]):focus,select:focus,textarea:focus{border-color:var(--accent);outline:none;box-shadow:0 0 0 3px var(--focus-ring)}
33
+ input[type=checkbox]{flex:none;width:16px;height:16px;margin:0;accent-color:var(--accent);cursor:pointer}
34
+ fieldset{min-width:0;margin:0;padding:0;border:0}
35
+ .field{display:flex;flex-direction:column;gap:6px;margin-bottom:14px}
36
+ .field label{color:var(--muted);font-size:12px;font-weight:600}
37
+ .field-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(190px,1fr));gap:0 16px;margin-top:18px}
38
+ .hint{margin:4px 0;color:var(--muted);font-size:12px;line-height:1.5}
39
+ .check-label{display:inline-flex;align-items:center;gap:7px;color:var(--muted);font-size:12px;cursor:pointer}
40
+ .secret-meta{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px 16px}
41
+ .completion{max-width:520px;margin:0 auto;padding:72px 24px;text-align:center}
42
+ .completion-icon{display:flex;align-items:center;justify-content:center;width:56px;height:56px;margin:0 auto 18px;border-radius:50%;background:var(--accent-soft);color:var(--accent);font-size:24px;font-weight:700}
43
+ .completion h1{font-size:21px}
44
+ .completion p{margin:0;color:var(--muted);font-size:13px}
45
+ .accounts-shell{max-width:1480px;margin:auto;min-height:100vh}.accounts-header{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:24px 40px;background:var(--paper);border-bottom:1px solid var(--line)}.accounts-header nav{flex-direction:row;gap:10px;margin:0}.accounts-header a[aria-current=page]{background:var(--soft);color:var(--blue)}.accounts-main{padding:42px 40px}.accounts-title{display:flex;justify-content:space-between;align-items:center;gap:24px;margin-bottom:28px}.accounts-title p{font-size:14px;color:var(--muted);margin:0}.account-totals{display:flex;flex-wrap:wrap;gap:16px;margin-bottom:26px}.unit-total{flex:1;min-width:250px;border-left:3px solid var(--blue);padding:12px 20px;background:var(--paper)}.unit-total h2{font-size:14px;margin-bottom:12px}.unit-total .total-values{display:flex;gap:32px;flex-wrap:wrap}.total-metric small{display:block;color:var(--muted);font-size:12px;margin-bottom:5px}.total-metric strong{font-size:24px;font-weight:650;font-variant-numeric:tabular-nums}.unit-total p{font-size:11px;color:var(--muted);margin:12px 0 0}.account-toolbar{display:flex;justify-content:space-between;align-items:center;gap:20px;margin:22px 0 14px}.account-toolbar p{font-size:12px;color:var(--muted);margin:0}.account-toolbar>div{display:flex;gap:10px}.account-table-scroll,.history-scroll{overflow:auto;border:1px solid var(--line);border-radius:8px;background:var(--paper)}table{border-collapse:collapse;width:100%;text-align:left}th{background:var(--table-head);font-size:12px;font-weight:600;color:var(--muted);padding:14px 16px;white-space:nowrap}td{padding:20px 16px;border-top:1px solid var(--line);font-size:13px;vertical-align:top;line-height:1.6}td .primary-value{font-weight:650;font-variant-numeric:tabular-nums;white-space:nowrap;font-size:15px}td .detail{font-size:11px;color:var(--muted);max-width:260px;overflow-wrap:anywhere;margin-top:5px}td .positive{color:var(--positive)}td .negative{color:var(--negative)}.row-actions{display:flex;flex-wrap:wrap;gap:5px;min-width:162px;max-width:240px}.row-actions button{font-size:11px;padding:5px 9px;min-height:30px}.row-actions .danger{color:var(--error)}.account-state{display:inline-block;border-radius:4px;padding:2px 6px;background:var(--soft);font-size:10px;color:var(--blue);margin-top:5px}.account-state.stale{color:var(--warning-ink);background:var(--warning-bg)}.account-notes{max-width:950px;margin-top:20px}.account-notes p{font-size:12px;color:var(--muted);margin-bottom:6px}.account-empty{padding:48px 24px;text-align:center;background:var(--paper);border:1px dashed var(--input-border);border-radius:8px;margin:24px 0}.account-empty h2{font-size:20px}.account-empty p{font-size:13px;color:var(--muted);max-width:540px;margin:0 auto}.accounts-error{margin-bottom:18px;padding:12px 15px;border:1px solid var(--error-border);background:var(--error-bg);color:var(--error);border-radius:6px;font-size:13px;line-height:1.7}dialog{width:min(640px,calc(100% - 32px));max-height:90vh;overflow:auto;border:1px solid var(--line);border-radius:12px;padding:26px;color:var(--ink);background:var(--paper);box-shadow:0 24px 80px var(--shadow)}dialog::backdrop{background:var(--backdrop)}.dialog-header{display:flex;justify-content:space-between;align-items:flex-start;gap:20px;margin-bottom:22px}.dialog-header h2{margin:0 0 8px}.dialog-header p{font-size:12px;color:var(--muted);margin:0}.dialog-header button{min-height:32px;padding:4px 12px}.dialog-footer{display:flex;align-items:center;justify-content:space-between;gap:20px;border-top:1px solid var(--line);padding-top:18px;margin-top:24px}.dialog-footer p{margin:0;max-width:320px}.account-toggles{display:flex;flex-direction:column;gap:12px}.dialog-footer button{white-space:nowrap}#account-history{width:min(950px,calc(100% - 32px))}.history-scroll{max-height:55vh}.history-scroll td,.history-scroll th{font-size:12px;white-space:nowrap;padding:12px}.accounts-error:focus{outline:2px solid var(--error);outline-offset:3px}
46
+ .account-schedule{border:1px solid var(--line);border-radius:8px;background:var(--canvas);padding:16px;margin-top:20px}.account-schedule .field-grid{margin-top:18px}.account-schedule .field{margin-bottom:8px}
47
+ @media(max-width:900px){.accounts-header{padding:20px}.accounts-main{padding:30px 20px}.accounts-title{align-items:flex-start}.accounts-header .brand{display:none}.account-totals{gap:12px}.account-toolbar{align-items:flex-start;flex-direction:column}.account-toolbar>div{flex-wrap:wrap}}
48
+ @media(max-width:560px){.accounts-header{gap:10px;padding:15px;flex-wrap:wrap}.accounts-header nav{flex-basis:100%}.accounts-header .theme-control{margin-right:auto}.accounts-header nav a{padding:8px;font-size:12px}.accounts-header>button{font-size:11px;padding:8px}.accounts-main{padding:26px 15px}.accounts-title{flex-direction:column;gap:16px}.accounts-title h1{font-size:24px}.accounts-title p{font-size:12px}.account-totals{flex-direction:column}.unit-total{min-width:0}.account-table-scroll table{min-width:1000px}dialog{padding:20px}.dialog-footer{flex-direction:column;align-items:stretch}.dialog-footer button{width:100%}.accounts-header nav{overflow:visible}}
49
+ .accounts-shell button,#account-editor button,#account-history button,.accounts-header nav a{min-height:44px;display:inline-flex;align-items:center;justify-content:center}
50
+ .accounts-header select{min-height:44px}
51
+ .account-toolbar-status{display:flex;align-items:center;gap:12px;flex-wrap:wrap;min-height:44px}
52
+ .account-toolbar-status p{margin:0}
53
+ .bulk-actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
54
+ .bulk-reason{font-size:12px;line-height:1.4;color:var(--muted);margin:0;max-width:280px}
55
+ #editor-dirty-state{color:var(--muted)}
56
+ #editor-dirty-state.dirty{color:var(--error);font-weight:600}
57
+ .dialog-footer-note{flex:1;min-width:0}
58
+ .dialog-footer-actions{display:flex;align-items:center;gap:10px;flex-wrap:wrap;justify-content:flex-end}
59
+ .dialog-footer-note .hint{margin:4px 0}
60
+ .accounts-shell [hidden],#account-editor [hidden],#account-history [hidden],#accounts-completion[hidden]{display:none!important}
61
+ @media(max-width:900px){.account-toolbar-status{width:100%}.bulk-actions{width:100%}}
62
+ #account-editor{padding:0;overflow:hidden}
63
+ #account-form{display:flex;flex-direction:column;max-height:90vh;min-height:0}
64
+ #account-editor .dialog-header{flex-shrink:0;padding:20px 22px 12px;margin:0;border-bottom:1px solid var(--line)}
65
+ #account-scroll{flex:1;min-height:0;overflow:auto;padding:18px 22px;scroll-padding:16px;overscroll-behavior:contain}
66
+ #account-fields{min-width:0}
67
+ #account-editor .dialog-footer{flex-shrink:0;margin:0;padding:12px 22px calc(12px + env(safe-area-inset-bottom));background:var(--paper);border-top:1px solid var(--input-border);gap:12px}
68
+ #account-form-error{flex-shrink:0;max-height:18vh;overflow:auto;margin:0;padding:10px 22px;border-radius:0;border-width:0 0 1px}
69
+ #account-editor .dialog-header h2{font-size:20px}
70
+ .reconciliation-summary{flex-shrink:0;max-height:12vh;overflow:auto;font-size:12px;line-height:1.7;padding:10px 20px;background:var(--warning-bg);color:var(--warning-ink);border-bottom:1px solid var(--warning-border);overflow-wrap:anywhere}
71
+ #account-editor .account-field-error{color:var(--error);font-size:12px;line-height:1.6;margin-top:6px}
72
+ @media(max-width:560px){.dialog-footer-actions{flex-direction:column;align-items:stretch}#account-editor .dialog-header{padding:14px 16px 10px}#account-scroll{padding:14px 16px}#account-editor .dialog-footer{padding:10px 16px;gap:8px}.dialog-footer-note .hint{font-size:11px}#account-editor .field input:not([type=checkbox]),#account-editor .field select{font-size:16px}}
73
+ @supports(max-height:90dvh){#account-form{max-height:90dvh}}
74
+ @media(max-height:500px){#account-editor .dialog-header p,#account-editor .dialog-footer-note>.hint:first-child{display:none}#account-editor .dialog-header{padding-top:10px;padding-bottom:6px}#account-editor .dialog-footer{padding-top:8px;padding-bottom:8px;flex-direction:row}}
75
+ @media(max-width:560px){.account-table-scroll{overflow:visible;border:0;border-radius:0;background:transparent}.account-table-scroll table,.account-table-scroll tbody,.account-table-scroll tr,.account-table-scroll td{display:block;width:auto;min-width:0}.account-table-scroll thead{display:none}.account-table-scroll tbody tr{margin-bottom:12px;padding:14px 16px;border:1px solid var(--line);border-radius:8px;background:var(--paper)}.account-table-scroll td{padding:0 0 10px;border:0}.account-table-scroll td:last-child{padding-bottom:0}.account-table-scroll td:not(:first-child)::before{content:attr(data-label);display:block;margin-bottom:2px;color:var(--muted);font-size:11px}.account-table-scroll .row-actions{max-width:none}}
@@ -0,0 +1,67 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="color-scheme" content="light dark">
7
+ <title>账号余额与签到 · UA PRO</title>
8
+ <script src="./theme.js"></script>
9
+ <link rel="stylesheet" href="./accounts.css">
10
+ <link rel="icon" type="image/svg+xml" href="./icon.svg">
11
+ </head>
12
+ <body>
13
+ <div id="accounts-shell" class="accounts-shell">
14
+ <header class="accounts-header"><a class="brand" href="./pro"><img class="brand-icon" src="./icon.svg" width="44" height="44" alt=""><span>Magpie<br><strong>UA PRO</strong></span></a><nav aria-label="UA PRO 页面"><a href="./pro">UA PRO</a><a href="./accounts" aria-current="page">账号余额与签到</a></nav><div class="theme-control"><label for="theme-mode">外观</label><select id="theme-mode" data-theme-control><option value="system">跟随系统</option><option value="dark">夜间模式</option><option value="light">浅色模式</option></select></div><button id="accounts-done" class="secondary" type="button">完成并关闭</button></header>
15
+ <main class="accounts-main">
16
+ <div class="accounts-title"><div><h1>每个账号,独立记账</h1><p>管理 New API / AgentRouter 站点余额、累计消耗与签到奖励,不改变现有模型路由。</p></div><button id="account-new" class="primary" type="button">添加账号</button></div>
17
+ <div id="accounts-error" class="accounts-error" role="alert" hidden tabindex="-1"></div>
18
+ <div id="account-totals" class="account-totals" aria-label="按单位汇总站点账号,不含连接 Key 余额"></div>
19
+ <div class="account-toolbar">
20
+ <div class="account-toolbar-status"><p id="accounts-status" role="status">正在读取本地账号…</p><a id="accounts-connections-link" href="./pro#connections">在连接与模型选择对应签到账号</a><button id="accounts-retry" class="secondary" type="button" hidden>重新读取账号列表</button><button id="accounts-ack" class="secondary" type="button" hidden>已核对结果,继续操作</button></div>
21
+ <div class="bulk-actions"><button id="refresh-all" class="secondary" type="button" disabled>刷新全部余额</button><button id="checkin-all" class="secondary" type="button" disabled>签到全部启用账号</button><span id="bulk-reason" class="bulk-reason" role="status" hidden></span></div>
22
+ </div>
23
+ <section id="connection-balances" class="account-notes" aria-labelledby="connection-balances-title">
24
+ <div class="account-toolbar">
25
+ <div class="account-toolbar-status"><div><h2 id="connection-balances-title">已配置连接余额/Key用量(不依赖签到凭据)</h2><p id="connection-balance-status" role="status">不会自动访问站点;请手动刷新连接 Key 用量。</p></div></div>
26
+ <div class="bulk-actions"><button id="connection-refresh-all" class="secondary" type="button" disabled>刷新全部连接 Key 用量</button></div>
27
+ </div>
28
+ <div id="connection-balance-list" class="account-table-scroll">
29
+ <table id="connection-balance-table"><thead><tr><th scope="col">连接 / 站点</th><th scope="col">Key 余额</th><th scope="col">Key 用量</th><th scope="col">最近查询</th></tr></thead><tbody id="connection-balance-rows"></tbody></table>
30
+ </div>
31
+ </section>
32
+ <div id="account-empty" class="account-empty" hidden><h2>还没有站点账号</h2><p>添加站点地址、站点类型和系统访问令牌或 Cookie;AgentRouter 还可填写登录用户名与密码。模型 API key 不能代替站点账号凭据。</p></div>
33
+ <div id="accounts-table-scroll" class="account-table-scroll"><table id="accounts-table"><thead><tr><th scope="col">账号 / 站点</th><th scope="col">剩余额度</th><th scope="col">累计消耗</th><th scope="col">相较上次成功刷新</th><th scope="col">签到</th><th scope="col">操作</th></tr></thead><tbody id="account-list"></tbody></table></div>
34
+ <div class="account-notes"><p>增量从两次成功读取计算,不等于“今日用量”。首次读取无基线;计数回退时重新建立基线。查询失败保留旧读数并标记缓存。</p><p>不同单位分别汇总,不做汇率转换。自动签到需在账号中单独开启;请勿同时启用宿主的另一套自动签到计划。验证码请到站点完成。</p></div>
35
+ </main>
36
+ </div>
37
+ <dialog id="account-editor" aria-labelledby="editor-title">
38
+ <form id="account-form" novalidate aria-describedby="account-form-error">
39
+ <header class="dialog-header"><div><h2 id="editor-title">添加站点账号</h2><p>账号凭据与模型路由 API key 分开保存。</p></div><button id="editor-close" class="secondary" type="button" aria-label="关闭账号编辑">×</button></header>
40
+ <div id="account-form-error" class="accounts-error" role="alert" hidden tabindex="-1"></div>
41
+ <div id="editor-reconciliation" class="reconciliation-summary" role="status" hidden></div>
42
+ <div id="account-scroll"><fieldset id="account-fields">
43
+ <div class="field-grid"><div class="field"><label for="account-name">账号名称</label><input id="account-name" required placeholder="便于识别的名称" autocomplete="off"></div><div class="field"><label for="site-type">站点类型</label><select id="site-type"><option value="newapi">NewAPI(Cookie/令牌签到)</option><option value="agentrouter">AgentRouter(登录即签到)</option></select><p class="hint">NewAPI 用 Cookie/令牌签到;AgentRouter 用登录即签到。</p></div></div>
44
+ <div class="field"><label for="site-url">站点地址</label><input id="site-url" type="url" required placeholder="https://你的站点地址" autocomplete="off" spellcheck="false"><p class="hint">填写站点根地址或部署基础路径,不是模型 API 的 /v1 地址。</p></div>
45
+ <div class="field-grid"><div class="field"><label for="user-id">用户 ID</label><input id="user-id" inputmode="numeric" required placeholder="站点个人资料中的数字 ID"><p class="hint">NewAPI 必填数字 ID;AgentRouter 可留空,由登录结果确定。</p></div><div class="field"><label for="auth-mode">余额查询凭据</label><select id="auth-mode"><option value="token">系统访问令牌</option><option value="cookie">登录 Cookie</option></select><p class="hint">仅用于只读余额查询,不用于 AgentRouter 登录签到。</p></div></div>
46
+ <div id="token-field" class="field"><label for="access-token">系统访问令牌</label><input type="password" id="access-token" autocomplete="new-password" placeholder="不是 sk- 开头的模型调用 key"><div class="secret-meta"><span id="token-state" class="hint">留空保留已有值</span><label class="check-label" for="clear-token"><input type="checkbox" id="clear-token">清除已存令牌</label></div></div>
47
+ <div id="cookie-field" class="field"><label for="account-cookie">登录 Cookie</label><input type="password" id="account-cookie" autocomplete="new-password" placeholder="session=…"><div class="secret-meta"><span id="cookie-state" class="hint">留空保留已有值</span><label class="check-label" for="clear-cookie"><input type="checkbox" id="clear-cookie">清除已存 Cookie</label></div><p class="hint">Cookie 过期后需从自己账号的站点重新获取。含登录凭据,仅保存在本机。</p></div>
48
+ <div id="agentrouter-fields" hidden><div class="field-grid"><div class="field"><label for="agent-username">AgentRouter 登录用户名</label><input id="agent-username" autocomplete="username" placeholder="用于站点登录签到"></div><div class="field"><label for="agent-password">AgentRouter 登录密码</label><input type="password" id="agent-password" autocomplete="new-password"><div class="secret-meta"><span id="agent-password-state" class="hint">尚未保存登录密码</span><label class="check-label" for="clear-password"><input type="checkbox" id="clear-password">清除已存密码</label></div></div></div><p class="hint">用户名和密码只用于向站点 POST api/user/login 完成签到,绝不进入模型请求路径;上方 PAT/Cookie 仍只用于只读余额查询。</p></div>
49
+ <div class="field-grid"><div class="field"><label for="quota-per-unit">每单位对应 quota</label><input id="quota-per-unit" type="number" min="0.000001" step="any" value="500000"><p class="hint">New API 常见默认 500000;按站点实际设置修改。</p></div><div class="field"><label for="unit">显示单位</label><input id="unit" value="USD" maxlength="20"><p class="hint">仅显示标签,不代表已验证美元汇率。</p></div></div>
50
+ <div class="account-toggles"><label class="check-label" for="account-enabled"><input id="account-enabled" type="checkbox" checked>启用账号,参与批量刷新</label><label class="check-label" for="checkin-enabled"><input id="checkin-enabled" type="checkbox" checked>允许手动、定时或宿主发起签到</label></div>
51
+ <section class="account-schedule" aria-label="自动签到时间">
52
+ <label class="check-label" for="schedule-enabled"><input id="schedule-enabled" type="checkbox">按此页设置定时签到(可选)</label>
53
+ <div id="schedule-settings" class="field-grid" hidden>
54
+ <div class="field"><label for="schedule-time">每天几点签到</label><input id="schedule-time" type="time" step="60" value="09:00"></div>
55
+ <div class="field"><label for="schedule-timezone">按哪个时区</label><input id="schedule-timezone" list="schedule-timezones" autocomplete="off" spellcheck="false" placeholder="Asia/Shanghai"><datalist id="schedule-timezones"><option value="Asia/Shanghai">北京时间</option><option value="Asia/Hong_Kong">香港</option><option value="Asia/Tokyo">东京</option><option value="UTC">世界标准时间</option><option value="America/New_York">纽约</option><option value="America/Los_Angeles">洛杉矶</option><option value="Europe/London">伦敦</option></datalist><p class="hint">默认使用你浏览器的时区,也可填写其他 IANA 时区名称。</p></div>
56
+ </div>
57
+ <p class="hint">此页定时签到可与站内手动签到、宿主签到分别使用;需要 Magpie 插件进程保持运行,但请勿同时启用宿主另一套自动签到。错过时间不补跑,同一天自动尝试一次,失败不自动重试。夏令时跳过的分钟不执行。</p>
58
+ </section>
59
+ </fieldset></div>
60
+ <footer class="dialog-footer"><div class="dialog-footer-note"><p class="hint">保存不会发送登录或签到请求。密钥不会回传浏览器。</p><p id="editor-dirty-state" class="hint" role="status"></p></div><div class="dialog-footer-actions"><button id="editor-recheck" class="secondary" type="button" hidden>重新读取账号列表</button><button id="editor-ack" class="secondary" type="button" hidden>已核对结果,继续操作</button><button id="account-save" class="primary" type="submit">保存账号</button></div></footer>
61
+ </form>
62
+ </dialog>
63
+ <dialog id="account-history" aria-labelledby="history-title"><header class="dialog-header"><h2 id="history-title">额度变化记录</h2><button id="history-close" class="secondary" type="button">关闭</button></header><div class="history-scroll"><table><thead><tr><th>读取时间</th><th>剩余额度</th><th>累计消耗</th><th>余额变化</th><th>消耗增加</th><th>请求增加</th></tr></thead><tbody id="history-list"></tbody></table></div><p class="hint">最多保留最近 90 条成功读取快照。缓存错误不会新增零值快照。</p></dialog>
64
+ <main id="accounts-completion" class="completion" hidden><div class="completion-icon" aria-hidden="true">✓</div><h1>账号设置已保存</h1><p>可以返回 Magpie。浏览器未自动关闭时可手动关闭此页面。</p></main>
65
+ <script type="module" src="./accounts.js"></script>
66
+ </body>
67
+ </html>