upgrade astro

-- [CST 2026-10-02 Friday 21:58:32]
This commit is contained in:
biss committed 2026-10-02 21:58:32 +08:00
commit ebd245deb2
117 files changed
+65233

No files matched your search

+1
View File
@@ -0,0 +1 @@
@import "https://fontsapi.zeoseven.com/7/main/result.css";:root{color-scheme:light;--bg:#f7f5ef;--surface:#fffdf8;--text:#20242a;--muted:#686f78;--line:#ded8cc;--accent:#0f766e;--accent-strong:#14532d;--shadow:0 14px 45px #3a33261a;--page-gutter:clamp(20px, 4vw, 64px);--wide-width:1440px;--content-width:1280px;--article-width:1080px;--narrow-width:1000px}:root[data-theme=dark]{color-scheme:dark;--bg:#0b1014;--surface:#141b21;--text:#eef4f6;--muted:#b6c3c9;--line:#b5c6cf47;--accent:#8be0d5;--accent-strong:#b7e7d4;--shadow:0 18px 52px #00000070}*{box-sizing:border-box}html{max-width:100%;overflow-x:clip}body{color:var(--text);background:linear-gradient(#f7f5efdb,#f7f5eff2),url(/images/background.png) top/cover fixed;margin:0;font-family:"Zhuque Fangsong (technical preview)";font-weight:400;line-height:1.75;transition:color .22s,background-color .22s}:root[data-theme=dark] body{background:linear-gradient(#070a0ee6,#080d11f5),url(/images/background.png) top/cover fixed}a{color:inherit;text-decoration:none}.site-header{z-index:10;pointer-events:none;position:sticky;top:12px}.nav{width:min(var(--wide-width), calc(100% - (var(--page-gutter) * 2)));-webkit-backdrop-filter:blur(22px)saturate(180%);pointer-events:auto;background:linear-gradient(135deg,#ffffff85,#fff3),#ffffff47;border:1px solid #ffffff8f;border-radius:999px;grid-template-columns:minmax(120px,1fr) auto minmax(120px,1fr);align-items:center;gap:24px;min-height:58px;margin:0 auto;padding:0 18px;display:grid;position:relative;overflow:hidden;box-shadow:inset 0 1px #ffffffd1,inset 0 -18px 38px #ffffff29,0 18px 54px #2c373f2e}.nav:before{content:"";opacity:.74;pointer-events:none;background:radial-gradient(circle at 18% 0,#ffffffb8,#0000 30%),linear-gradient(90deg,#ffffff6b,#0000 38%,#ffffff38);position:absolute;inset:0}.nav:after{display:none}.brand{z-index:1;font-size:1.05rem;font-weight:800;position:relative}.nav-menu{display:contents}.nav-drawer-backdrop{display:none}.nav-menu-toggle{z-index:1;width:40px;height:40px;color:var(--muted);font:inherit;cursor:pointer;background:0 0;border:1px solid #0000;border-radius:999px;place-items:center;transition:color .2s,background-color .2s,border-color .2s,box-shadow .2s,transform .2s;display:none;position:relative}.nav-menu-close{display:none}.nav-links{z-index:1;color:var(--muted);white-space:nowrap;align-items:center;gap:6px;font-size:.94rem;display:flex;position:relative}.nav-center{justify-content:center}.nav-actions{justify-content:flex-end}.nav-links a,.nav-random,.nav-search,.nav-console,.theme-toggle{border:1px solid #0000;border-radius:999px;align-items:center;gap:6px;padding:7px 12px;transition:color .2s,background-color .2s,border-color .2s,box-shadow .2s,transform .2s;display:inline-flex}.nav-search,.nav-random,.nav-console,.theme-toggle{color:inherit;font:inherit;line-height:inherit;cursor:pointer;background:0 0}.nav-random{position:relative;overflow:hidden}.nav-random:after{content:"";border-radius:inherit;opacity:0;pointer-events:none;background:linear-gradient(120deg,#0000 8%,#ffffffd1 34%,#0000 58%);position:absolute;inset:3px;transform:translate(-135%)}.nav-random.is-randomizing{color:var(--accent);background:#ffffff80;border-color:#0f766e38;box-shadow:inset 0 1px #ffffffc2,0 10px 24px #0f766e29}.nav-random.is-randomizing:after{opacity:1;animation:.72s both random-button-sheen}.nav-random.is-randomizing .nav-icon{animation:.72s cubic-bezier(.2,.8,.2,1) both random-button-spin}.nav-icon{place-items:center;width:16px;min-width:16px;height:16px;font-size:.95em;line-height:1;display:inline-grid}.theme-toggle{justify-content:center;width:38px;min-height:38px;padding:0}:root:not([data-theme=dark]) .theme-toggle-sun,:root[data-theme=dark] .theme-toggle-moon{display:none}.nav-links a:hover,.nav-random:hover,.nav-search:hover,.nav-console:hover,.theme-toggle:hover,.site-footer a:hover,.section-heading a:hover{color:var(--accent)}.custom-context-menu{z-index:1000;color:#4f565b;-webkit-backdrop-filter:blur(18px)saturate(165%);opacity:0;pointer-events:none;transform-origin:0 0;background:linear-gradient(145deg,#ffffffc7,#ebf8e7ad),#f5fcf1d1;border:1px solid #ffffff94;border-radius:14px;width:min(218px,100vw - 20px);max-height:calc(100vh - 20px);padding:8px;transition:opacity .14s,transform .14s;position:fixed;top:0;left:0;overflow-y:auto;transform:translateY(6px)scale(.98);box-shadow:inset 0 1px #ffffffdb,0 18px 42px #2c373f2e}.custom-context-menu.is-open{opacity:1;pointer-events:auto;transform:translate(0,0)scale(1)}.custom-context-menu [hidden]{display:none!important}.context-menu-nav{grid-template-columns:repeat(4,minmax(0,1fr));gap:6px;padding-bottom:7px;display:grid}.context-menu-group{border-top:1px dashed #686f782e;gap:2px;padding-top:7px;display:grid}.context-menu-group+.context-menu-group{margin-top:7px}.custom-context-menu :where(a,button){width:100%;min-width:0;color:inherit;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;align-items:center;line-height:1.25;display:flex}.contLine truncated
+373
View File
@@ -0,0 +1,373 @@
<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="description" content="关于 Bi's Blog 和站长 biss 的简短介绍。"><meta name="author" content="biss"><link rel="canonical" href="https://blog.biss.click/about/"><link rel="alternate" type="application/rss+xml" title="Bi's Blog RSS" href="https://blog.biss.click/rss.xml"><meta property="og:site_name" content="Bi's Blog"><meta property="og:locale" content="zh_CN"><meta property="og:type" content="website"><meta property="og:title" content="关于 | Bi's Blog"><meta property="og:description" content="关于 Bi's Blog 和站长 biss 的简短介绍。"><meta property="og:url" content="https://blog.biss.click/about/"><meta property="og:image" content="https://free.picui.cn/free/2025/08/10/689845496a283.png"><meta property="og:image:alt" content="关于"><meta name="twitter:card" content="summary_large_image"><meta name="twitter:title" content="关于 | Bi's Blog"><meta name="twitter:description" content="关于 Bi's Blog 和站长 biss 的简短介绍。"><meta name="twitter:image" content="https://free.picui.cn/free/2025/08/10/689845496a283.png"><link rel="icon" href="/images/Bi.ico"><link rel="manifest" href="/manifest.webmanifest"><link rel="apple-touch-icon" href="/images/apple-touch-icon.png"><meta name="theme-color" content="#f7f5ef" media="(prefers-color-scheme: light)"><meta name="theme-color" content="#0b1014" media="(prefers-color-scheme: dark)"><script defer src="https://umami.biss.click/script.js" data-website-id="3d97b310-b241-4fc6-bc9c-68e317fc7d42"></script><script>window.SITE_CONFIG = {"site":{"url":"https://blog.biss.click","name":"Bi's Blog","description":"Personal blog by biss.","language":"zh-CN","domain":"blog.biss.click","slogan":"好奇心转化为代码的空间。","startTime":"2025-01-01T00:00:00+08:00","copyrightStartYear":2025,"license":"内容采用 CC BY-NC-SA 4.0 协议"},"author":{"name":"biss","email":"bishsh2006@gmail.com","github":"https://github.com/bishshi","avatar":"https://free.picui.cn/free/2025/08/10/689845496a283.png"},"comments":{"envId":"https://comment.biss.click","region":"","script":"https://cdn.jsdelivr.net/npm/twikoo@1.7.7/dist/twikoo.min.js"},"analytics":{"umami":{"script":"https://umami.biss.click/script.js","websiteId":"3d97b310-b241-4fc6-bc9c-68e317fc7d42","statsEndpoint":"https://blogumami.biss.click"}},"talks":{"apiUrl":"https://mm.biss.click/api/echo/page","pageSize":30,"homeLimit":6,"cacheKey":"talksCache","cacheTimeKey":"talksCacheTime","cacheDurationMs":1800000,"fallbackAvatar":"https://free.picui.cn/free/2025/08/10/689845496a283.png"},"search":{"apiKey":"2uxQzk7eD2GBCljdSmIiuU3ause7UK9n","server":{"host":"typesense.biss.click","port":"443","protocol":"https"},"indexName":"blogs","searchParams":{"query_by":"title,content","highlight_full_fields":"title,content","per_page":8,"num_typos":1,"typo_tokens_threshold":1,"prefix":true},"ui":{"maxRetries":10,"retryDelay":100,"animationDuration":300,"maxInitRetries":30,"placeholder":"输入关键词寻找故事..."}},"externalLinks":{"waitSeconds":10,"whitelist":["blog.biss.click","biss.click","github.com","localhost","127.0.0.1"]}};</script><script>
(() => {
const storageKey = 'site-theme';
const media = window.matchMedia('(prefers-color-scheme: dark)');
const getSystemTheme = () => (media.matches ? 'dark' : 'light');
const getSavedTheme = () => {
try {
const theme = localStorage.getItem(storageKey);
return theme === 'dark' || theme === 'light' ? theme : null;
} catch {
return null;
}
};
document.documentElement.dataset.theme = getSavedTheme() || getSystemTheme();
})();
</script><link rel="stylesheet" href="https://cdn.jsdmirror.com/npm/instantsearch.css/themes/reset-min.css"><link rel="stylesheet" href="https://cdn.jsdmirror.com/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css"><link rel="stylesheet" href="https://cdn.jsdmirror.com/npm/@fortawesome/fontawesome-free@6.7.2/css/all.min.css"><title>关于 | Bi&#39;s Blog</title><link rel="stylesheet" href="/_astro/BaseLayout.BC0-3eVR.css"></head><body><header class="site-header"><nav class="nav"><a class="brand" href="/" aria-label="Bi's Blog 首页"><span>biss</span><i>.log</i></a><button class="nav-menu-toggle" type="button" aria-label="打开菜单" aria-expanded="false" data-nav-toggle><i class="fa-solid fa-bars nav-menu-open" aria-hidden="true"></i><i class="fa-solid fa-xmark nav-menu-close" aria-hidden="true"></i></button><div class="nav-drawer-backdrop" data-nav-backdrop></div><div class="nav-menu" data-nav-menu><div class="nav-links nav-center"><a href="/archives/"><i class="fa-solid fa-box-archive nav-icon" aria-hidden="true"></i><span>归档</span></a><a href="/categories/"><i class="fa-solid fa-folder-open nav-icon" aria-hidden="true"></i><span>分类</span></a><a href="/tags/"><i class="fa-solid fa-tags nav-icon" aria-hidden="true"></i><span>标签</span></a><a href="/shuoshuo/"><i class="fa-regular fa-comments nav-icon" aria-hidden="true"></i><span>说说</span></a><a href="/about/"><i class="fa-solid fa-heart nav-icon" aria-hidden="true"></i><span>关于</span></a><a href="/link/"><i class="fa-solid fa-link nav-icon" aria-hidden="true"></i><span>友链</span></a></div><div class="nav-links nav-actions"><button class="nav-random" type="button" onclick="randomPost()" aria-label="前往随机文章" title="前往随机文章"><i class="fa-solid fa-shuffle nav-icon" aria-hidden="true"></i><span>随机文章</span></button><button class="nav-search search-typesense-trigger" type="button" aria-label="搜索" title="搜索"><i class="fa-solid fa-magnifying-glass nav-icon" aria-hidden="true"></i><span>搜索</span></button><button class="nav-console" type="button" aria-label="打开中控台" title="中控台" data-console-open><i class="fa-solid fa-gauge-high nav-icon" aria-hidden="true"></i><span>中控台</span></button><button class="theme-toggle" type="button" aria-label="切换夜间模式" title="切换夜间模式" data-theme-toggle><i class="fa-solid fa-sun theme-toggle-sun nav-icon" aria-hidden="true"></i><i class="fa-solid fa-moon theme-toggle-moon nav-icon" aria-hidden="true"></i></button></div></div></nav></header><div class="control-console" data-console-modal aria-hidden="true"><div class="control-console-backdrop" data-console-close></div><section class="control-console-panel" role="dialog" aria-modal="true" aria-labelledby="control-console-title" tabindex="-1"><header class="control-console-head"><div><p>CONTROL CENTER</p><h2 id="control-console-title">中控台</h2></div><button class="control-console-close" type="button" aria-label="关闭中控台" title="关闭" data-console-close><i class="fa-solid fa-xmark" aria-hidden="true"></i></button></header><div class="control-console-grid"><a class="control-site-card" href="https://biss.click" target="_blank" rel="noreferrer"><i class="fa-solid fa-house-chimney" aria-hidden="true"></i><span><strong>主站入口</strong><em>个人主页与常用入口集合</em></span><small>biss.click</small></a><a class="control-site-card" href="https://mm.biss.click" target="_blank" rel="noreferrer"><i class="fa-regular fa-comments" aria-hidden="true"></i><span><strong>说说动态</strong><em>短句、碎片记录和近况更新</em></span><small>mm.biss.click</small></a><a class="control-site-card" href="https://comment.biss.click" target="_blank" rel="noreferrer"><i class="fa-solid fa-message" aria-hidden="true"></i><span><strong>评论系统</strong><em>Twikoo 评论服务与访客互动</em></span><small>comment.biss.click</small></a><a class="control-site-card" href="https://umami.biss.click" target="_blank" rel="noreferrer"><i class="fa-solid fa-chart-line" aria-hidden="true"></i><span><strong>站点统计</strong><em>Umami 访问统计与站点数据</em></span><small>umami.biss.click</small></a></div><div class="control-console-info" aria-label="站点信息"><section><span>当前站点</span><strong>blog.biss.click</strong></section><section><span>站点作者</span><strong>biss</strong></section><section><span>运行起点</span><strong>2025-01-01</strong></section></div></section></div><main><section class="content-wrap page-with-card native-page"><header class="page-header-card"><p class="page-header-eyebrow">Bi&#39;s Blog</p><h1>关于</h1><p class="page-header-subtitle">这里记录折腾、学习和一些普通日子的回声。</p></header><article class="article page-article native-page-article about-page-article"><div class="prose"><p>你好,我是 Bi。这个博客主要用来保存技术实践、生活片段和那些一时半会儿不想让它Line truncated
(() => {
const menu = document.querySelector('[data-context-menu]');
if (!menu) return;
const nativeHint = document.querySelector('[data-context-native-hint]');
const selectionItems = [...menu.querySelectorAll('[data-selection-item]')];
const selectionGroup = menu.querySelector('[data-selection-group]');
const commentsItems = [...menu.querySelectorAll('[data-comments-item]')];
const imageGroup = menu.querySelector('[data-image-group]');
const focusableSelector = 'a[href], button:not([disabled])';
let lastSelectionText = '';
let lastImage = null;
let nativeHintTimer = 0;
const isNativeContextTarget = (target) =>
target instanceof Element &&
Boolean(target.closest('input, textarea, select, [contenteditable="true"], [contenteditable=""]'));
const getCommentsTarget = () =>
document.querySelector('.twikoo-comments, #twikoo-wrap, #twikoo, .tk-comments-container');
const getSelectionText = () => String(window.getSelection?.() || '').trim();
const getImageTarget = (target) => {
if (!(target instanceof Element)) return null;
const image = target.closest('img');
return image instanceof HTMLImageElement ? image : null;
};
const getImageUrl = () => {
if (!lastImage) return '';
return lastImage.currentSrc || lastImage.src || lastImage.getAttribute('src') || '';
};
const copyText = async (text) => {
if (navigator.clipboard?.writeText) {
await navigator.clipboard.writeText(text);
return;
}
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.setAttribute('readonly', '');
textarea.style.position = 'fixed';
textarea.style.inset = '0 auto auto -9999px';
document.body.appendChild(textarea);
textarea.select();
document.execCommand('copy');
textarea.remove();
};
const setMenuState = () => {
const hasSelection = lastSelectionText.length > 0;
const hasComments = Boolean(getCommentsTarget());
const hasImage = Boolean(getImageUrl());
selectionItems.forEach((item) => {
item.hidden = !hasSelection;
});
if (selectionGroup) selectionGroup.hidden = !hasSelection;
commentsItems.forEach((item) => {
item.hidden = !hasComments || (item.hasAttribute('data-selection-item') && !hasSelection);
});
if (imageGroup) imageGroup.hidden = !hasImage;
};
const closeMenu = () => {
menu.classList.remove('is-open');
menu.setAttribute('aria-hidden', 'true');
};
const openMenu = (x, y) => {
setMenuState();
menu.classList.add('is-open');
menu.setAttribute('aria-hidden', 'false');
const rect = menu.getBoundingClientRect();
const gap = 10;
const left = Math.min(Math.max(gap, x), window.innerWidth - rect.width - gap);
const top = Math.min(Math.max(gap, y), window.innerHeight - rect.height - gap);
menu.style.left = `${left}px`;
menu.style.top = `${top}px`;
};
const showNativeHint = () => {
if (!nativeHint) return;
window.clearTimeout(nativeHintTimer);
nativeHint.classList.add('is-visible');
nativeHintTimer = window.setTimeout(() => {
nativeHint.classList.remove('is-visible');
}, 2600);
};
const jumpToComments = () => {
const target = getCommentsTarget();
target?.scrollIntoView({ behavior: 'smooth', block: 'start' });
};
const quoteToComments = () => {
jumpToComments();
window.setTimeout(() => {
const textarea = document.querySelector('#twikoo textarea, .twikoo-comments textarea, .tk-input textarea');
if (!(textarea instanceof HTMLTextAreaElement) || !lastSelectionText) return;
const quote = lastSelectionText
.split(/\r?\n/)
.map((line) => `> ${line}`)
.join('\n');
const current = textarea.value.trim();
textarea.value = current ? `${current}\n\n${quote}\n` : `${quote}\n`;
textarea.dispatchEvent(new Event('input', { bubbles: true }));
textarea.focus();
}, 500);
};
const searchSelection = () => {
if (!lastSelectionText) return;
const url = `https://www.bing.com/search?q=${encodeURIComponent(lastSelectionText)}`;
window.open(url, '_blank', 'noopener,noreferrer');
};
const copyImage = async () => {
const imageUrl = getImageUrl();
if (!imageUrl) return;
try {
if (!navigator.clipboard?.write || typeof ClipboardItem === 'undefined') {
throw new Error('Image clipboard is not available.');
}
const response = await fetch(imageUrl, { mode: 'cors' });
const blob = await response.blob();
await navigator.clipboard.write([
new ClipboardItem({ [blob.type || 'image/png']: blob }),
]);
} catch {
await copyText(new URL(imageUrl, window.location.href).toString());
}
};
const openImage = () => {
const imageUrl = getImageUrl();
if (!imageUrl) return;
window.open(new URL(imageUrl, window.location.href).toString(), '_blank', 'noopener,noreferrer');
};
document.addEventListener('contextmenu', (event) => {
if (event.ctrlKey) {
closeMenu();
nativeHint?.classList.remove('is-visible');
return;
}
if (isNativeContextTarget(event.target)) return;
lastSelectionText = getSelectionText();
lastImage = getImageTarget(event.target);
event.preventDefault();
openMenu(event.clientX, event.clientY);
showNativeHint();
});
document.addEventListener('click', (event) => {
const actionTarget = event.target instanceof Element ? event.target.closest('[data-context-action]') : null;
if (!actionTarget || !menu.contains(actionTarget)) {
closeMenu();
return;
}
const action = actionTarget.dataset.contextAction;
closeMenu();
if (action === 'back') history.back();
if (action === 'forward') history.forward();
if (action === 'reload') location.reload();
if (action === 'copy-selection' && lastSelectionText) copyText(lastSelectionText);
if (action === 'search-selection') searchSelection();
if (action === 'quote-selection') quoteToComments();
if (action === 'copy-image') copyImage();
if (action === 'open-image') openImage();
if (action === 'copy-image-url') copyText(new URL(getImageUrl(), window.location.href).toString());
if (action === 'random-post' && typeof window.randomPost === 'function') window.randomPost(actionTarget);
if (action === 'comments') jumpToComments();
if (action === 'print') window.print();
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape') closeMenu();
if (event.key === 'Tab' && menu.classList.contains('is-open')) {
const items = [...menu.querySelectorAll(focusableSelector)].filter((item) => !item.closest('[hidden]'));
if (items.length === 0) return;
const first = items[0];
const last = items[items.length - 1];
if (event.shiftKey && document.activeElement === first) {
event.preventDefault();
last.focus();
} else if (!event.shiftKey && document.activeElement === last) {
event.preventDefault();
first.focus();
}
}
});
window.addEventListener('scroll', closeMenu, { passive: true });
window.addEventListener('resize', closeMenu);
})();
</script><aside class="pwa-toast" data-pwa-toast hidden role="status" aria-live="polite"><div class="pwa-toast-icon" aria-hidden="true"><i class="fa-solid fa-download"></i></div><div class="pwa-toast-copy"><strong data-pwa-title>PWA 提示</strong><p data-pwa-message></p></div><div class="pwa-toast-actions"><button class="pwa-toast-primary" type="button" data-pwa-primary>确定</button><button class="pwa-toast-close" type="button" data-pwa-close aria-label="关闭提示">稍后</button></div></aside><script src="https://cdn.jsdmirror.com/npm/instantsearch.js@4.56.0"></script><script src="https://cdn.jsdmirror.com/npm/typesense-instantsearch-adapter@2.7.0/dist/typesense-instantsearch-adapter.min.js"></script><script src="https://cdn.jsdmirror.com/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.umd.js"></script><script src="/js/random.js"></script><script src="/js/search/typesense-search.js"></script><script src="/js/external-links.js"></script><script src="/js/pwa.js"></script><script>
(() => {
const nav = document.querySelector('.nav');
const toggle = document.querySelector('[data-nav-toggle]');
const menu = document.querySelector('[data-nav-menu]');
const backdrop = document.querySelector('[data-nav-backdrop]');
if (!nav || !toggle || !menu) return;
function setMenu(open) {
nav.classList.toggle('is-open', open);
toggle.setAttribute('aria-expanded', String(open));
toggle.setAttribute('aria-label', open ? '关闭菜单' : '打开菜单');
menu.setAttribute('aria-hidden', String(!open && window.innerWidth <= 720));
document.body.classList.toggle('has-nav-drawer', open);
}
toggle.addEventListener('click', () => {
setMenu(!nav.classList.contains('is-open'));
});
backdrop?.addEventListener('click', () => setMenu(false));
menu.addEventListener('click', (event) => {
if (event.target instanceof Element && event.target.closest('a')) setMenu(false);
});
document.addEventListener('click', (event) => {
if (!nav.classList.contains('is-open')) return;
if (event.target instanceof Node && nav.contains(event.target)) return;
setMenu(false);
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape' && nav.classList.contains('is-open')) setMenu(false);
});
window.addEventListener('resize', () => {
if (window.innerWidth > 720) setMenu(false);
else menu.setAttribute('aria-hidden', String(!nav.classList.contains('is-open')));
});
menu.setAttribute('aria-hidden', String(window.innerWidth <= 720));
})();
(() => {
const modal = document.querySelector('[data-console-modal]');
const panel = modal?.querySelector('.control-console-panel');
const openButtons = document.querySelectorAll('[data-console-open]');
const closeButtons = modal?.querySelectorAll('[data-console-close]') || [];
if (!modal || !panel || openButtons.length === 0) return;
function setConsole(open) {
modal.classList.toggle('is-open', open);
modal.setAttribute('aria-hidden', String(!open));
document.body.classList.toggle('has-control-console', open);
if (open) panel.focus();
}
openButtons.forEach((button) => {
button.addEventListener('click', () => setConsole(true));
});
closeButtons.forEach((button) => {
button.addEventListener('click', () => setConsole(false));
});
document.addEventListener('keydown', (event) => {
if (event.key === 'Escape' && modal.classList.contains('is-open')) setConsole(false);
});
})();
(() => {
const storageKey = 'site-theme';
const root = document.documentElement;
const button = document.querySelector('[data-theme-toggle]');
const media = window.matchMedia('(prefers-color-scheme: dark)');
const getSystemTheme = () => (media.matches ? 'dark' : 'light');
const getSavedTheme = () => {
try {
const theme = localStorage.getItem(storageKey);
return theme === 'dark' || theme === 'light' ? theme : null;
} catch {
return null;
}
};
const setSavedTheme = (theme) => {
try {
if (theme === getSystemTheme()) localStorage.removeItem(storageKey);
else localStorage.setItem(storageKey, theme);
} catch {
// localStorage can be unavailable in strict privacy modes.
}
};
const getTheme = () => getSavedTheme() || getSystemTheme();
function applyTheme(theme) {
root.dataset.theme = theme;
root.dataset.themeMode = getSavedTheme() ? 'manual' : 'auto';
button?.setAttribute('aria-label', theme === 'dark' ? '切换到日间模式' : '切换到夜间模式');
button?.setAttribute(
'title',
getSavedTheme()
? (theme === 'dark' ? '切换到日间模式' : '切换到夜间模式')
: `跟随系统:${theme === 'dark' ? '夜间' : '日间'}模式`
);
}
applyTheme(getTheme());
button?.addEventListener('click', () => {
const nextTheme = root.dataset.theme === 'dark' ? 'light' : 'dark';
setSavedTheme(nextTheme);
applyTheme(nextTheme);
});
const handleSystemThemeChange = () => {
if (!getSavedTheme()) applyTheme(getSystemTheme());
};
if (typeof media.addEventListener === 'function') {
media.addEventListener('change', handleSystemThemeChange);
} else if (typeof media.addListener === 'function') {
media.addListener(handleSystemThemeChange);
}
})();
(() => {
const runtime = document.getElementById('site-runtime');
if (!runtime) return;
const start = new Date(window.SITE_CONFIG.site.startTime).getTime();
const pad = (value) => String(value).padStart(2, '0');
function updateRuntime() {
const diff = Math.max(0, Date.now() - start);
const days = Math.floor(diff / 86400000);
const hours = Math.floor((diff / 3600000) % 24);
const minutes = Math.floor((diff / 60000) % 60);
const seconds = Math.floor((diff / 1000) % 60);
runtime.textContent = `${days} 天 ${pad(hours)} 时 ${pad(minutes)} 分 ${pad(seconds)} 秒`;
}
updateRuntime();
window.setInterval(updateRuntime, 1000);
})();
</script></body></html>
+1
View File
@@ -0,0 +1 @@
[{"title":"从间接平差到程序:一个水准网最小二乘解算案例","href":"/posts/e67166f3/"},{"title":"网站迁移日志","href":"/posts/8f3b9d21/"},{"title":"用 Umami 分享链接给网站信息卡提供统计数据","href":"/posts/4c91a8f2/"},{"title":"把普通的一天过成自己的节奏","href":"/posts/efe1e805/"},{"title":"GPT Image2 初试","href":"/posts/3f8de22/"},{"title":"电子价签玩法","href":"/posts/8712baaa/"},{"title":"OpenGL- Cohen-Sutherland 编码裁剪算法","href":"/posts/9b2ef00a/"},{"title":"OpenGL-直线的扫描转换","href":"/posts/7207243b/"},{"title":"OpenGL-基础程序","href":"/posts/437a5198/"},{"title":"配置OpenGL环境","href":"/posts/c4477b0c/"},{"title":"opencv应用-算术运算","href":"/posts/b559997d/"},{"title":"opencv应用-基础操作","href":"/posts/e8f95ead/"},{"title":"配置opencv","href":"/posts/6e3332b/"},{"title":"自建bitwarden服务","href":"/posts/7baa41fc/"},{"title":"自建renovate-bot","href":"/posts/56f57c0b/"},{"title":"新年快乐!","href":"/posts/5785bd01/"},{"title":"添加网站左上角菜单","href":"/posts/7e921903/"},{"title":"将博客仓库转移到gitea","href":"/posts/d2c8521/"},{"title":"安装gitea","href":"/posts/34725d47/"},{"title":"添加typesense搜索","href":"/posts/f287c563/"},{"title":"自定义字体","href":"/posts/b5601a7e/"},{"title":"在侧边栏添加日历和倒计时","href":"/posts/5ed2f1e6/"},{"title":"和朋友们的故事","href":"/posts/a31d95d9/"},{"title":"Adguard和Openclash共存","href":"/posts/66e66374/"},{"title":"Adguard规则分享","href":"/posts/69b16001/"},{"title":"在Openwrt上安装AdguardHome","href":"/posts/b57500e9/"},{"title":"在Openwrt中安装OpenClash","href":"/posts/2b2fb1a7/"},{"title":"Cudy TR3000刷入Openwrt系统","href":"/posts/8802e397/"},{"title":"搭建Owncloud并集成Onlyoffice","href":"/posts/59c8572a/"},{"title":"为博客添加CMS系统","href":"/posts/3a26a97a/"},{"title":"为1Panel添加自己想要的应用","href":"/posts/bb18d851/"},{"title":"使用GitHub推送Hexo到服务器","href":"/posts/ce1ec3fe/"},{"title":"C# 基本语法","href":"/posts/e9a8e898/"},{"title":"C# 入门","href":"/posts/bc56f789/"},{"title":"自定义页脚(新)","href":"/posts/c6143ad3/"},{"title":"自定义分类条","href":"/posts/33249733/"},{"title":"自定义导航栏","href":"/posts/3e61a389/"},{"title":"利用 SiteMap 随机访问站内页面","href":"/posts/b5866b9e/"},{"title":"博客添加AI总结","href":"/posts/41b9aff7/"},{"title":"利用插件自定义页脚菜单","href":"/posts/a6ab0925/"},{"title":"英语文章分享-去奋力生活吧,就好像死亡近在咫尺","href":"/posts/f0a1a1f4/"},{"title":"自定义右键菜单","href":"/posts/8bdb35fb/"},{"title":"在侧边栏中添加欢迎信息","href":"/posts/da17d00/"},{"title":"配置说说页面","href":"/posts/ad244066/"},{"title":"部署历程","href":"/posts/6e5f5039/"}]
Loaded 3 of 117 files, more files were not shown because too many files have changed in this diff. Show more