Download index.html from chihsing/DrugOps: direct link, hf CLI and curl.
- Browser
- Download file 20.7 kB
-
https://huggingface.co/spaces/chihsing/DrugOps/resolve/main/index.html
- Command line
-
hf download hf://spaces/chihsing/DrugOps/index.html
-
curl -L -o index.html https://huggingface.co/spaces/chihsing/DrugOps/resolve/main/index.html
20.7 kB
| <html lang="zh-Hant" data-theme="dark"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>DrugOps</title> | |
| <link rel="preconnect" href="https://fonts.googleapis.com"> | |
| <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;600;700&family=Syne:wght@700;800&family=Inter:wght@300;400;500&display=swap" rel="stylesheet"> | |
| <style> | |
| :root{ | |
| --bg:#080a0e;--surface:#0f1117;--surface2:#161b24;--surface3:#1d2333; | |
| --border:rgba(255,255,255,.07);--border2:rgba(255,255,255,.13); | |
| --text:#dde3f0;--text2:#7a85a0;--text3:#3f4860; | |
| --blue:#3b8dff;--blue2:#1a5cd4;--blue-glow:rgba(59,141,255,.18); | |
| --teal:#22d3b8;--teal-glow:rgba(34,211,184,.15); | |
| --mono:'IBM Plex Mono',monospace;--display:'Syne',sans-serif;--sans:'Inter',sans-serif; | |
| --r:10px;--r2:16px; | |
| } | |
| html[data-theme="light"]{ | |
| --bg:#f0f2f7;--surface:#ffffff;--surface2:#e9ecf4;--surface3:#dde2ef; | |
| --border:rgba(0,0,0,.08);--border2:rgba(0,0,0,.14); | |
| --text:#111827;--text2:#4b5568;--text3:#9ca3af; | |
| --blue:#1d4ed8;--blue2:#1e40af;--blue-glow:rgba(29,78,216,.1); | |
| --teal:#0d9488;--teal-glow:rgba(13,148,136,.1); | |
| } | |
| *{box-sizing:border-box;margin:0;padding:0;} | |
| html,body{height:100%;} | |
| body{background:var(--bg);color:var(--text);font-family:var(--sans);font-size:15px;line-height:1.6;min-height:100vh;overflow-x:hidden;} | |
| .page{max-width:860px;margin:0 auto;padding:2rem 1.25rem 4rem;} | |
| /* TOPBAR */ | |
| .topbar{display:flex;align-items:center;justify-content:space-between;margin-bottom:3.5rem;} | |
| .brand{display:flex;align-items:center;gap:10px;} | |
| .brand-mark{ | |
| width:34px;height:34px;border-radius:8px; | |
| background:linear-gradient(135deg,var(--blue) 0%,var(--teal) 100%); | |
| display:flex;align-items:center;justify-content:center;flex-shrink:0; | |
| } | |
| .brand-mark svg{width:18px;height:18px;fill:none;stroke:#fff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;} | |
| .brand-name{font-family:var(--display);font-size:20px;font-weight:800;letter-spacing:-.02em;} | |
| .brand-mol{color:var(--blue);} | |
| .brand-gate{color:var(--teal);} | |
| .ctrls{display:flex;gap:6px;align-items:center;} | |
| .ctrl-pill{ | |
| font-family:var(--mono);font-size:10px;padding:4px 11px; | |
| border-radius:20px;border:1px solid var(--border2); | |
| background:transparent;color:var(--text3);cursor:pointer;transition:all .18s; | |
| } | |
| .ctrl-pill.active{background:var(--surface3);color:var(--text);border-color:var(--border2);} | |
| .ctrl-sep{width:1px;height:20px;background:var(--border2);} | |
| /* HERO */ | |
| .hero{text-align:center;padding:1rem 0 3rem;animation:fadeUp .5s both;} | |
| @keyframes fadeUp{from{opacity:0;transform:translateY(24px);}to{opacity:1;transform:none;}} | |
| .hero-eyebrow{ | |
| display:inline-flex;align-items:center;gap:8px; | |
| font-family:var(--mono);font-size:11px;letter-spacing:.1em; | |
| color:var(--teal);padding:5px 14px;border-radius:20px; | |
| border:1px solid var(--teal-glow);background:var(--teal-glow); | |
| margin-bottom:1.5rem; | |
| } | |
| .hero-eyebrow span.dot{width:6px;height:6px;border-radius:50%;background:var(--teal);animation:pulse 2s infinite;} | |
| @keyframes pulse{0%,100%{opacity:1;}50%{opacity:.35;}} | |
| .hero-h1{font-family:var(--display);font-size:clamp(2.5rem,7vw,4rem);font-weight:800;line-height:1.05;letter-spacing:-.04em;margin-bottom:1.25rem;} | |
| .hero-h1 .hl-blue{color:var(--blue);} | |
| .hero-h1 .hl-teal{color:var(--teal);} | |
| .hero-sub{font-size:15px;color:var(--text2);max-width:560px;margin:0 auto 2rem;line-height:1.8;} | |
| .hero-cta{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;margin-top:.5rem;} | |
| /* DIVIDER */ | |
| .divider{display:flex;align-items:center;gap:1rem;margin:0 0 1.5rem;} | |
| .divider-line{flex:1;height:1px;background:var(--border);} | |
| .divider-label{font-family:var(--mono);font-size:10px;color:var(--text3);letter-spacing:.1em;white-space:nowrap;} | |
| /* PIPELINE CARDS */ | |
| .pipeline{display:flex;flex-direction:column;gap:.75rem;margin-bottom:2rem;} | |
| .pcard{ | |
| background:var(--surface);border:1px solid var(--border); | |
| border-radius:var(--r2);overflow:hidden; | |
| transition:border-color .2s,transform .2s; | |
| animation:slideIn .4s both; | |
| } | |
| @keyframes slideIn{from{opacity:0;transform:translateY(16px);}to{opacity:1;transform:none;}} | |
| .pcard:nth-child(1){animation-delay:.05s;} | |
| .pcard:nth-child(2){animation-delay:.12s;} | |
| .pcard:nth-child(3){animation-delay:.19s;} | |
| .pcard:hover{border-color:var(--border2);transform:translateY(-2px);} | |
| .pcard-top{display:flex;align-items:stretch;} | |
| .pcard-accent{width:4px;flex-shrink:0;} | |
| .pcard:nth-child(1) .pcard-accent{background:var(--blue);} | |
| .pcard:nth-child(2) .pcard-accent{background:var(--teal);} | |
| .pcard:nth-child(3) .pcard-accent{background:linear-gradient(180deg,var(--blue),var(--teal));} | |
| .pcard-head{display:flex;align-items:flex-start;gap:1rem;padding:1.1rem 1.3rem;flex:1;} | |
| .stage-badge{ | |
| font-family:var(--mono);font-size:11px;font-weight:700; | |
| padding:6px 10px;border-radius:8px;flex-shrink:0;line-height:1;border:1px solid; | |
| } | |
| .pcard:nth-child(1) .stage-badge{background:var(--blue-glow);color:var(--blue);border-color:rgba(59,141,255,.25);} | |
| .pcard:nth-child(2) .stage-badge{background:var(--teal-glow);color:var(--teal);border-color:rgba(34,211,184,.25);} | |
| .pcard:nth-child(3) .stage-badge{background:var(--blue-glow);color:var(--blue);border-color:rgba(59,141,255,.25);} | |
| .pcard-meta{flex:1;} | |
| .pcard-kicker{font-family:var(--mono);font-size:10px;color:var(--text3);letter-spacing:.07em;margin-bottom:4px;} | |
| .pcard-title{font-family:var(--display);font-size:17px;font-weight:700;line-height:1.2;margin-bottom:4px;} | |
| .pcard-modules{font-family:var(--mono);font-size:10px;color:var(--text3);} | |
| .pcard-body{border-top:1px solid var(--border);padding:1rem 1.3rem 1.3rem 1.3rem;} | |
| .pcard-desc{font-size:13px;color:var(--text2);margin-bottom:1rem;line-height:1.75;} | |
| .outputs{display:flex;gap:.4rem;flex-wrap:wrap;margin-bottom:1rem;} | |
| .out-file{font-family:var(--mono);font-size:10px;padding:3px 9px;border-radius:5px;background:var(--surface2);border:1px solid var(--border);color:var(--text2);} | |
| .out-status{font-family:var(--mono);font-size:10px;padding:3px 9px;border-radius:5px;color:var(--teal);background:var(--teal-glow);border:1px solid rgba(34,211,184,.2);} | |
| .pcard-actions{display:flex;gap:.5rem;flex-wrap:wrap;} | |
| /* BUTTONS */ | |
| .btn{ | |
| font-family:var(--mono);font-size:11px;font-weight:600; | |
| padding:8px 16px;border-radius:8px;border:1px solid; | |
| cursor:pointer;text-decoration:none;display:inline-block; | |
| transition:all .18s;line-height:1; | |
| } | |
| .btn-teal{background:var(--teal);color:#080a0e;border-color:var(--teal);} | |
| html[data-theme="light"] .btn-teal{color:#fff;} | |
| .btn-teal:hover{filter:brightness(1.1);} | |
| .btn-ghost{background:transparent;color:var(--text2);border-color:var(--border2);} | |
| .btn-ghost:hover{background:var(--surface2);color:var(--text);} | |
| .btn-hero-primary{ | |
| font-family:var(--mono);font-size:12px;font-weight:700; | |
| padding:12px 24px;border-radius:10px;border:none; | |
| cursor:pointer;text-decoration:none;display:inline-block; | |
| background:var(--blue);color:#fff;transition:all .18s; | |
| } | |
| .btn-hero-primary:hover{background:var(--blue2);} | |
| /* CTA BAR */ | |
| .cta-bar{ | |
| background:var(--surface);border:1px solid var(--border); | |
| border-radius:var(--r2);padding:1.75rem; | |
| display:flex;align-items:center;justify-content:space-between;gap:1rem;flex-wrap:wrap; | |
| margin-bottom:2rem; | |
| } | |
| .cta-title{font-family:var(--display);font-size:16px;font-weight:700;margin-bottom:4px;} | |
| .cta-sub{font-size:13px;color:var(--text2);} | |
| /* FOOTER */ | |
| .footer{ | |
| display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:.5rem; | |
| padding-top:1.5rem;border-top:1px solid var(--border); | |
| font-family:var(--mono);font-size:10px;color:var(--text3); | |
| } | |
| .footer-brand{color:var(--text2);} | |
| .footer-links{display:flex;gap:1rem;} | |
| .footer-links a{color:var(--text3);text-decoration:none;} | |
| .footer-links a:hover{color:var(--text2);} | |
| </style> | |
| </head> | |
| <body> | |
| <div class="page"> | |
| <!-- TOPBAR --> | |
| <div class="topbar"> | |
| <a class="brand" href="/" style="text-decoration:none;color:inherit"> | |
| <div class="brand-mark"> | |
| <svg viewBox="0 0 18 18"><circle cx="9" cy="5" r="2"/><circle cx="4" cy="14" r="2"/><circle cx="14" cy="14" r="2"/><line x1="9" y1="7" x2="5" y2="12"/><line x1="9" y1="7" x2="13" y2="12"/></svg> | |
| </div> | |
| <span class="brand-name"><span class="brand-mol">Drug</span><span class="brand-gate">Ops</span></span> | |
| <span style="font-family:var(--mono);font-size:11px;color:var(--text3);margin-left:4px;align-self:flex-end;padding-bottom:2px;">CreaDrug</span> | |
| </a> | |
| <div class="ctrls"> | |
| <button type="button" class="ctrl-pill active" id="btn-theme-dark" onclick="setTheme('dark')">深色</button> | |
| <button type="button" class="ctrl-pill" id="btn-theme-light" onclick="setTheme('light')">淺色</button> | |
| <div class="ctrl-sep"></div> | |
| <button type="button" class="ctrl-pill active" id="btn-lang-zh" onclick="setLang('zh')">中文</button> | |
| <button type="button" class="ctrl-pill" id="btn-lang-en" onclick="setLang('en')">EN</button> | |
| </div> | |
| </div> | |
| <!-- HERO --> | |
| <section class="hero"> | |
| <div class="hero-eyebrow"> | |
| <span class="dot"></span> | |
| <span data-zh="CreaDrug 計算藥物對接平台" data-en="CreaDrug Computational Docking Platform">CreaDrug 計算藥物對接平台</span> | |
| </div> | |
| <h1 class="hero-h1"> | |
| <span data-zh="從 SMILES<br>到<br>" data-en="From SMILES<br>to<br>">從 SMILES<br>到<br></span><span class="hl-blue">Dock</span><span class="hl-teal">ing</span> | |
| </h1> | |
| <p class="hero-sub" data-zh="CreaDrug 平台 · DrugOps 27 Stage 品質管控 pipeline,從首頁依序進入 Module 1→5。請執行 bin\\start_all.bat,依終端機顯示的網址開啟(預設 port 8780)。" data-en="CreaDrug platform · DrugOps 27-stage QC pipeline, Module 1→5 from the homepage. Run bin\\start_all.bat and open the URL shown in the terminal (default port 8780).">CreaDrug 平台 · DrugOps 27 Stage 品質管控 pipeline,從首頁依序進入 Module 1→5。請執行 bin\\start_all.bat,依終端機顯示的網址開啟(預設 port 8780)。</p> | |
| <div class="hero-cta"> | |
| <a class="btn-hero-primary" id="linkStart" href="/module/1" data-zh="進入 Module 1 開始 →" data-en="Start at Module 1 →">進入 Module 1 開始 →</a> | |
| <a class="btn btn-ghost" id="linkReasonMind" href="/reasonmind" data-zh="ReasonMind 藥研助手 →" data-en="ReasonMind AI →">ReasonMind 藥研助手 →</a> | |
| </div> | |
| </section> | |
| <!-- DIVIDER --> | |
| <div class="divider" id="pipeline"> | |
| <div class="divider-line"></div> | |
| <div class="divider-label" data-zh="三段落流程" data-en="THREE-STAGE PIPELINE">三段落流程</div> | |
| <div class="divider-line"></div> | |
| </div> | |
| <!-- PIPELINE CARDS --> | |
| <div class="pipeline"> | |
| <article class="pcard"> | |
| <div class="pcard-top"> | |
| <div class="pcard-accent"></div> | |
| <div class="pcard-head"> | |
| <div class="stage-badge">01</div> | |
| <div class="pcard-meta"> | |
| <div class="pcard-kicker" data-zh="段落 1 · 配體準備" data-en="STAGE 1 · LIGAND PREP">段落 1 · 配體準備</div> | |
| <div class="pcard-title" data-zh="藥品 · 配體" data-en="Drug · Ligand">藥品 · 配體</div> | |
| <div class="pcard-modules">Module 1–2 · Stage 01–09</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="pcard-body"> | |
| <p class="pcard-desc" data-zh="輸入 SMILES 與靶點後,系統完成標準化、質子化態與互變異構選擇,輸出可直接對接的 3D 配體。" data-en="After SMILES and target input, the pipeline standardizes the molecule, selects protonation and tautomer states, and produces a dock-ready 3D ligand.">輸入 SMILES 與靶點後,系統完成標準化、質子化態與互變異構選擇,輸出可直接對接的 3D 配體。</p> | |
| <div class="outputs"> | |
| <span class="out-file">ligand.pdb</span> | |
| <span class="out-file">ligand.pdbqt</span> | |
| <span class="out-file">SMILES</span> | |
| <span class="out-status">LIGAND_READY</span> | |
| </div> | |
| <div class="pcard-actions"> | |
| <a class="btn btn-teal" id="linkMod1" href="/module/1" data-zh="進入 Module 1 →" data-en="Open Module 1 →">進入 Module 1 →</a> | |
| <a class="btn btn-ghost" id="linkMod2" href="/module/2" data-zh="Module 2 →" data-en="Module 2 →">Module 2 →</a> | |
| <a class="btn btn-ghost" id="link3d1" href="/creadrug24/creadrug_showboard_24.html?view=ligand&src=molgate" data-zh="CreaDrug 3D →" data-en="CreaDrug 3D →">CreaDrug 3D →</a> | |
| </div> | |
| </div> | |
| </article> | |
| <article class="pcard"> | |
| <div class="pcard-top"> | |
| <div class="pcard-accent"></div> | |
| <div class="pcard-head"> | |
| <div class="stage-badge">02</div> | |
| <div class="pcard-meta"> | |
| <div class="pcard-kicker" data-zh="段落 2 · 受體清理" data-en="STAGE 2 · RECEPTOR PREP">段落 2 · 受體清理</div> | |
| <div class="pcard-title" data-zh="受體 · 蛋白結構" data-en="Receptor · Protein">受體 · 蛋白結構</div> | |
| <div class="pcard-modules">Module 3 · Stage 10–19</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="pcard-body"> | |
| <p class="pcard-desc" data-zh="下載並清理 PDB 結構:鏈選擇、水分子去除、輔因子決策,輸出可供口袋定義與對接使用的 cleaned 受體。" data-en="Download and clean the PDB structure: chain selection, water removal, cofactor decisions — yielding a cleaned receptor ready for pocket definition and docking.">下載並清理 PDB 結構:鏈選擇、水分子去除、輔因子決策,輸出可供口袋定義與對接使用的 cleaned 受體。</p> | |
| <div class="outputs"> | |
| <span class="out-file">cleaned.pdb</span> | |
| <span class="out-file">receptor.pdbqt</span> | |
| <span class="out-file">PDB ID</span> | |
| <span class="out-status">STRUCTURE_READY</span> | |
| </div> | |
| <div class="pcard-actions"> | |
| <a class="btn btn-teal" id="linkMod3" href="/module/3" data-zh="進入 Module 3 →" data-en="Open Module 3 →">進入 Module 3 →</a> | |
| <a class="btn btn-ghost" id="link3d2" href="/creadrug24/creadrug_showboard_24.html?view=receptor&src=molgate" data-zh="CreaDrug 3D →" data-en="CreaDrug 3D →">CreaDrug 3D →</a> | |
| </div> | |
| </div> | |
| </article> | |
| <article class="pcard"> | |
| <div class="pcard-top"> | |
| <div class="pcard-accent"></div> | |
| <div class="pcard-head"> | |
| <div class="stage-badge">03</div> | |
| <div class="pcard-meta"> | |
| <div class="pcard-kicker" data-zh="段落 3 · 對接執行" data-en="STAGE 3 · DOCKING">段落 3 · 對接執行</div> | |
| <div class="pcard-title" data-zh="Docking 完成" data-en="Docking Complete">Docking 完成</div> | |
| <div class="pcard-modules">Module 4–5 · Stage 21–26</div> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="pcard-body"> | |
| <p class="pcard-desc" data-zh="定義口袋、執行 AutoDock Vina,取得最佳 pose、結合親和力與信心 tier,可在 CreaDrug 以受體+pose 方式檢視對接結果。" data-en="Define the pocket, run AutoDock Vina, obtain the best pose, binding affinity, and confidence tier — view receptor + pose together in CreaDrug.">定義口袋、執行 AutoDock Vina,取得最佳 pose、結合親和力與信心 tier,可在 CreaDrug 以受體+pose 方式檢視對接結果。</p> | |
| <div class="outputs"> | |
| <span class="out-file">best_pose.pdb</span> | |
| <span class="out-file">affinity</span> | |
| <span class="out-file">confidence tier</span> | |
| <span class="out-status">DOCK_COMPLETE</span> | |
| </div> | |
| <div class="pcard-actions"> | |
| <a class="btn btn-teal" id="linkMod4" href="/module/4" data-zh="進入 Module 4 →" data-en="Open Module 4 →">進入 Module 4 →</a> | |
| <a class="btn btn-ghost" id="linkMod5" href="/module/5" data-zh="Module 5 →" data-en="Module 5 →">Module 5 →</a> | |
| <a class="btn btn-ghost" id="link3d3" href="/creadrug24/creadrug_showboard_24.html?view=pose&src=molgate" data-zh="CreaDrug 3D →" data-en="CreaDrug 3D →">CreaDrug 3D →</a> | |
| </div> | |
| </div> | |
| </article> | |
| </div> | |
| <!-- CTA BAR --> | |
| <div class="cta-bar"> | |
| <div> | |
| <div class="cta-title" data-zh="準備開始新的對接流程?" data-en="Ready to start a new docking run?">準備開始新的對接流程?</div> | |
| <div class="cta-sub" data-zh="從 Module 1 輸入 SMILES,全程自動化完成 27 個 Stage。" data-en="Enter SMILES at Module 1 and let the 27-stage pipeline run automatically.">從 Module 1 輸入 SMILES,全程自動化完成 27 個 Stage。</div> | |
| </div> | |
| <a class="btn-hero-primary" id="linkStart2" href="/module/1" data-zh="進入 Module 1 →" data-en="Start at Module 1 →">進入 Module 1 →</a> | |
| </div> | |
| <!-- FOOTER --> | |
| <footer class="footer"> | |
| <div class="footer-brand">CreaDrug · DrugOps Pipeline</div> | |
| <div class="footer-links"> | |
| <a href="/module/1">M1</a> | |
| <a href="/module/2">M2</a> | |
| <a href="/module/3">M3</a> | |
| <a href="/module/4">M4</a> | |
| <a href="/module/5">M5</a> | |
| </div> | |
| </footer> | |
| </div> | |
| <script> | |
| (function(){ | |
| var IS_FILE = location.protocol === 'file:'; | |
| var LANG = { cur: localStorage.getItem('molgate-lang') || localStorage.getItem('mg-lang') || 'zh' }; | |
| function moduleUrl(n) { | |
| if (IS_FILE) return 'modules/m' + n + '/module' + n + '_panel.html'; | |
| return '/module/' + n; | |
| } | |
| function reasonmindUrl() { | |
| if (IS_FILE) return 'reasonmind/index.html'; | |
| return '/reasonmind'; | |
| } | |
| function creadrugUrl(view) { | |
| if (IS_FILE) return '../MolGate/CreaDrug24/creadrug_showboard_24.html?view=' + view + '&src=molgate'; | |
| return '/creadrug24/creadrug_showboard_24.html?view=' + view + '&src=molgate'; | |
| } | |
| var linkIds = ['linkStart', 'linkStart2', 'linkMod1']; | |
| linkIds.forEach(function(id) { | |
| var el = document.getElementById(id); | |
| if (el) el.href = moduleUrl(1); | |
| }); | |
| var rm = document.getElementById('linkReasonMind'); | |
| if (rm) rm.href = reasonmindUrl(); | |
| ['linkMod2','linkMod3','linkMod4','linkMod5'].forEach(function(id, i) { | |
| var el = document.getElementById(id); | |
| if (el) el.href = moduleUrl(i + 2); | |
| }); | |
| var brand = document.querySelector('a.brand'); | |
| if (brand && IS_FILE) brand.href = 'index.html'; | |
| document.querySelectorAll('.footer-links a').forEach(function(a, i) { | |
| a.href = moduleUrl(i + 1); | |
| }); | |
| ['link3d1', 'link3d2', 'link3d3'].forEach(function(id, i) { | |
| var el = document.getElementById(id); | |
| if (el) el.href = creadrugUrl(['ligand', 'receptor', 'pose'][i]); | |
| }); | |
| if (IS_FILE) { | |
| var banner = document.createElement('div'); | |
| banner.setAttribute('role', 'alert'); | |
| banner.style.cssText = 'position:fixed;left:0;right:0;top:0;z-index:9999;padding:10px 14px;background:#7c2d12;color:#fff;font:13px/1.5 system-ui;text-align:center;border-bottom:2px solid #ea580c'; | |
| banner.innerHTML = '請執行 <b>bin\\start_all.bat</b>,用瀏覽器開啟唯一入口 <b>http://127.0.0.1:8780/</b>(勿雙擊 HTML;port 可改 config\\ui_ports.json)。'; | |
| document.body.prepend(banner); | |
| document.body.style.paddingTop = '48px'; | |
| } | |
| function applyI18n() { | |
| document.querySelectorAll('[data-zh][data-en]').forEach(function(el) { | |
| if (el.tagName === 'A') { | |
| var t = el.getAttribute('data-' + LANG.cur); | |
| if (t) el.textContent = t; | |
| } else { | |
| var t2 = el.getAttribute('data-' + LANG.cur); | |
| if (t2) el.innerHTML = t2; | |
| } | |
| }); | |
| document.getElementById('btn-lang-zh').classList.toggle('active', LANG.cur === 'zh'); | |
| document.getElementById('btn-lang-en').classList.toggle('active', LANG.cur === 'en'); | |
| } | |
| window.setLang = function(l) { | |
| LANG.cur = l === 'en' ? 'en' : 'zh'; | |
| localStorage.setItem('molgate-lang', LANG.cur); | |
| localStorage.setItem('mg-lang', LANG.cur); | |
| applyI18n(); | |
| }; | |
| window.setTheme = function(t) { | |
| document.documentElement.setAttribute('data-theme', t === 'light' ? 'light' : 'dark'); | |
| localStorage.setItem('molgate-theme', t); | |
| localStorage.setItem('mg-theme', t); | |
| document.getElementById('btn-theme-dark').classList.toggle('active', t !== 'light'); | |
| document.getElementById('btn-theme-light').classList.toggle('active', t === 'light'); | |
| }; | |
| setTheme(localStorage.getItem('molgate-theme') || localStorage.getItem('mg-theme') === 'light' ? 'light' : 'dark'); | |
| applyI18n(); | |
| })(); | |
| </script> | |
| </body> | |
| </html> | |