2026-03-24 17:33:01 +00:00
|
|
|
---
|
2026-03-24 22:28:23 +00:00
|
|
|
import Footer from "@/components/Footer.astro";
|
2026-03-24 18:01:45 +00:00
|
|
|
import Header from "@/components/Header.astro";
|
2026-03-24 22:50:33 +00:00
|
|
|
import { ClientRouter } from "astro:transitions";
|
2026-04-17 10:42:26 +00:00
|
|
|
import { fade } from "astro:transitions";
|
|
|
|
|
import { getLangFromUrl } from "@/i18n";
|
2026-06-01 09:50:06 +00:00
|
|
|
import "katex/dist/katex.min.css";
|
2026-04-17 10:42:26 +00:00
|
|
|
|
|
|
|
|
const lang = getLangFromUrl(Astro.url);
|
|
|
|
|
const htmlLang = lang === "zh" ? "zh-CN" : "en-US";
|
2026-03-25 15:26:22 +00:00
|
|
|
import SEO from "@/components/SEO.astro";
|
2026-04-13 20:24:35 +00:00
|
|
|
import FloatingActions from "@/components/FloatingActions.astro";
|
2026-04-13 20:47:23 +00:00
|
|
|
import Spinner from "@/components/Spinner.astro";
|
2026-03-24 19:32:44 +00:00
|
|
|
|
2026-03-26 16:25:07 +00:00
|
|
|
const {
|
|
|
|
|
pageTitle,
|
|
|
|
|
description = "在这里,发现更多(雾)欢迎来到三叶的博客🥳",
|
|
|
|
|
image,
|
|
|
|
|
} = Astro.props;
|
2026-03-24 17:33:01 +00:00
|
|
|
---
|
|
|
|
|
|
2026-03-24 14:19:09 +00:00
|
|
|
<!doctype html>
|
2026-04-17 10:42:26 +00:00
|
|
|
<html lang={htmlLang}>
|
2026-03-24 14:19:09 +00:00
|
|
|
<head>
|
2026-04-13 19:35:33 +00:00
|
|
|
<ClientRouter />
|
2026-03-24 14:19:09 +00:00
|
|
|
<meta charset="UTF-8" />
|
|
|
|
|
<meta name="viewport" content="width=device-width" />
|
2026-03-25 15:26:22 +00:00
|
|
|
<SEO title={pageTitle} description={description} image={image} />
|
2026-03-24 14:19:09 +00:00
|
|
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
|
|
|
<link rel="icon" href="/favicon.ico" />
|
2026-04-17 11:02:45 +00:00
|
|
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
|
|
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
|
|
|
<link
|
|
|
|
|
href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;700&display=swap"
|
|
|
|
|
rel="stylesheet"
|
|
|
|
|
/>
|
2026-04-17 18:56:28 +00:00
|
|
|
<link
|
|
|
|
|
href="https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@400;500;700&display=swap"
|
|
|
|
|
rel="stylesheet"
|
|
|
|
|
/>
|
2026-03-24 14:19:09 +00:00
|
|
|
<meta name="generator" content={Astro.generator} />
|
2026-03-24 17:33:01 +00:00
|
|
|
<title>{pageTitle}</title>
|
2026-03-24 14:19:09 +00:00
|
|
|
</head>
|
2026-04-13 20:24:35 +00:00
|
|
|
<FloatingActions />
|
2026-07-18 09:18:43 +00:00
|
|
|
<script is:inline>
|
|
|
|
|
function addCodeCopyButtons() {
|
|
|
|
|
document.querySelectorAll("pre").forEach((pre) => {
|
|
|
|
|
const code = pre.querySelector("code");
|
|
|
|
|
if (!code) return;
|
|
|
|
|
|
2026-08-05 04:33:47 +00:00
|
|
|
/* 已经处理过则跳过 */
|
|
|
|
|
if (
|
|
|
|
|
pre.parentElement?.classList.contains("code-block-wrapper")
|
|
|
|
|
) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 创建外层容器 */
|
|
|
|
|
const wrapper = document.createElement("div");
|
|
|
|
|
wrapper.className = "code-block-wrapper";
|
|
|
|
|
|
|
|
|
|
pre.parentNode?.insertBefore(wrapper, pre);
|
|
|
|
|
wrapper.appendChild(pre);
|
|
|
|
|
|
|
|
|
|
/* 创建复制按钮 */
|
2026-07-18 09:18:43 +00:00
|
|
|
const button = document.createElement("button");
|
|
|
|
|
button.className = "code-copy-button";
|
|
|
|
|
button.type = "button";
|
|
|
|
|
button.setAttribute("aria-label", "复制代码");
|
|
|
|
|
button.title = "复制代码";
|
|
|
|
|
|
|
|
|
|
const icon = document.createElement("img");
|
|
|
|
|
icon.className = "code-copy-icon";
|
|
|
|
|
icon.src = "/images/copy-svgrepo-com.svg";
|
|
|
|
|
icon.alt = "";
|
|
|
|
|
icon.setAttribute("aria-hidden", "true");
|
|
|
|
|
|
|
|
|
|
button.appendChild(icon);
|
2026-08-05 04:33:47 +00:00
|
|
|
wrapper.appendChild(button);
|
2026-07-18 09:18:43 +00:00
|
|
|
|
|
|
|
|
button.addEventListener("click", async () => {
|
|
|
|
|
const text = code.textContent ?? "";
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
await navigator.clipboard.writeText(text);
|
|
|
|
|
} catch {
|
|
|
|
|
const textarea = document.createElement("textarea");
|
|
|
|
|
textarea.value = text;
|
|
|
|
|
textarea.style.position = "fixed";
|
|
|
|
|
textarea.style.opacity = "0";
|
2026-08-05 04:33:47 +00:00
|
|
|
textarea.style.pointerEvents = "none";
|
2026-07-18 09:18:43 +00:00
|
|
|
|
|
|
|
|
document.body.appendChild(textarea);
|
|
|
|
|
textarea.select();
|
|
|
|
|
document.execCommand("copy");
|
|
|
|
|
textarea.remove();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
icon.src = "/images/correct-signal-svgrepo-com.svg";
|
|
|
|
|
button.setAttribute("aria-label", "已复制");
|
|
|
|
|
button.title = "已复制";
|
|
|
|
|
button.classList.add("copied");
|
|
|
|
|
|
|
|
|
|
window.setTimeout(() => {
|
|
|
|
|
icon.src = "/images/copy-svgrepo-com.svg";
|
|
|
|
|
button.setAttribute("aria-label", "复制代码");
|
|
|
|
|
button.title = "复制代码";
|
|
|
|
|
button.classList.remove("copied");
|
|
|
|
|
}, 1500);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
addCodeCopyButtons();
|
|
|
|
|
document.addEventListener("astro:page-load", addCodeCopyButtons);
|
|
|
|
|
</script>
|
2026-04-13 20:47:23 +00:00
|
|
|
|
2026-03-24 14:19:09 +00:00
|
|
|
<body>
|
2026-03-24 18:01:45 +00:00
|
|
|
<Header />
|
2026-04-13 20:47:23 +00:00
|
|
|
<Spinner />
|
|
|
|
|
<main
|
|
|
|
|
class="page-content"
|
|
|
|
|
transition:animate={fade({ duration: "0.05s" })}
|
|
|
|
|
>
|
2026-03-24 22:50:33 +00:00
|
|
|
<slot />
|
|
|
|
|
</main>
|
2026-03-24 17:33:01 +00:00
|
|
|
<Footer />
|
2026-03-24 14:19:09 +00:00
|
|
|
</body>
|
|
|
|
|
</html>
|
|
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
html,
|
|
|
|
|
body {
|
|
|
|
|
margin: 0;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
}
|
|
|
|
|
</style>
|