Forgor to publish a bit
18
.oxfmtrc.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"$schema": "./node_modules/oxfmt/configuration_schema.json",
|
||||
"printWidth": 100,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all",
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "always",
|
||||
"endOfLine": "lf",
|
||||
"insertFinalNewline": true,
|
||||
"ignorePatterns": [
|
||||
"node_modules/**",
|
||||
".cache/**",
|
||||
"_site/**"
|
||||
]
|
||||
}
|
||||
24
.oxlintrc.json
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"$schema": "./node_modules/oxlint/configuration_schema.json",
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true,
|
||||
"es2024": true
|
||||
},
|
||||
"plugins": ["typescript", "react", "unicorn", "import", "oxc"],
|
||||
"categories": {
|
||||
"correctness": "error",
|
||||
"suspicious": "warn",
|
||||
"perf": "warn"
|
||||
},
|
||||
"rules": {
|
||||
"eqeqeq": "error",
|
||||
"no-unused-vars": "off",
|
||||
"typescript/no-unused-vars": "warn",
|
||||
"typescript/no-explicit-any": "warn",
|
||||
"import/no-cycle": "error",
|
||||
"prefer-const": ["error", { "ignoreReadBeforeAssign": true }],
|
||||
"react/react-in-jsx-scope": "allow"
|
||||
},
|
||||
"ignorePatterns": ["node_modules/**", ".cache/**", "_site/**"]
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
import { getAllPostSlugs, getPostBySlug } from "@/lib/posts"
|
||||
import type { Metadata } from "next"
|
||||
import readingTime from "reading-time"
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return getAllPostSlugs().map((slug) => ({ slug }))
|
||||
}
|
||||
|
||||
export const dynamicParams = false
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ slug: string }>
|
||||
}): Promise<Metadata> {
|
||||
const { slug } = await params
|
||||
const { meta } = await getPostBySlug(slug)
|
||||
return { title: meta.title, description: meta.description }
|
||||
}
|
||||
|
||||
export default async function Post({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ slug: string }>
|
||||
}) {
|
||||
const { slug } = await params
|
||||
const { meta, contentHtml } = await getPostBySlug(slug)
|
||||
|
||||
return (
|
||||
<article className="prose mx-auto my-8 max-w-3xl px-4">
|
||||
<h1>{meta.title}</h1>
|
||||
<time>{new Date(meta.date).toLocaleTimeString()}</time>
|
||||
<span>{readingTime(contentHtml).text}</span>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{ __html: contentHtml }}
|
||||
className="custom-prose"
|
||||
/>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
37
app/categories/[category]/page.tsx
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import { getAllPostsMeta } from "@/lib/posts"
|
||||
import type { Metadata } from "next"
|
||||
import Link from "next/link"
|
||||
|
||||
type CategoryPageProps = {
|
||||
params: Promise<{
|
||||
category: string
|
||||
}>
|
||||
}
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: CategoryPageProps): Promise<Metadata> {
|
||||
const { category } = await params
|
||||
return { title: `Category: ${category}`, description: "List of posts in this category" }
|
||||
}
|
||||
|
||||
export default async function CategoryPage({
|
||||
params,
|
||||
}: CategoryPageProps) {
|
||||
const { category } = await params
|
||||
const posts = getAllPostsMeta()
|
||||
return (
|
||||
<main>
|
||||
<h1>Category: {category}</h1>
|
||||
<ul>
|
||||
{posts
|
||||
.filter((post) => post.categories.includes(category))
|
||||
.map((post) => (
|
||||
<li key={post.slug}>
|
||||
<Link href={`/${post.slug}`}>{post.title}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,29 +1,56 @@
|
|||
import meta from "@/const/meta"
|
||||
import { getAllPostsMeta } from "@/lib/posts"
|
||||
|
||||
const SITE_URL = process.env.SITE_URL || "http://localhost:3000"
|
||||
|
||||
function escapeXml(str: string) {
|
||||
return str
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'")
|
||||
}
|
||||
|
||||
export async function GET() {
|
||||
const posts = getAllPostsMeta()
|
||||
const items = posts
|
||||
.map(
|
||||
(p) => `
|
||||
<item>
|
||||
<title>${p.title}</title>
|
||||
<link>https://yourdomain.com/blog/${p.slug}</link>
|
||||
<description>${p.description}</description>
|
||||
<pubDate>${new Date(p.date).toUTCString()}</pubDate>
|
||||
</item>`,
|
||||
)
|
||||
|
||||
const updated =
|
||||
posts.length > 0
|
||||
? new Date(posts[0].date).toISOString()
|
||||
: new Date().toISOString()
|
||||
|
||||
const entries = posts
|
||||
.map((p) => {
|
||||
const url = `${SITE_URL}/posts/${p.slug}`
|
||||
const date = new Date(p.date).toISOString()
|
||||
return `
|
||||
<entry>
|
||||
<title>${escapeXml(p.title)}</title>
|
||||
<link href="${url}" rel="alternate" type="text/html" />
|
||||
<id>${url}</id>
|
||||
<published>${date}</published>
|
||||
<updated>${date}</updated>
|
||||
<content type="html" src="${url}" />
|
||||
<summary>${escapeXml(p.description)}</summary>
|
||||
</entry>`
|
||||
})
|
||||
.join("")
|
||||
|
||||
const feed = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<rss version="2.0"><channel>
|
||||
<title>${meta.title}</title>
|
||||
<link>https://yourdomain.com</link>
|
||||
<description>Latest posts</description>
|
||||
${items}
|
||||
</channel></rss>`
|
||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||
<title>${escapeXml(meta.title)}</title>
|
||||
<id>${SITE_URL}/</id>
|
||||
<updated>${updated}</updated>
|
||||
<author>
|
||||
<name>${escapeXml("d")}</name>
|
||||
</author>
|
||||
<link href="${SITE_URL}/feed" rel="self" type="application/atom+xml" />
|
||||
<link href="${SITE_URL}" rel="alternate" type="text/html" />
|
||||
${entries}
|
||||
</feed>`
|
||||
|
||||
return new Response(feed, {
|
||||
headers: { "Content-Type": "application/xml" },
|
||||
headers: { "Content-Type": "application/atom+xml; charset=utf-8" },
|
||||
})
|
||||
}
|
||||
}
|
||||
203
app/globals.css
|
|
@ -1,31 +1,34 @@
|
|||
@import "tailwindcss";
|
||||
@import 'tailwindcss';
|
||||
@import '../node_modules/highlight.js/styles/monokai.min.css';
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
@theme {
|
||||
--color-bg: #040404;
|
||||
--color-fg: #e0e0e0;
|
||||
--color-fg-dim: #909090;
|
||||
--color-accent: #ef1f1f;
|
||||
--color-border: #374151;
|
||||
|
||||
--color-warning: #facc15;
|
||||
--color-tip: #22c55e;
|
||||
--color-info: #3b82f6;
|
||||
--color-note: #8b5cf6;
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
.hljs {
|
||||
@apply bg-transparent;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
}
|
||||
pre code.hljs {
|
||||
@apply p-0;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
@apply bg-bg text-fg;
|
||||
}
|
||||
|
||||
.custom-prose {
|
||||
.prose {
|
||||
@apply space-y-4;
|
||||
|
||||
ul {
|
||||
@apply list-disc list-inside;
|
||||
}
|
||||
|
|
@ -38,3 +41,167 @@ body {
|
|||
@apply mb-1;
|
||||
}
|
||||
}
|
||||
|
||||
.categories::before {
|
||||
@apply content-['$'] text-accent;
|
||||
}
|
||||
|
||||
.handle::before {
|
||||
@apply content-['@'] text-current;
|
||||
}
|
||||
|
||||
/* ── Mark ────────────────────────────── */
|
||||
|
||||
mark {
|
||||
@apply bg-accent/20 px-1 py-0.5 rounded text-accent;
|
||||
}
|
||||
|
||||
/* ── Tables ────────────────────────────────────────── */
|
||||
|
||||
table {
|
||||
@apply border-collapse w-full;
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
@apply border border-border px-4 py-2;
|
||||
}
|
||||
|
||||
th {
|
||||
@apply bg-fg/10;
|
||||
}
|
||||
|
||||
tbody tr:nth-child(even) {
|
||||
@apply bg-fg/5;
|
||||
}
|
||||
|
||||
/* ── Definition lists ─────────────────────────────── */
|
||||
|
||||
dl {
|
||||
@apply my-4;
|
||||
}
|
||||
|
||||
dt {
|
||||
@apply font-semibold text-fg mt-3;
|
||||
}
|
||||
|
||||
dt:first-child {
|
||||
@apply mt-0;
|
||||
}
|
||||
|
||||
dd {
|
||||
@apply ml-6 pl-3 border-l-2 border-fg/20 text-fg-dim;
|
||||
}
|
||||
|
||||
/* ── Prose (markdown) content ─────────────────────── */
|
||||
|
||||
.prose h1 {
|
||||
@apply text-3xl md:text-4xl;
|
||||
}
|
||||
|
||||
.prose h2 {
|
||||
@apply text-2xl md:text-3xl;
|
||||
}
|
||||
|
||||
.prose h3 {
|
||||
@apply text-xl md:text-2xl;
|
||||
}
|
||||
|
||||
.prose h4 {
|
||||
@apply text-lg md:text-xl;
|
||||
}
|
||||
|
||||
.prose h5 {
|
||||
@apply text-base md:text-lg;
|
||||
}
|
||||
|
||||
.prose h6 {
|
||||
@apply text-sm md:text-base;
|
||||
}
|
||||
|
||||
.prose h1,
|
||||
.prose h2,
|
||||
.prose h3,
|
||||
.prose h4,
|
||||
.prose h5,
|
||||
.prose h6 {
|
||||
@apply font-bold mb-2;
|
||||
|
||||
&::before {
|
||||
@apply content-['#'] text-accent mr-1;
|
||||
}
|
||||
}
|
||||
|
||||
.prose code:not(pre code) {
|
||||
@apply text-sm bg-fg/10 px-1 py-0.5 rounded;
|
||||
}
|
||||
|
||||
.prose a {
|
||||
@apply text-accent;
|
||||
}
|
||||
|
||||
.prose ul:not(.task-list-container) {
|
||||
@apply list-disc pl-6;
|
||||
}
|
||||
|
||||
hr {
|
||||
@apply text-border;
|
||||
}
|
||||
|
||||
/* Only ol that do not include checkboxes */
|
||||
.prose ol {
|
||||
@apply list-decimal pl-6;
|
||||
}
|
||||
|
||||
/* ── Task lists ────────────────────────────────────── */
|
||||
|
||||
.task-list-item {
|
||||
@apply list-none ml-0 pl-0;
|
||||
}
|
||||
|
||||
.task-list-item input[type='checkbox'] {
|
||||
@apply mr-2 accent-accent w-4 h-4 align-middle cursor-pointer;
|
||||
}
|
||||
|
||||
.task-list-item input[type='checkbox']:checked + label,
|
||||
.task-list-item input[type='checkbox'][checked] + label {
|
||||
@apply text-fg-dim line-through;
|
||||
}
|
||||
|
||||
/* ── Footnotes ─────────────────────────────────────── */
|
||||
|
||||
.footnotes {
|
||||
@apply text-sm italic text-fg-dim pt-4 mt-4 border-t border-border;
|
||||
}
|
||||
|
||||
.footnotes ol {
|
||||
@apply space-y-2;
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
@apply sr-only;
|
||||
}
|
||||
|
||||
.note {
|
||||
@apply border-l-4 pl-4 py-1 text-fg-dim bg-accent/20;
|
||||
|
||||
&.warning {
|
||||
@apply border-warning bg-warning/20 text-warning;
|
||||
}
|
||||
|
||||
&.tip {
|
||||
@apply border-tip bg-tip/20 text-tip;
|
||||
}
|
||||
|
||||
&.info {
|
||||
@apply border-info bg-info/20 text-info;
|
||||
}
|
||||
}
|
||||
|
||||
.no-js .js-only {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
#mermaid-diagram {
|
||||
@apply mx-auto;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,18 @@
|
|||
import { Geist, Geist_Mono } from "next/font/google"
|
||||
import "./globals.css"
|
||||
import { Metadata } from "next"
|
||||
import meta from "@/const/meta"
|
||||
import { Geist, Geist_Mono } from 'next/font/google'
|
||||
import './globals.css'
|
||||
import { Metadata } from 'next'
|
||||
import meta from '@/const/meta'
|
||||
import Script from 'next/script'
|
||||
import { Sidebar } from '@/components/layout/Sidebar'
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
subsets: ["latin"],
|
||||
variable: '--font-geist-sans',
|
||||
subsets: ['latin'],
|
||||
})
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
variable: "--font-geist-mono",
|
||||
subsets: ["latin"],
|
||||
variable: '--font-geist-mono',
|
||||
subsets: ['latin'],
|
||||
})
|
||||
|
||||
export const metadata: Metadata = {
|
||||
|
|
@ -27,9 +29,17 @@ export default function RootLayout({
|
|||
return (
|
||||
<html
|
||||
lang="en"
|
||||
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
|
||||
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased no-js`}
|
||||
>
|
||||
<body className="min-h-full flex flex-col">{children}</body>
|
||||
<Script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `document.documentElement.classList.replace('no-js','js')`,
|
||||
}}
|
||||
/>
|
||||
<body className="min-h-full flex">
|
||||
<Sidebar />
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ export default function BlogIndex() {
|
|||
<ul>
|
||||
{posts.map((post) => (
|
||||
<li key={post.slug}>
|
||||
<Link href={`/${post.slug}`}>{post.title}</Link>
|
||||
<Link href={`/posts/${post.slug}`}>{post.title}</Link>
|
||||
<p>{post.description}</p>
|
||||
</li>
|
||||
))}
|
||||
|
|
|
|||
54
app/posts/[slug]/page.tsx
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
import { ImageWrapper } from '@/components/common/ImageWrapper'
|
||||
import { TableOfContents } from '@/components/common/TableOfContents'
|
||||
import { getAllPostSlugs, getPostBySlug } from '@/lib/posts'
|
||||
import type { Metadata } from 'next'
|
||||
|
||||
export async function generateStaticParams() {
|
||||
return getAllPostSlugs().map((slug) => ({ slug }))
|
||||
}
|
||||
|
||||
export const dynamicParams = false
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ slug: string }>
|
||||
}): Promise<Metadata> {
|
||||
const { slug } = await params
|
||||
const { meta } = await getPostBySlug(slug)
|
||||
return { title: meta.title, description: meta.description }
|
||||
}
|
||||
|
||||
export default async function Post({ params }: { params: Promise<{ slug: string }> }) {
|
||||
const { slug } = await params
|
||||
const { meta, content, tableOfContents } = await getPostBySlug(slug)
|
||||
|
||||
return (
|
||||
<article className="flex w-full">
|
||||
<main className="max-w-3xl mx-auto px-4 py-8 lg:py-16">
|
||||
{meta.categories.length > 0 && (
|
||||
<div className="flex flex-wrap gap-2 mb-2">
|
||||
{meta.categories.map((category) => (
|
||||
<span
|
||||
key={category}
|
||||
className="bg-accent/20 text-accent px-2 py-1 rounded-full text-sm"
|
||||
>
|
||||
{category}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<h1 className="text-5xl font-bold mb-4">{meta.title}</h1>
|
||||
<span>{meta.readingTimeText}</span>
|
||||
<time>{new Date(meta.date).toLocaleDateString()}</time>
|
||||
<p>{meta.description}</p>
|
||||
{meta.coverImage && <ImageWrapper src={meta.coverImage} alt={meta.coverImageAlt} />}
|
||||
<div className="prose">{content}</div>
|
||||
</main>
|
||||
|
||||
<aside className="hidden lg:block w-80">
|
||||
<TableOfContents items={tableOfContents} />
|
||||
</aside>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
import { getPostsByTag } from "@/lib/posts"
|
||||
import type { Metadata } from "next"
|
||||
import Link from "next/link"
|
||||
|
||||
export const dynamicParams = false
|
||||
|
||||
export async function generateMetadata({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ tag: string }>
|
||||
}): Promise<Metadata> {
|
||||
const { tag } = await params
|
||||
return { title: `Tag: ${tag}`, description: `Posts tagged with ${tag}` }
|
||||
}
|
||||
|
||||
export default async function Post({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ tag: string }>
|
||||
}) {
|
||||
const { tag } = await params
|
||||
const posts = getPostsByTag(tag)
|
||||
|
||||
return (
|
||||
<main>
|
||||
<h1>Posts tagged with {tag}</h1>
|
||||
<ul className="flex flex-wrap gap-2">
|
||||
{posts.map((post) => (
|
||||
<li
|
||||
key={post.slug}
|
||||
className="rounded bg-gray-200 px-2 py-1 text-sm text-gray-800"
|
||||
>
|
||||
<Link href={`/${post.slug}`}>{post.title}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
import { getAllPostsMeta } from "@/lib/posts"
|
||||
import type { Metadata } from "next"
|
||||
import Link from "next/link"
|
||||
|
||||
export async function generateMetadata(): Promise<Metadata> {
|
||||
return { title: "Tags", description: "List of tags" }
|
||||
}
|
||||
|
||||
export default function TagsPage() {
|
||||
const posts = getAllPostsMeta()
|
||||
return (
|
||||
<main>
|
||||
<h1>Tags</h1>
|
||||
<ul className="flex flex-wrap gap-2">
|
||||
{Array.from(new Set(posts.flatMap((post) => post.tags))).map((tag) => (
|
||||
<li
|
||||
key={tag}
|
||||
className="rounded bg-gray-200 px-2 py-1 text-sm text-gray-800"
|
||||
>
|
||||
<Link href={`/tags/${tag}`}>
|
||||
{tag} {posts.filter((p) => p.tags.includes(tag)).length}
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
284
bun.lock
|
|
@ -5,16 +5,35 @@
|
|||
"": {
|
||||
"name": "blog.hangerthem.com",
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1",
|
||||
"gray-matter": "^4.0.3",
|
||||
"hast": "^1.0.0",
|
||||
"hast-util-from-html-isomorphic": "^2.0.0",
|
||||
"hast-util-to-text": "^4.0.2",
|
||||
"highlight.js": "^11.11.1",
|
||||
"lucide-react": "^1.28.0",
|
||||
"next": "16.2.12",
|
||||
"oxfmt": "^0.61.0",
|
||||
"oxlint": "^1.76.0",
|
||||
"puppeteer": "^25.4.0",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"reading-time": "^1.5.0",
|
||||
"rehype-highlight": "^7.0.2",
|
||||
"rehype-katex": "^7.0.1",
|
||||
"rehype-react": "^8.0.0",
|
||||
"remark": "^15.0.1",
|
||||
"remark-html": "^16.0.1",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"remark-math": "^6.0.0",
|
||||
"remark-parse": "^11.0.0",
|
||||
"remark-rehype": "^11.1.2",
|
||||
"tailwind-merge": "^3.6.0",
|
||||
"unified": "^11.0.5",
|
||||
"unist-util-visit": "^5.0.0",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/hast": "^3.0.4",
|
||||
"@types/node": "^26.1.1",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
|
|
@ -28,6 +47,7 @@
|
|||
"trustedDependencies": [
|
||||
"sharp",
|
||||
"unrs-resolver",
|
||||
"puppeteer",
|
||||
],
|
||||
"packages": {
|
||||
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
|
||||
|
|
@ -188,6 +208,84 @@
|
|||
|
||||
"@nolyfill/is-core-module": ["@nolyfill/is-core-module@1.0.39", "", {}, "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA=="],
|
||||
|
||||
"@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.61.0", "", { "os": "android", "cpu": "arm" }, "sha512-BaS+1OVvg9sr+Xav0+KdWedQRcAzrdoEcwMZeqoc2F6ieC1s/t5eM35YQoRPQ7vAqkZ+p3tbQb1r9I9mrV5oGA=="],
|
||||
|
||||
"@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.61.0", "", { "os": "android", "cpu": "arm64" }, "sha512-of8atAV0M1egGcVOMbgZCvc10sFOP3ayQBNQV5h5G3fNq8gACdEswfFk9bzGrdbM23rtg0Coxi7np7oPLcueNw=="],
|
||||
|
||||
"@oxfmt/binding-darwin-arm64": ["@oxfmt/binding-darwin-arm64@0.61.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-7l8+5ov4BGwtAcmpzvEik/TG3bciwyw/S3e6j5GKH7pcQqcgCVxD3AuJeP6upto+SOTBKQ4wrrdbMt0gq8fHSQ=="],
|
||||
|
||||
"@oxfmt/binding-darwin-x64": ["@oxfmt/binding-darwin-x64@0.61.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-Fnz4dDDXBb7udk+DmwelNjxbD6yptyxwCqwCH2ebo4RVLxVsRfFsn/AHJC49KIltPrVokamGv4SSOsiV50DTxQ=="],
|
||||
|
||||
"@oxfmt/binding-freebsd-x64": ["@oxfmt/binding-freebsd-x64@0.61.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-mddOebKNCP+AucmzfNsk3jgbr681qAUvgMqi865GW5gWLJ/AnzXbvjQRrny0e++NAN8aphav/aRSrfFxNsNjpA=="],
|
||||
|
||||
"@oxfmt/binding-linux-arm-gnueabihf": ["@oxfmt/binding-linux-arm-gnueabihf@0.61.0", "", { "os": "linux", "cpu": "arm" }, "sha512-svx59iYL+DbaZGZUIoice4W0CjRXGExnbz7Re+awIb60rVxBS2KrU7Hnlx+nZYanLGLpjneUEgo/VFEKkSZAyQ=="],
|
||||
|
||||
"@oxfmt/binding-linux-arm-musleabihf": ["@oxfmt/binding-linux-arm-musleabihf@0.61.0", "", { "os": "linux", "cpu": "arm" }, "sha512-BYK9MPJPCf6d+fLKMTruThmEyCtHzQ1zLcsrTlUVkmnoXIaHAbfpeLYQwX1tkjs7W11dyzoi6HFvKcdnvX1zNg=="],
|
||||
|
||||
"@oxfmt/binding-linux-arm64-gnu": ["@oxfmt/binding-linux-arm64-gnu@0.61.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-QUaCNLq2/EC6G5ljOuFanl9Lgw6ZWp4co7rs4+KOMUzbGfA4Lq58FHRjjF9sVIG+93XSbo343MxFATrOU1qctA=="],
|
||||
|
||||
"@oxfmt/binding-linux-arm64-musl": ["@oxfmt/binding-linux-arm64-musl@0.61.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-S6uvJ6MXnRXl+zTs0CARNDvkE+cymj0EVWEKKsyKnlLlqTyQJBjw5s4D2pSIOZc+S46cy4STefzcr/sm0VzVPA=="],
|
||||
|
||||
"@oxfmt/binding-linux-ppc64-gnu": ["@oxfmt/binding-linux-ppc64-gnu@0.61.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-6VDlRcytvZG6UlSIdAFKDLbppo9tvPxrWzle6vHldYFMeuDPQEfMKrkwezp7FaBq1wik9ra554ZZeRPsyIkFpg=="],
|
||||
|
||||
"@oxfmt/binding-linux-riscv64-gnu": ["@oxfmt/binding-linux-riscv64-gnu@0.61.0", "", { "os": "linux", "cpu": "none" }, "sha512-KkBTYbzExpbmn15XjKPLu2fRV2PVlq+KWt+brad5rwIa03vdYoaDRWiS7raHII/dCTR6Ro4UpYUCH4t6lif4WQ=="],
|
||||
|
||||
"@oxfmt/binding-linux-riscv64-musl": ["@oxfmt/binding-linux-riscv64-musl@0.61.0", "", { "os": "linux", "cpu": "none" }, "sha512-69tzIq7sJLVB9dxYYtvMzcSSsnZHSO+U2U19O2RqDqgj6+Q4O7HjSXdaszbcgqzhsUwzSH7z5kWvk8nmf6BHTg=="],
|
||||
|
||||
"@oxfmt/binding-linux-s390x-gnu": ["@oxfmt/binding-linux-s390x-gnu@0.61.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-Oqi/N0OvtOVXsPKAOOhKgGH3msRYF8BLJaNBbWiupRiKoKVyc8JRKPCfarkQJC+RgP9U8raUKLe+bNwd0HUMiA=="],
|
||||
|
||||
"@oxfmt/binding-linux-x64-gnu": ["@oxfmt/binding-linux-x64-gnu@0.61.0", "", { "os": "linux", "cpu": "x64" }, "sha512-3TKwv/ed4uwJSemAA8P9XcoqETpjQI4waquF9UilhA9Mn/dhr1PdUEXWlL74mtc6ZNfmKPA9+NEJm01nRF8CVA=="],
|
||||
|
||||
"@oxfmt/binding-linux-x64-musl": ["@oxfmt/binding-linux-x64-musl@0.61.0", "", { "os": "linux", "cpu": "x64" }, "sha512-uFso4u4nLkVSlMCpgjyvWV60Gt7GvDQHnk1mmRxHIkZTMB0ljpUKwCD9FYGgN9H97x2wYl0UwEjgRZaPIuhEhw=="],
|
||||
|
||||
"@oxfmt/binding-openharmony-arm64": ["@oxfmt/binding-openharmony-arm64@0.61.0", "", { "os": "none", "cpu": "arm64" }, "sha512-keGLkzeOvkMpNmPp4hffXWpfoSsY6e1K8++KXD4mSSfxdvM8q9QUDsYY689TB1k6Co832DZn1MnaaVx6cIBMWQ=="],
|
||||
|
||||
"@oxfmt/binding-win32-arm64-msvc": ["@oxfmt/binding-win32-arm64-msvc@0.61.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-VzsAISkFxmNhJ5LBDEL9VuH6tJsVJMtqYit2LyIUf/HLnsCe4Pg9SMOjjVQzGWt0bnpyfJ94CrqTqcpNZzK+ug=="],
|
||||
|
||||
"@oxfmt/binding-win32-ia32-msvc": ["@oxfmt/binding-win32-ia32-msvc@0.61.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-xv4t7yzwJoYaLB6Zv28B3W+j7brEjsyv50rLTAQgmxJzddce9fAMCxed8dSAkbWES0zz2J29nYK5FaTuD2YBHg=="],
|
||||
|
||||
"@oxfmt/binding-win32-x64-msvc": ["@oxfmt/binding-win32-x64-msvc@0.61.0", "", { "os": "win32", "cpu": "x64" }, "sha512-6EZXFkqOwxdDYjIn3TSNnPk3ST5E5GiYd4FiM6UF/mCL/LZSfr6D6UygTfW3R1PCQP2quCKpCEGRlij8E3VYbg=="],
|
||||
|
||||
"@oxlint/binding-android-arm-eabi": ["@oxlint/binding-android-arm-eabi@1.76.0", "", { "os": "android", "cpu": "arm" }, "sha512-ZHIE5Zt9AsPDcY4nOlofXt0YfneEeo+QrKMPcPzLf2Z6Q8VtV2W73d7SFJ920WUwyik783u/doKCs3KXdwG+7w=="],
|
||||
|
||||
"@oxlint/binding-android-arm64": ["@oxlint/binding-android-arm64@1.76.0", "", { "os": "android", "cpu": "arm64" }, "sha512-shm/ngQilHK6bs+ElJWa4oHfNj5vL1Gl/iVEJldTQjpr0/67oSgr0KUpbmcnLig5Fo0v/l6j2567A7TOL89ONA=="],
|
||||
|
||||
"@oxlint/binding-darwin-arm64": ["@oxlint/binding-darwin-arm64@1.76.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-rvJmrAPKSQ9aWJ6wIS6CK2tJjwzfW0ApQH9qokq6sfDvmHwoyIHxHFMq7z7i7GiV6fdE6s8qvBqWKPTu8RmT6Q=="],
|
||||
|
||||
"@oxlint/binding-darwin-x64": ["@oxlint/binding-darwin-x64@1.76.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U/zYdb7VYKGY6pA9Vd2rYl9O/HlCylcOlb5PGPvVLtg+oLGsk6H3XGKEMHKyqD3nmmtmlmwb/8SwU2vfSAtvMw=="],
|
||||
|
||||
"@oxlint/binding-freebsd-x64": ["@oxlint/binding-freebsd-x64@1.76.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-WvKG9CAriuo0XNiFzpXjDngUZcRGFNpaK2kLyMUsnJlShxkT96u+BpJQ3KqdQwGOrvI14L6V8bAwXwAYNNY6Jg=="],
|
||||
|
||||
"@oxlint/binding-linux-arm-gnueabihf": ["@oxlint/binding-linux-arm-gnueabihf@1.76.0", "", { "os": "linux", "cpu": "arm" }, "sha512-qJ5+RH99TqFRq3UCDxkW0zJJu9c+OAHFY72vGlxZLEpuO+MpKo3POgqb8sYipL9KYm8XY6ofb0HsOuvY6hQNqQ=="],
|
||||
|
||||
"@oxlint/binding-linux-arm-musleabihf": ["@oxlint/binding-linux-arm-musleabihf@1.76.0", "", { "os": "linux", "cpu": "arm" }, "sha512-PvPCVptkgVARsucgIqFQQcSmJ6xc6GtnVB5bRBekRahTc9eObMtjHfMjy5M+C2tHt5UCMttWM9RuSk/H9NqYeg=="],
|
||||
|
||||
"@oxlint/binding-linux-arm64-gnu": ["@oxlint/binding-linux-arm64-gnu@1.76.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-3KeFDx8Bu4HPAXbuHZOr/oHvN+QT+JQhMw/NYPz7Z071xLSsG27Jfh9PIQVEY7hk1I+jr43ExqRIeJ6VKk2yLw=="],
|
||||
|
||||
"@oxlint/binding-linux-arm64-musl": ["@oxlint/binding-linux-arm64-musl@1.76.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-oPFkkKTgl0K/EIg9fQ8oA3IGcI05/Mq1en04iFa41mmNPT+6KEiByVazTOZZJiHMBBrbsns1YJ2e1Scqwzesjw=="],
|
||||
|
||||
"@oxlint/binding-linux-ppc64-gnu": ["@oxlint/binding-linux-ppc64-gnu@1.76.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-gN7yZ0eqflA5Fhf1wvHxGUltIV3FsvmB1zhNMDEK9vSHhc7E6qg9CuPeBgPZab66Tjzq6w6kHAtNEvnTHf4cyw=="],
|
||||
|
||||
"@oxlint/binding-linux-riscv64-gnu": ["@oxlint/binding-linux-riscv64-gnu@1.76.0", "", { "os": "linux", "cpu": "none" }, "sha512-S/HqMbn22mQrjtErUxEoS/a55u8kIeXvreIxiJu5G7Le3UecEd6SQZxrDIpuhtgaFnsY/nVra3ytP+pRljDilA=="],
|
||||
|
||||
"@oxlint/binding-linux-riscv64-musl": ["@oxlint/binding-linux-riscv64-musl@1.76.0", "", { "os": "linux", "cpu": "none" }, "sha512-ZIga3097VJZolGZk6SrIAUokIGfRkxRlhiHDUznZptGBfwrhD7pNfD1rzEzsCwvk/1DX0A1bLz+liuNh5QKIVQ=="],
|
||||
|
||||
"@oxlint/binding-linux-s390x-gnu": ["@oxlint/binding-linux-s390x-gnu@1.76.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-ZGiiA7pFzMJSyMWYZTVlPgbTsx+Vl8ihLGMIujPwaslUF7kIPPWAbVmAlTc+9lWDV+DCiB8Ikixu+lSHeOIIWQ=="],
|
||||
|
||||
"@oxlint/binding-linux-x64-gnu": ["@oxlint/binding-linux-x64-gnu@1.76.0", "", { "os": "linux", "cpu": "x64" }, "sha512-JLiy5WuvEBFTT6ErIFV35SLzi0R7Iri6MKU6dZbTxfIx8pndbbPs3Mj780nMipBFcPkti+okAPOJ9POKkHFEgg=="],
|
||||
|
||||
"@oxlint/binding-linux-x64-musl": ["@oxlint/binding-linux-x64-musl@1.76.0", "", { "os": "linux", "cpu": "x64" }, "sha512-z7lgKQtbo/I1NIe8G5NHLesxJDv0tRSUWTpXKb9Pm3E9nKFKfO4IOSDtFroKgXtOYb0jQbcdH+0wzTyMXVes+A=="],
|
||||
|
||||
"@oxlint/binding-openharmony-arm64": ["@oxlint/binding-openharmony-arm64@1.76.0", "", { "os": "none", "cpu": "arm64" }, "sha512-JOjKymIpb9QcYfEhZsN6h4V9Ivd474W38cNIBRv6bg2TbIvogbMTH0Mg6YWW9TiRDqfcX+/Hyfsbo5vcSE5guQ=="],
|
||||
|
||||
"@oxlint/binding-win32-arm64-msvc": ["@oxlint/binding-win32-arm64-msvc@1.76.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-pqDWZiwcmByWUEm1NFUBNiT6aentCcaoMWJv0HbXEmuYermJ4sg8ppVrshubYP2MZ6SHccJJcpr6x469PuDFIw=="],
|
||||
|
||||
"@oxlint/binding-win32-ia32-msvc": ["@oxlint/binding-win32-ia32-msvc@1.76.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-Ba0O659kgMv6pwO3z9PdO+K3aMxQRaw9HnG+e6AtOfgwcKFvYilciQYBoUBmxfQvOCKZe1SwjMkuB542NkuDMQ=="],
|
||||
|
||||
"@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.76.0", "", { "os": "win32", "cpu": "x64" }, "sha512-5qcirPHO8nKfkoowEVWtpAoVTcYDy6g0UT0NGic450Qv8J2NrOqg4uQ8QppRP4MDTC7Xx47lbZnmadTH03CGGA=="],
|
||||
|
||||
"@puppeteer/browsers": ["@puppeteer/browsers@3.0.6", "", { "dependencies": { "modern-tar": "^0.7.6", "yargs": "^18.0.0" }, "peerDependencies": { "proxy-agent": ">=8.0.1", "yauzl": "^2.10.0 || ^3.4.0" }, "optionalPeers": ["proxy-agent", "yauzl"], "bin": { "browsers": "lib/main-cli.js" } }, "sha512-B/gKoqlFkzhvzsI6jo9K1cZz9o5ypviVv/xu8CwA4grZzyVwN+XfkT+tu8T1zrauuEXv6VhS2oGX+6NL95WcKA=="],
|
||||
|
||||
"@rtsao/scc": ["@rtsao/scc@1.1.0", "", {}, "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g=="],
|
||||
|
||||
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
|
||||
|
|
@ -228,12 +326,16 @@
|
|||
|
||||
"@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="],
|
||||
|
||||
"@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="],
|
||||
|
||||
"@types/hast": ["@types/hast@3.0.5", "", { "dependencies": { "@types/unist": "*" } }, "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g=="],
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
|
||||
|
||||
"@types/katex": ["@types/katex@0.16.8", "", {}, "sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg=="],
|
||||
|
||||
"@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="],
|
||||
|
||||
"@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="],
|
||||
|
|
@ -318,6 +420,8 @@
|
|||
|
||||
"ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="],
|
||||
|
||||
"ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
|
||||
|
||||
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
|
||||
|
|
@ -382,14 +486,24 @@
|
|||
|
||||
"character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="],
|
||||
|
||||
"character-reference-invalid": ["character-reference-invalid@2.0.1", "", {}, "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw=="],
|
||||
|
||||
"chromium-bidi": ["chromium-bidi@17.0.2", "", { "dependencies": { "mitt": "^3.0.1", "zod": "^3.24.1" }, "peerDependencies": { "devtools-protocol": "*" } }, "sha512-5v9GQFhTktFvotn/OFNJBmKLKRAb6n9r0bVCwf7sHgWc3/JryK0bj1nn93L3pHFrfgcsu6Be6EWsDi+1XHTGDg=="],
|
||||
|
||||
"client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="],
|
||||
|
||||
"cliui": ["cliui@9.0.1", "", { "dependencies": { "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w=="],
|
||||
|
||||
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
|
||||
|
||||
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||
|
||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||
|
||||
"comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="],
|
||||
|
||||
"commander": ["commander@8.3.0", "", {}, "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww=="],
|
||||
|
||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||
|
||||
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
|
||||
|
|
@ -422,6 +536,8 @@
|
|||
|
||||
"devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="],
|
||||
|
||||
"devtools-protocol": ["devtools-protocol@0.0.1653615", "", {}, "sha512-pGVkY3T/qXxAp2nFPodwYqOevk6ncNMSmvL8QfRCx5ZWGd6Vor7AFNmyaA8Zs6uJyP1QAfjuLandCgvSix1BNA=="],
|
||||
|
||||
"doctrine": ["doctrine@2.1.0", "", { "dependencies": { "esutils": "^2.0.2" } }, "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw=="],
|
||||
|
||||
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
||||
|
|
@ -432,6 +548,8 @@
|
|||
|
||||
"enhanced-resolve": ["enhanced-resolve@5.24.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.3.3" } }, "sha512-PwKooW9JUzh5chmYfHM3IQl5OkK2u2Nm011MgeZrss3JmFraUx/fqrf78kk8GUMYoibx/14MdwTl/1WKkG7TpQ=="],
|
||||
|
||||
"entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="],
|
||||
|
||||
"es-abstract": ["es-abstract@1.24.2", "", { "dependencies": { "array-buffer-byte-length": "^1.0.2", "arraybuffer.prototype.slice": "^1.0.4", "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "data-view-buffer": "^1.0.2", "data-view-byte-length": "^1.0.2", "data-view-byte-offset": "^1.0.1", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "es-set-tostringtag": "^2.1.0", "es-to-primitive": "^1.3.0", "function.prototype.name": "^1.1.8", "get-intrinsic": "^1.3.0", "get-proto": "^1.0.1", "get-symbol-description": "^1.1.0", "globalthis": "^1.0.4", "gopd": "^1.2.0", "has-property-descriptors": "^1.0.2", "has-proto": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "internal-slot": "^1.1.0", "is-array-buffer": "^3.0.5", "is-callable": "^1.2.7", "is-data-view": "^1.0.2", "is-negative-zero": "^2.0.3", "is-regex": "^1.2.1", "is-set": "^2.0.3", "is-shared-array-buffer": "^1.0.4", "is-string": "^1.1.1", "is-typed-array": "^1.1.15", "is-weakref": "^1.1.1", "math-intrinsics": "^1.1.0", "object-inspect": "^1.13.4", "object-keys": "^1.1.1", "object.assign": "^4.1.7", "own-keys": "^1.0.1", "regexp.prototype.flags": "^1.5.4", "safe-array-concat": "^1.1.3", "safe-push-apply": "^1.0.0", "safe-regex-test": "^1.1.0", "set-proto": "^1.0.0", "stop-iteration-iterator": "^1.1.0", "string.prototype.trim": "^1.2.10", "string.prototype.trimend": "^1.0.9", "string.prototype.trimstart": "^1.0.8", "typed-array-buffer": "^1.0.3", "typed-array-byte-length": "^1.0.3", "typed-array-byte-offset": "^1.0.4", "typed-array-length": "^1.0.7", "unbox-primitive": "^1.1.0", "which-typed-array": "^1.1.19" } }, "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg=="],
|
||||
|
||||
"es-abstract-get": ["es-abstract-get@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "es-object-atoms": "^1.1.2", "is-callable": "^1.2.7", "object-inspect": "^1.13.4" } }, "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg=="],
|
||||
|
|
@ -486,6 +604,8 @@
|
|||
|
||||
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
|
||||
|
||||
"estree-util-is-identifier-name": ["estree-util-is-identifier-name@3.0.0", "", {}, "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg=="],
|
||||
|
||||
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
|
||||
|
||||
"extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="],
|
||||
|
|
@ -526,6 +646,10 @@
|
|||
|
||||
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
|
||||
|
||||
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
|
||||
|
||||
"get-east-asian-width": ["get-east-asian-width@1.6.0", "", {}, "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA=="],
|
||||
|
||||
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
||||
|
||||
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
|
||||
|
|
@ -560,17 +684,33 @@
|
|||
|
||||
"hasown": ["hasown@2.0.4", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A=="],
|
||||
|
||||
"hast-util-sanitize": ["hast-util-sanitize@5.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@ungap/structured-clone": "^1.0.0", "unist-util-position": "^5.0.0" } }, "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg=="],
|
||||
"hast": ["hast@1.0.0", "", {}, "sha512-vFUqlRV5C+xqP76Wwq2SrM0kipnmpxJm7OfvVXpB35Fp+Fn4MV+ozr+JZr5qFvyR1q/U+Foim2x+3P+x9S1PLA=="],
|
||||
|
||||
"hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="],
|
||||
"hast-util-from-dom": ["hast-util-from-dom@5.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hastscript": "^9.0.0", "web-namespaces": "^2.0.0" } }, "sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q=="],
|
||||
|
||||
"hast-util-from-html": ["hast-util-from-html@2.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.1.0", "hast-util-from-parse5": "^8.0.0", "parse5": "^7.0.0", "vfile": "^6.0.0", "vfile-message": "^4.0.0" } }, "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw=="],
|
||||
|
||||
"hast-util-from-html-isomorphic": ["hast-util-from-html-isomorphic@2.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-from-dom": "^5.0.0", "hast-util-from-html": "^2.0.0", "unist-util-remove-position": "^5.0.0" } }, "sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw=="],
|
||||
|
||||
"hast-util-from-parse5": ["hast-util-from-parse5@8.0.3", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "hastscript": "^9.0.0", "property-information": "^7.0.0", "vfile": "^6.0.0", "vfile-location": "^5.0.0", "web-namespaces": "^2.0.0" } }, "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg=="],
|
||||
|
||||
"hast-util-is-element": ["hast-util-is-element@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g=="],
|
||||
|
||||
"hast-util-parse-selector": ["hast-util-parse-selector@4.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A=="],
|
||||
|
||||
"hast-util-to-jsx-runtime": ["hast-util-to-jsx-runtime@2.3.6", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "hast-util-whitespace": "^3.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "style-to-js": "^1.0.0", "unist-util-position": "^5.0.0", "vfile-message": "^4.0.0" } }, "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg=="],
|
||||
|
||||
"hast-util-to-text": ["hast-util-to-text@4.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "hast-util-is-element": "^3.0.0", "unist-util-find-after": "^5.0.0" } }, "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A=="],
|
||||
|
||||
"hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="],
|
||||
|
||||
"hastscript": ["hastscript@9.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-parse-selector": "^4.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0" } }, "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w=="],
|
||||
|
||||
"hermes-estree": ["hermes-estree@0.25.1", "", {}, "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw=="],
|
||||
|
||||
"hermes-parser": ["hermes-parser@0.25.1", "", { "dependencies": { "hermes-estree": "0.25.1" } }, "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA=="],
|
||||
|
||||
"html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="],
|
||||
"highlight.js": ["highlight.js@11.11.1", "", {}, "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w=="],
|
||||
|
||||
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
||||
|
||||
|
|
@ -578,8 +718,14 @@
|
|||
|
||||
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
|
||||
|
||||
"inline-style-parser": ["inline-style-parser@0.2.7", "", {}, "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA=="],
|
||||
|
||||
"internal-slot": ["internal-slot@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "hasown": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw=="],
|
||||
|
||||
"is-alphabetical": ["is-alphabetical@2.0.1", "", {}, "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ=="],
|
||||
|
||||
"is-alphanumerical": ["is-alphanumerical@2.0.1", "", { "dependencies": { "is-alphabetical": "^2.0.0", "is-decimal": "^2.0.0" } }, "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw=="],
|
||||
|
||||
"is-array-buffer": ["is-array-buffer@3.0.5", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "get-intrinsic": "^1.2.6" } }, "sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A=="],
|
||||
|
||||
"is-async-function": ["is-async-function@2.1.1", "", { "dependencies": { "async-function": "^1.0.0", "call-bound": "^1.0.3", "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" } }, "sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ=="],
|
||||
|
|
@ -598,6 +744,8 @@
|
|||
|
||||
"is-date-object": ["is-date-object@1.1.0", "", { "dependencies": { "call-bound": "^1.0.2", "has-tostringtag": "^1.0.2" } }, "sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg=="],
|
||||
|
||||
"is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="],
|
||||
|
||||
"is-document.all": ["is-document.all@1.0.0", "", { "dependencies": { "call-bound": "^1.0.4" } }, "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g=="],
|
||||
|
||||
"is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="],
|
||||
|
|
@ -610,6 +758,8 @@
|
|||
|
||||
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
|
||||
|
||||
"is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="],
|
||||
|
||||
"is-map": ["is-map@2.0.3", "", {}, "sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw=="],
|
||||
|
||||
"is-negative-zero": ["is-negative-zero@2.0.3", "", {}, "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw=="],
|
||||
|
|
@ -662,6 +812,8 @@
|
|||
|
||||
"jsx-ast-utils": ["jsx-ast-utils@3.3.5", "", { "dependencies": { "array-includes": "^3.1.6", "array.prototype.flat": "^1.3.1", "object.assign": "^4.1.4", "object.values": "^1.1.6" } }, "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ=="],
|
||||
|
||||
"katex": ["katex@0.16.47", "", { "dependencies": { "commander": "^8.3.0" }, "bin": { "katex": "cli.js" } }, "sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg=="],
|
||||
|
||||
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
|
||||
|
||||
"kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="],
|
||||
|
|
@ -696,6 +848,8 @@
|
|||
|
||||
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
|
||||
|
||||
"lilconfig": ["lilconfig@3.1.3", "", {}, "sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw=="],
|
||||
|
||||
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
||||
|
||||
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
||||
|
|
@ -704,14 +858,42 @@
|
|||
|
||||
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
|
||||
|
||||
"lowlight": ["lowlight@3.3.0", "", { "dependencies": { "@types/hast": "^3.0.0", "devlop": "^1.0.0", "highlight.js": "~11.11.0" } }, "sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ=="],
|
||||
|
||||
"lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
|
||||
|
||||
"lucide-react": ["lucide-react@1.28.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-fARAFJULsGuDDydjp6+6blekG/sBIM29TerzLjc9bQUKAcEfrSc4ZQKb25KRz4OMKd87cZTb5dgq0w/T6KufVg=="],
|
||||
|
||||
"magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="],
|
||||
|
||||
"markdown-table": ["markdown-table@3.0.4", "", {}, "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw=="],
|
||||
|
||||
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
||||
|
||||
"mdast-util-find-and-replace": ["mdast-util-find-and-replace@3.0.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "escape-string-regexp": "^5.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg=="],
|
||||
|
||||
"mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.3", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "mdast-util-to-string": "^4.0.0", "micromark": "^4.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q=="],
|
||||
|
||||
"mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="],
|
||||
|
||||
"mdast-util-gfm-autolink-literal": ["mdast-util-gfm-autolink-literal@2.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "ccount": "^2.0.0", "devlop": "^1.0.0", "mdast-util-find-and-replace": "^3.0.0", "micromark-util-character": "^2.0.0" } }, "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ=="],
|
||||
|
||||
"mdast-util-gfm-footnote": ["mdast-util-gfm-footnote@2.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0" } }, "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ=="],
|
||||
|
||||
"mdast-util-gfm-strikethrough": ["mdast-util-gfm-strikethrough@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg=="],
|
||||
|
||||
"mdast-util-gfm-table": ["mdast-util-gfm-table@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "markdown-table": "^3.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg=="],
|
||||
|
||||
"mdast-util-gfm-task-list-item": ["mdast-util-gfm-task-list-item@2.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ=="],
|
||||
|
||||
"mdast-util-math": ["mdast-util-math@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "longest-streak": "^3.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.1.0", "unist-util-remove-position": "^5.0.0" } }, "sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w=="],
|
||||
|
||||
"mdast-util-mdx-expression": ["mdast-util-mdx-expression@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ=="],
|
||||
|
||||
"mdast-util-mdx-jsx": ["mdast-util-mdx-jsx@3.2.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" } }, "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q=="],
|
||||
|
||||
"mdast-util-mdxjs-esm": ["mdast-util-mdxjs-esm@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "devlop": "^1.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg=="],
|
||||
|
||||
"mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="],
|
||||
|
||||
"mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="],
|
||||
|
|
@ -726,6 +908,22 @@
|
|||
|
||||
"micromark-core-commonmark": ["micromark-core-commonmark@2.0.3", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-destination": "^2.0.0", "micromark-factory-label": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-factory-title": "^2.0.0", "micromark-factory-whitespace": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-html-tag-name": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg=="],
|
||||
|
||||
"micromark-extension-gfm": ["micromark-extension-gfm@3.0.0", "", { "dependencies": { "micromark-extension-gfm-autolink-literal": "^2.0.0", "micromark-extension-gfm-footnote": "^2.0.0", "micromark-extension-gfm-strikethrough": "^2.0.0", "micromark-extension-gfm-table": "^2.0.0", "micromark-extension-gfm-tagfilter": "^2.0.0", "micromark-extension-gfm-task-list-item": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w=="],
|
||||
|
||||
"micromark-extension-gfm-autolink-literal": ["micromark-extension-gfm-autolink-literal@2.1.0", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw=="],
|
||||
|
||||
"micromark-extension-gfm-footnote": ["micromark-extension-gfm-footnote@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw=="],
|
||||
|
||||
"micromark-extension-gfm-strikethrough": ["micromark-extension-gfm-strikethrough@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw=="],
|
||||
|
||||
"micromark-extension-gfm-table": ["micromark-extension-gfm-table@2.1.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg=="],
|
||||
|
||||
"micromark-extension-gfm-tagfilter": ["micromark-extension-gfm-tagfilter@2.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg=="],
|
||||
|
||||
"micromark-extension-gfm-task-list-item": ["micromark-extension-gfm-task-list-item@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw=="],
|
||||
|
||||
"micromark-extension-math": ["micromark-extension-math@3.1.0", "", { "dependencies": { "@types/katex": "^0.16.0", "devlop": "^1.0.0", "katex": "^0.16.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg=="],
|
||||
|
||||
"micromark-factory-destination": ["micromark-factory-destination@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA=="],
|
||||
|
||||
"micromark-factory-label": ["micromark-factory-label@2.0.1", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg=="],
|
||||
|
|
@ -770,6 +968,10 @@
|
|||
|
||||
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
||||
|
||||
"mitt": ["mitt@3.0.1", "", {}, "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="],
|
||||
|
||||
"modern-tar": ["modern-tar@0.7.7", "", {}, "sha512-t9VmxaqrmANnEOBhpSDI6HD192Ge48k8vmWqQQL7hSFEqHEYwZbbsu49+aKLWZeRvFs3j1pMhXOqqF4kPlvjkQ=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"nanoid": ["nanoid@3.3.16", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="],
|
||||
|
|
@ -804,12 +1006,20 @@
|
|||
|
||||
"own-keys": ["own-keys@1.0.2", "", { "dependencies": { "call-bound": "^1.0.4", "get-intrinsic": "^1.3.0", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" } }, "sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg=="],
|
||||
|
||||
"oxfmt": ["oxfmt@0.61.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.61.0", "@oxfmt/binding-android-arm64": "0.61.0", "@oxfmt/binding-darwin-arm64": "0.61.0", "@oxfmt/binding-darwin-x64": "0.61.0", "@oxfmt/binding-freebsd-x64": "0.61.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.61.0", "@oxfmt/binding-linux-arm-musleabihf": "0.61.0", "@oxfmt/binding-linux-arm64-gnu": "0.61.0", "@oxfmt/binding-linux-arm64-musl": "0.61.0", "@oxfmt/binding-linux-ppc64-gnu": "0.61.0", "@oxfmt/binding-linux-riscv64-gnu": "0.61.0", "@oxfmt/binding-linux-riscv64-musl": "0.61.0", "@oxfmt/binding-linux-s390x-gnu": "0.61.0", "@oxfmt/binding-linux-x64-gnu": "0.61.0", "@oxfmt/binding-linux-x64-musl": "0.61.0", "@oxfmt/binding-openharmony-arm64": "0.61.0", "@oxfmt/binding-win32-arm64-msvc": "0.61.0", "@oxfmt/binding-win32-ia32-msvc": "0.61.0", "@oxfmt/binding-win32-x64-msvc": "0.61.0" }, "peerDependencies": { "svelte": "^5.0.0", "vite-plus": "*" }, "optionalPeers": ["svelte", "vite-plus"], "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-DxdHBEMYpcEnHoUHjjOigUqV2TYKsvxLwUPXnVYBjgFdqrcQ/91OtwubtZ2PUodCs3sStI8R5Qw3fKNGK4e8wQ=="],
|
||||
|
||||
"oxlint": ["oxlint@1.76.0", "", { "optionalDependencies": { "@oxlint/binding-android-arm-eabi": "1.76.0", "@oxlint/binding-android-arm64": "1.76.0", "@oxlint/binding-darwin-arm64": "1.76.0", "@oxlint/binding-darwin-x64": "1.76.0", "@oxlint/binding-freebsd-x64": "1.76.0", "@oxlint/binding-linux-arm-gnueabihf": "1.76.0", "@oxlint/binding-linux-arm-musleabihf": "1.76.0", "@oxlint/binding-linux-arm64-gnu": "1.76.0", "@oxlint/binding-linux-arm64-musl": "1.76.0", "@oxlint/binding-linux-ppc64-gnu": "1.76.0", "@oxlint/binding-linux-riscv64-gnu": "1.76.0", "@oxlint/binding-linux-riscv64-musl": "1.76.0", "@oxlint/binding-linux-s390x-gnu": "1.76.0", "@oxlint/binding-linux-x64-gnu": "1.76.0", "@oxlint/binding-linux-x64-musl": "1.76.0", "@oxlint/binding-openharmony-arm64": "1.76.0", "@oxlint/binding-win32-arm64-msvc": "1.76.0", "@oxlint/binding-win32-ia32-msvc": "1.76.0", "@oxlint/binding-win32-x64-msvc": "1.76.0" }, "peerDependencies": { "oxlint-tsgolint": ">=7.0.2001", "vite-plus": "*" }, "optionalPeers": ["oxlint-tsgolint", "vite-plus"], "bin": { "oxlint": "bin/oxlint" } }, "sha512-6QoFioEU4fNdiUx/2Eo6TRd6NG7H7njnRCz8rhB66cZmMHDTqcm1Rjvl8Wry+ZTQMBAmyb4Mlf62Mk5X+eHSOw=="],
|
||||
|
||||
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
||||
|
||||
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
||||
|
||||
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
|
||||
|
||||
"parse-entities": ["parse-entities@4.0.2", "", { "dependencies": { "@types/unist": "^2.0.0", "character-entities-legacy": "^3.0.0", "character-reference-invalid": "^2.0.0", "decode-named-character-reference": "^1.0.0", "is-alphanumerical": "^2.0.0", "is-decimal": "^2.0.0", "is-hexadecimal": "^2.0.0" } }, "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw=="],
|
||||
|
||||
"parse5": ["parse5@7.3.0", "", { "dependencies": { "entities": "^6.0.0" } }, "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw=="],
|
||||
|
||||
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
|
||||
|
||||
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
||||
|
|
@ -832,6 +1042,10 @@
|
|||
|
||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||
|
||||
"puppeteer": ["puppeteer@25.4.0", "", { "dependencies": { "@puppeteer/browsers": "3.0.6", "chromium-bidi": "17.0.2", "devtools-protocol": "0.0.1653615", "lilconfig": "^3.1.3", "puppeteer-core": "25.4.0", "typed-query-selector": "^2.12.2" }, "bin": { "puppeteer": "lib/puppeteer/node/cli.js" } }, "sha512-xfQp8dFBcGaLc1hEMaVr7s+oW4ZkAurr8Y9H81ilKhu6QoLfSTkZjU7IavnyJ/VWpB9ni3KNJUQHUatslLWyGw=="],
|
||||
|
||||
"puppeteer-core": ["puppeteer-core@25.4.0", "", { "dependencies": { "@puppeteer/browsers": "3.0.6", "chromium-bidi": "17.0.2", "devtools-protocol": "0.0.1653615", "typed-query-selector": "^2.12.2", "webdriver-bidi-protocol": "0.4.2", "ws": "^8.21.1" } }, "sha512-K1plkLOdeoUnGeT1OvdqF3qxl33v+Ra/uH5VyPEhXdMcpvGiEskHzxxEU3fgpccJpJLIipB/rPUsvkZRWeKqOA=="],
|
||||
|
||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||
|
||||
"react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
|
||||
|
|
@ -846,12 +1060,22 @@
|
|||
|
||||
"regexp.prototype.flags": ["regexp.prototype.flags@1.5.4", "", { "dependencies": { "call-bind": "^1.0.8", "define-properties": "^1.2.1", "es-errors": "^1.3.0", "get-proto": "^1.0.1", "gopd": "^1.2.0", "set-function-name": "^2.0.2" } }, "sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA=="],
|
||||
|
||||
"rehype-highlight": ["rehype-highlight@7.0.2", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-text": "^4.0.0", "lowlight": "^3.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-k158pK7wdC2qL3M5NcZROZ2tR/l7zOzjxXd5VGdcfIyoijjQqpHd3JKtYSBDpDZ38UI2WJWuFAtkMDxmx5kstA=="],
|
||||
|
||||
"rehype-katex": ["rehype-katex@7.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/katex": "^0.16.0", "hast-util-from-html-isomorphic": "^2.0.0", "hast-util-to-text": "^4.0.0", "katex": "^0.16.0", "unist-util-visit-parents": "^6.0.0", "vfile": "^6.0.0" } }, "sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA=="],
|
||||
|
||||
"rehype-react": ["rehype-react@8.0.0", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "unified": "^11.0.0" } }, "sha512-vzo0YxYbB2HE+36+9HWXVdxNoNDubx63r5LBzpxBGVWM8s9mdnMdbmuJBAX6TTyuGdZjZix6qU3GcSuKCIWivw=="],
|
||||
|
||||
"remark": ["remark@15.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A=="],
|
||||
|
||||
"remark-html": ["remark-html@16.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "hast-util-sanitize": "^5.0.0", "hast-util-to-html": "^9.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0" } }, "sha512-B9JqA5i0qZe0Nsf49q3OXyGvyXuZFDzAP2iOFLEumymuYJITVpiH1IgsTEwTpdptDmZlMDMWeDmSawdaJIGCXQ=="],
|
||||
"remark-gfm": ["remark-gfm@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="],
|
||||
|
||||
"remark-math": ["remark-math@6.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-math": "^3.0.0", "micromark-extension-math": "^3.0.0", "unified": "^11.0.0" } }, "sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA=="],
|
||||
|
||||
"remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="],
|
||||
|
||||
"remark-rehype": ["remark-rehype@11.1.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw=="],
|
||||
|
||||
"remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="],
|
||||
|
||||
"resolve": ["resolve@2.0.0-next.7", "", { "dependencies": { "es-errors": "^1.3.0", "is-core-module": "^2.16.2", "node-exports-info": "^1.6.0", "object-keys": "^1.1.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ=="],
|
||||
|
|
@ -906,6 +1130,8 @@
|
|||
|
||||
"stop-iteration-iterator": ["stop-iteration-iterator@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "internal-slot": "^1.1.0" } }, "sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ=="],
|
||||
|
||||
"string-width": ["string-width@8.2.2", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg=="],
|
||||
|
||||
"string.prototype.includes": ["string.prototype.includes@2.0.1", "", { "dependencies": { "call-bind": "^1.0.7", "define-properties": "^1.2.1", "es-abstract": "^1.23.3" } }, "sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg=="],
|
||||
|
||||
"string.prototype.matchall": ["string.prototype.matchall@4.0.12", "", { "dependencies": { "call-bind": "^1.0.8", "call-bound": "^1.0.3", "define-properties": "^1.2.1", "es-abstract": "^1.23.6", "es-errors": "^1.3.0", "es-object-atoms": "^1.0.0", "get-intrinsic": "^1.2.6", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "internal-slot": "^1.1.0", "regexp.prototype.flags": "^1.5.3", "set-function-name": "^2.0.2", "side-channel": "^1.1.0" } }, "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA=="],
|
||||
|
|
@ -920,24 +1146,34 @@
|
|||
|
||||
"stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="],
|
||||
|
||||
"strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="],
|
||||
|
||||
"strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="],
|
||||
|
||||
"strip-bom-string": ["strip-bom-string@1.0.0", "", {}, "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g=="],
|
||||
|
||||
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
||||
|
||||
"style-to-js": ["style-to-js@1.1.21", "", { "dependencies": { "style-to-object": "1.0.14" } }, "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ=="],
|
||||
|
||||
"style-to-object": ["style-to-object@1.0.14", "", { "dependencies": { "inline-style-parser": "0.2.7" } }, "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw=="],
|
||||
|
||||
"styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "@babel/core": "*", "babel-plugin-macros": "*", "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" }, "optionalPeers": ["@babel/core", "babel-plugin-macros"] }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="],
|
||||
|
||||
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
|
||||
|
||||
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
|
||||
|
||||
"tailwind-merge": ["tailwind-merge@3.6.0", "", {}, "sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w=="],
|
||||
|
||||
"tailwindcss": ["tailwindcss@4.3.3", "", {}, "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ=="],
|
||||
|
||||
"tapable": ["tapable@2.3.3", "", {}, "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A=="],
|
||||
|
||||
"tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="],
|
||||
|
||||
"tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="],
|
||||
|
||||
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
||||
|
||||
"trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
|
||||
|
|
@ -960,6 +1196,8 @@
|
|||
|
||||
"typed-array-length": ["typed-array-length@1.0.8", "", { "dependencies": { "call-bind": "^1.0.9", "for-each": "^0.3.5", "gopd": "^1.2.0", "is-typed-array": "^1.1.15", "possible-typed-array-names": "^1.1.0", "reflect.getprototypeof": "^1.0.10" } }, "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g=="],
|
||||
|
||||
"typed-query-selector": ["typed-query-selector@2.12.2", "", {}, "sha512-EOPFbyIub4ngnEdqi2yOcNeDLaX/0jcE1JoAXQDDMIthap7FoN795lc/SHfIq2d416VufXpM8z/lD+WRm2gfOQ=="],
|
||||
|
||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||
|
||||
"typescript-eslint": ["typescript-eslint@8.65.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.65.0", "@typescript-eslint/parser": "8.65.0", "@typescript-eslint/typescript-estree": "8.65.0", "@typescript-eslint/utils": "8.65.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA=="],
|
||||
|
|
@ -970,10 +1208,14 @@
|
|||
|
||||
"unified": ["unified@11.0.5", "", { "dependencies": { "@types/unist": "^3.0.0", "bail": "^2.0.0", "devlop": "^1.0.0", "extend": "^3.0.0", "is-plain-obj": "^4.0.0", "trough": "^2.0.0", "vfile": "^6.0.0" } }, "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA=="],
|
||||
|
||||
"unist-util-find-after": ["unist-util-find-after@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ=="],
|
||||
|
||||
"unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="],
|
||||
|
||||
"unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="],
|
||||
|
||||
"unist-util-remove-position": ["unist-util-remove-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-visit": "^5.0.0" } }, "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q=="],
|
||||
|
||||
"unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="],
|
||||
|
||||
"unist-util-visit": ["unist-util-visit@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg=="],
|
||||
|
|
@ -988,8 +1230,14 @@
|
|||
|
||||
"vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="],
|
||||
|
||||
"vfile-location": ["vfile-location@5.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg=="],
|
||||
|
||||
"vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="],
|
||||
|
||||
"web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="],
|
||||
|
||||
"webdriver-bidi-protocol": ["webdriver-bidi-protocol@0.4.2", "", {}, "sha512-VSV+fzfChirL3e7jay2yUC7B4HQCGtEWEg/MSSQbK+qWbqeGlRLlXTzPpYr3XGUvbpDHumWZBJxgesg4N7dbtA=="],
|
||||
|
||||
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||
|
||||
"which-boxed-primitive": ["which-boxed-primitive@1.1.1", "", { "dependencies": { "is-bigint": "^1.1.0", "is-boolean-object": "^1.2.1", "is-number-object": "^1.1.1", "is-string": "^1.1.1", "is-symbol": "^1.1.1" } }, "sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA=="],
|
||||
|
|
@ -1002,8 +1250,18 @@
|
|||
|
||||
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
|
||||
|
||||
"wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="],
|
||||
|
||||
"ws": ["ws@8.21.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw=="],
|
||||
|
||||
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
|
||||
|
||||
"yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
|
||||
|
||||
"yargs": ["yargs@18.1.0", "", { "dependencies": { "cliui": "^9.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "string-width": "^8.2.1", "y18n": "^5.0.5", "yargs-parser": "^22.0.0" } }, "sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg=="],
|
||||
|
||||
"yargs-parser": ["yargs-parser@22.0.0", "", {}, "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw=="],
|
||||
|
||||
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||
|
||||
"zod": ["zod@4.4.3", "", {}, "sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ=="],
|
||||
|
|
@ -1042,6 +1300,10 @@
|
|||
|
||||
"@unrs/resolver-binding-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="],
|
||||
|
||||
"chromium-bidi/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
||||
|
||||
"cliui/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
|
||||
|
||||
"eslint-import-resolver-node/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
|
||||
|
||||
"eslint-module-utils/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
|
||||
|
|
@ -1052,16 +1314,28 @@
|
|||
|
||||
"is-bun-module/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
|
||||
|
||||
"micromatch/picomatch": ["picomatch@2.3.2", "", {}, "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="],
|
||||
|
||||
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
||||
|
||||
"parse-entities/@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="],
|
||||
|
||||
"sharp/semver": ["semver@7.8.5", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA=="],
|
||||
|
||||
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
||||
|
||||
"wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
|
||||
|
||||
"@eslint/eslintrc/js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@5.0.8", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg=="],
|
||||
|
||||
"cliui/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
|
||||
|
||||
"wrap-ansi/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
|
||||
}
|
||||
}
|
||||
|
|
|
|||
27
components/common/BlockquoteWrapper.tsx
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import type { NoteType } from '@/types/Note.type'
|
||||
import { Lightbulb, FileWarning, TriangleAlert } from 'lucide-react'
|
||||
|
||||
type BlockquoteWrapperProps = {
|
||||
type?: NoteType
|
||||
children: React.ReactNode
|
||||
}
|
||||
|
||||
const noteTypeIcons: Record<NoteType, React.ReactNode> = {
|
||||
warning: <TriangleAlert className="w-4 h-4" />,
|
||||
tip: <Lightbulb className="w-4 h-4" />,
|
||||
info: <FileWarning className="w-4 h-4" />,
|
||||
}
|
||||
|
||||
export function BlockquoteWrapper({ type, children }: BlockquoteWrapperProps) {
|
||||
return (
|
||||
<blockquote className={`note ${type}`}>
|
||||
{type && (
|
||||
<div className="note-icon flex items-center gap-2 mb-2">
|
||||
{noteTypeIcons[type]}
|
||||
<span className="capitalize font-bold">{type}</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="italic">{children}</div>
|
||||
</blockquote>
|
||||
)
|
||||
}
|
||||
56
components/common/CodeWrapper.tsx
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
'use client'
|
||||
|
||||
import { isValidElement, type ReactNode } from 'react'
|
||||
import { CopyButton } from './CopyButton'
|
||||
|
||||
type CodeWrapperProps = {
|
||||
language?: string
|
||||
children?: ReactNode
|
||||
}
|
||||
|
||||
function getTextContent(node: ReactNode): string {
|
||||
if (node === null || typeof node === 'boolean') return ''
|
||||
if (typeof node === 'string' || typeof node === 'number') return String(node)
|
||||
if (Array.isArray(node)) return node.map(getTextContent).join('')
|
||||
if (isValidElement(node)) {
|
||||
const props = node.props as { children?: ReactNode }
|
||||
return getTextContent(props.children)
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
export function CodeWrapper({ language, children }: CodeWrapperProps) {
|
||||
const text = getTextContent(children).replace(/\n$/, '')
|
||||
const lineCount = text.length === 0 ? 1 : text.split('\n').length
|
||||
|
||||
return (
|
||||
<div className="bg-foreground/10 rounded-md overflow-x-auto border border-border bg-fg/10">
|
||||
<div
|
||||
className="flex items-center gap-2 px-2 h-6 border-b border-border w-full"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div className="space-x-1">
|
||||
<span className="w-2 h-2 bg-border rounded-full inline-block"></span>
|
||||
<span className="w-2 h-2 bg-border rounded-full inline-block"></span>
|
||||
<span className="w-2 h-2 bg-border rounded-full inline-block"></span>
|
||||
</div>
|
||||
<span className="text-xs text-fg-dim font-mono">{language ?? 'code'}</span>
|
||||
<CopyButton textToCopy={text} className="ml-auto" />
|
||||
</div>
|
||||
|
||||
<div className="flex">
|
||||
<div className="select-none text-right py-2 px-3 border-r border-border text-white font-mono text-sm leading-6 min-w-6">
|
||||
{Array.from({ length: lineCount }, (_, i) => (
|
||||
<span className="block" key={i}>
|
||||
{i + 1}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<pre className="flex-1 p-2 m-0 overflow-x-auto text-fg-dim font-mono text-sm leading-6">
|
||||
{children}
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
25
components/common/CopyButton.tsx
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
'use client'
|
||||
|
||||
import { ButtonHTMLAttributes } from 'react'
|
||||
import { Copy } from 'lucide-react'
|
||||
import { cn } from '@/utils/cn'
|
||||
|
||||
type CopyButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
|
||||
textToCopy: string
|
||||
}
|
||||
|
||||
export function CopyButton({ textToCopy, className, ...props }: CopyButtonProps) {
|
||||
const handleCopy = () => {
|
||||
navigator.clipboard.writeText(textToCopy)
|
||||
}
|
||||
|
||||
return (
|
||||
<button
|
||||
className={cn('text-fg-dim hover:text-fg transition-colors js-only', className)}
|
||||
onClick={handleCopy}
|
||||
{...props}
|
||||
>
|
||||
<Copy className="w-4 h-4" />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
20
components/common/ExternalLink.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import type { AnchorHTMLAttributes } from 'react';
|
||||
import { cn } from '@/utils/cn';
|
||||
|
||||
type ExternalLinkProps = Omit<
|
||||
AnchorHTMLAttributes<HTMLAnchorElement>,
|
||||
'href' | 'rel' | 'target'
|
||||
> & {
|
||||
href: string;
|
||||
};
|
||||
|
||||
export function ExternalLink({ className, ...props }: ExternalLinkProps) {
|
||||
return (
|
||||
<a
|
||||
{...props}
|
||||
className={cn(className, 'hover:underline focus:underline')}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
/>
|
||||
);
|
||||
}
|
||||
40
components/common/ImageWrapper.tsx
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import { cn } from '@/utils/cn'
|
||||
import Image from 'next/image'
|
||||
|
||||
type ImageWrapperProps = {
|
||||
src: string
|
||||
alt?: string
|
||||
isListing?: boolean
|
||||
}
|
||||
|
||||
export function ImageWrapper({ src, alt, isListing }: ImageWrapperProps) {
|
||||
return (
|
||||
<figure className="flex flex-col items-center gap-1 w-full">
|
||||
<div className="border border-border rounded-xl w-full overflow-hidden">
|
||||
<div
|
||||
className="flex items-center gap-2 px-2 h-6 border-b border-border w-full bg-fg/10"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<div className="space-x-1">
|
||||
<span className="w-2 h-2 bg-border rounded-full inline-block"></span>
|
||||
<span className="w-2 h-2 bg-border rounded-full inline-block"></span>
|
||||
<span className="w-2 h-2 bg-border rounded-full inline-block"></span>
|
||||
</div>
|
||||
<span className="text-xs text-fg-dim font-mono">~/{src}</span>
|
||||
</div>
|
||||
<Image
|
||||
src={`/${src}`}
|
||||
alt={alt ?? ''}
|
||||
width={isListing ? 400 : 800}
|
||||
height={isListing ? 240 : 400}
|
||||
quality={100}
|
||||
priority={true}
|
||||
className={cn('w-auto mx-auto object-cover', isListing ? 'h-60' : '')}
|
||||
/>
|
||||
</div>
|
||||
{!isListing && alt && (
|
||||
<figcaption className="block text-xs text-fg-dim font-mono text-center">{alt}</figcaption>
|
||||
)}
|
||||
</figure>
|
||||
)
|
||||
}
|
||||
60
components/common/TableOfContents.tsx
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
'use client'
|
||||
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
|
||||
type TocItem = { text: string; id: string; level: number }
|
||||
|
||||
const indentByLevel: Record<number, string> = {
|
||||
2: 'pl-0',
|
||||
3: 'pl-4',
|
||||
}
|
||||
|
||||
export function TableOfContents({ items }: { items: TocItem[] }) {
|
||||
const [activeId, setActiveId] = useState<string | null>(null)
|
||||
const observer = useRef<IntersectionObserver | null>(null)
|
||||
|
||||
useEffect(() => {
|
||||
if (items.length === 0) return
|
||||
|
||||
const headingElements = items
|
||||
.map((item) => document.getElementById(item.id))
|
||||
.filter((el): el is HTMLElement => el !== null)
|
||||
|
||||
observer.current = new IntersectionObserver(
|
||||
(entries) => {
|
||||
const visible = entries.filter((entry) => entry.isIntersecting)
|
||||
if (visible.length > 0) {
|
||||
setActiveId(visible[0].target.id)
|
||||
}
|
||||
},
|
||||
{ rootMargin: '0px 0px -70% 0px', threshold: 1.0 },
|
||||
)
|
||||
|
||||
headingElements.forEach((el) => observer.current?.observe(el))
|
||||
|
||||
return () => observer.current?.disconnect()
|
||||
}, [items])
|
||||
|
||||
if (items.length === 0) return null
|
||||
|
||||
return (
|
||||
<nav aria-label="Table of contents" className="sticky top-20">
|
||||
<h2 className="text-2xl font-bold mb-4">Table of Contents</h2>
|
||||
<ul className="space-y-1 text-sm">
|
||||
{items.map((item) => (
|
||||
<li key={item.id} className={indentByLevel[item.level] ?? 'pl-0'}>
|
||||
<a
|
||||
href={`#${item.id}`}
|
||||
className={`block truncate transition-colors ${
|
||||
activeId === item.id ? 'text-accent font-medium' : 'text-fg-dim hover:text-fg'
|
||||
}`}
|
||||
aria-current={activeId === item.id ? 'location' : undefined}
|
||||
>
|
||||
{item.text}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
26
components/layout/Sidebar.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
export function Sidebar() {
|
||||
return (
|
||||
<aside className="hidden lg:block w-64 shrink-0">
|
||||
<div className="sticky top-6">
|
||||
<h2 className="text-lg font-bold mb-4">Navigation</h2>
|
||||
<ul className="space-y-2">
|
||||
<li>
|
||||
<a href="/" className="text-blue-500 hover:underline">
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/about" className="text-blue-500 hover:underline">
|
||||
About
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/contact" className="text-blue-500 hover:underline">
|
||||
Contact
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
|
|
@ -22,9 +22,7 @@ Self-development is the process of improving oneself be it through learning new
|
|||
There are many books on self-development that offer valuable insights and practical advice on how to improve various aspects of your life. Some of my favorite books on self-development include:
|
||||
|
||||
1. **"Atomic Habits" by James Clear**: This book explores the power of small habits and how they can lead to significant changes in your life. It offers practical strategies for building good habits and breaking bad ones.
|
||||
|
||||
2. **"The 7 Habits of Highly Effective People" by Stephen Covey**: This classic book outlines seven habits that can help you become more effective in your personal and professional life. It emphasizes the importance of proactivity, goal setting, and continuous improvement.
|
||||
|
||||
3. **"The 5AM Club" by Robin Sharma**: This book advocates for waking up early and using the early morning hours to focus on personal growth and self-improvement. It offers a simple yet powerful formula for success based on the concept of the 20/20/20 rule.
|
||||
|
||||
## My Journey with Self-Development
|
||||
|
|
|
|||
410
content/posts/2024-08-20-standard-model.md
Normal file
|
|
@ -0,0 +1,410 @@
|
|||
---
|
||||
title: Standard Model of Particle Physics
|
||||
description: This post provides an overview of the Standard Model of particle physics, including its basic components and interactions. It covers fundamental particles, forces, and the Higgs mechanism, highlighting key concepts and limitations of the model.
|
||||
author: hangerthem
|
||||
date: 2024-08-20 21:15:00 +0200
|
||||
categories: [Physics]
|
||||
tags:
|
||||
[
|
||||
Standard Model,
|
||||
Particle Physics,
|
||||
Fundamental Particles,
|
||||
Forces,
|
||||
Higgs Mechanism,
|
||||
Quantum Field Theory,
|
||||
Electromagnetic Force,
|
||||
Weak Nuclear Force,
|
||||
Strong Nuclear Force,
|
||||
QED,
|
||||
QCD,
|
||||
Electroweak Theory,
|
||||
Neutrino Oscillations,
|
||||
Gauge Bosons,
|
||||
Quarks,
|
||||
Leptons,
|
||||
Higgs Boson,
|
||||
Mass,
|
||||
Charge
|
||||
]
|
||||
math: true
|
||||
mermaid: true
|
||||
coverImage: standard_model.svg
|
||||
coverImageAlt: Overview of the fundamental particles and forces in the Standard Model of particle physics.
|
||||
---
|
||||
|
||||
At the beginning, I want to clarify that I'm not a physicist, but I'm interested in physics and I'm trying to understand it better. This post is collection of my old notes and even though I read them again and tried to correct them, there might be some mistakes. If you find any, please let me know.
|
||||
|
||||
## Fundamental Particles
|
||||
|
||||
The Standard Model categorizes all known fundamental particles into three main groups: quarks, leptons, and gauge bosons. These particles interact through the fundamental forces of nature, which are mediated by gauge bosons.
|
||||
|
||||
Before we dive into the details, let's define some key terms.
|
||||
|
||||
### Key Quantum Numbers and Properties
|
||||
|
||||
Quantum numbers are properties that characterize particles and determine their behavior in quantum mechanics. For our discussion, we will focus specifically on those that are most relevant to the Standard Model.
|
||||
|
||||
#### Mass
|
||||
|
||||
Although fundamental particles are incredibly small, they can possess measurable masses, notably the $W$ and $Z$ bosons. This mass, however, is not the same as everyday mass; it is a measure of energy.
|
||||
|
||||
In particle physics, mass is frequently measured in electronvolts (eV), where $1\text{ eV}$ represents the energy gained or lost by an electron when accelerated through an electric potential difference of $1\text{ V}$. This unit scales in the same way as other SI units, allowing for conversion to larger units such as giga-electronvolts (GeV) by multiplying by $10^9$.
|
||||
|
||||
The relationship between energy and mass is described by Einstein's equation $E=mc^2$. Consequently, $1\text{ eV}$ of energy corresponds to a mass of approximately $1.783 \times 10^{-36}$kg.
|
||||
|
||||
In particle physics, the total energy of a particle is often described by:
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
E^2 = (pc)^2 + (m_0 c^2)^2
|
||||
\label{eq:energy_momentum_mass}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
where $p$ is the momentum of the particle, $m_0$ is its rest mass, and $c$ is the speed of light.
|
||||
|
||||
#### Charge
|
||||
|
||||
Charge is a fundamental property of particles that causes them to experience electromagnetic forces. Particles can have positive, negative, or neutral charges, with the electron having a charge of $-e$ and the proton having a charge of $+e$.
|
||||
|
||||
The unit of charge is Columb (C) but for fundamental particles is usually used elementary charge (e).
|
||||
|
||||
$$
|
||||
e\approx1.602\times10^{-19}C
|
||||
$$
|
||||
|
||||
#### Spin
|
||||
|
||||
Fundamental quantum property of particles representing their intrinsic angular momentum, which affects their behavior in magnetic fields.
|
||||
|
||||
Particles can have integer or half-integer spin values, with fermions (e.g., quarks, leptons) having half-integer spins and bosons (e.g., gauge bosons) having integer spins.
|
||||
|
||||
As spins are quite complex topic and deal with quantum mechanics, I won't go into details here. But you can expect a separate post just about spins in the near future. All you need to know for now is that the spin is not the same as the classical angular momentum.
|
||||
|
||||
### Fermions
|
||||
|
||||
Fermions are particles that obey Fermi-Dirac statistics and follow the Pauli exclusion principle, which states that no two identical fermions can occupy the same quantum state simultaneously. To explain this a bit more, for example, electrons are fermions, and they can't occupy the same quantum state in an atom.
|
||||
|
||||
#### Quarks
|
||||
|
||||
Quarks are the building blocks of hadrons (protons, neutrons etc.) and are never found in isolation due to confinement, a phenomenon where quarks are bound together in color-neutral combinations. Quarks come in six flavors:
|
||||
|
||||
1. **Up ($u$)**
|
||||
2. **Down ($d$)**
|
||||
3. **Charm ($c$)**
|
||||
4. **Strange ($s$)**
|
||||
5. **Top ($t$)**
|
||||
6. **Bottom ($b$)**
|
||||
|
||||
All quarks have fractional electric charges, with the up, charm and top quarks having a charge of $+\frac{2}{3}e$, and the down, strange and bottom quarks having a charge of $-\frac{1}{3}e$.
|
||||
|
||||
##### Quark Color Charge
|
||||
|
||||
Quarks also carry a property called color charge, which is associated with the strong nuclear force. Quarks come in three "colors": red, green, and blue and their anti-colors: anti-red, anti-green, and anti-blue. The term "color" is a metaphorical description and does not refer to the colors we see in everyday life. Quarks must combine in color-neutral combinations to form hadrons.
|
||||
|
||||
If the color explanation is confusing, you can instead imagine the colors as a vector (two dimensional one is enough). So let's say that red is $(1,0)$, green is $(0,1)$ and blue is $(-1,-1)$. Then the color-neutral combination would be:
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
(1,0)+(0,1)+(-1,-1)=(0,0)
|
||||
\label{eq:color_neutral_combination}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
Thus the color-neutral combination is $(0,0)$ which is the same as no color. For anti-colors, you just need to change the sign of the vector. So anti-red would be $(-1,0)$, anti-green $(0,-1)$ and anti-blue $(1,1)$. As stated before, the resulting particle must have a color-neutral combination, so it can be a quark-antiquark pair, three quarks or more complex combinations.
|
||||
|
||||
##### Quark Confinement
|
||||
|
||||
Quarks are never found in isolation due to a phenomenon called quark confinement. This means that quarks are always bound together in groups of two or more, forming color-neutral particles called hadrons.
|
||||
|
||||
- **Mesons**: Consist of a quark and an antiquark. ($q\bar{q}$)
|
||||
- **Baryons**: Consist of three quarks. ($qqq$)
|
||||
- **Exotic Hadrons**: Include particles composed of more than three quarks, such as tetraquarks ($qq\bar{q}\bar{q}$) and pentaquarks ($qqqq\bar{q}$).
|
||||
|
||||
```mermaid
|
||||
graph TB;
|
||||
id0[q1 ... qn] --> Hadrons;
|
||||
Hadrons --> Mesons;
|
||||
Hadrons --> Baryons;
|
||||
Hadrons --> id1[Exotic Hadrons]
|
||||
```
|
||||
|
||||
This is a simplified representation of the relationship between quarks and hadrons. Quarks combine to form hadrons, which include mesons and baryons. Exotic hadrons are more complex combinations of quarks.
|
||||
|
||||
#### Leptons
|
||||
|
||||
Leptons are a group of fundamental particles that do not experience the strong nuclear force. There are six types of leptons, each with a unique flavor:
|
||||
|
||||
1. **Electron ($e$)**
|
||||
2. **Muon ($\mu$)**
|
||||
3. **Tau ($\tau$)**
|
||||
4. **Electron neutrino ($\nu_e$)**
|
||||
5. **Muon neutrino ($\nu_\mu$)**
|
||||
6. **Tau neutrino ($\nu_\tau$)**
|
||||
|
||||
Leptons are divided into two categories:
|
||||
|
||||
- **Charged Leptons**: Include the electron, muon, and tau, which have electric charge of $-1e$.
|
||||
- **Neutrinos**: Include the electron neutrino, muon neutrino, and tau neutrino, which are neutral and weakly interacting.
|
||||
|
||||
##### Neutrinos
|
||||
|
||||
Neutrinos are neutral, weakly interacting particles that come in three flavors: electron neutrino, muon neutrino, and tau neutrino. They have very small masses and are produced in various nuclear reactions and particle decays.
|
||||
|
||||
Neutrinos are challenging to detect due to their weak interactions with matter, but they play a crucial role in processes like beta decay and neutrino oscillations.
|
||||
|
||||
##### Neutrino Oscillation
|
||||
|
||||
Neutrino oscillation is a phenomenon where neutrinos change flavors as they travel through space. This effect arises from the mixing of neutrino mass eigenstates, leading to oscillation between different flavor states.
|
||||
|
||||
Neutrino oscillation occurs because the flavor eigenstates (which are the states detected in experiments) are mixtures of the mass eigenstates (which are the states that propagate through space).
|
||||
|
||||
- **Flavor Eigenstates** ($\nu_e$, $\nu_\mu$, $\nu_\tau$): These are the states in which neutrinos are produced and detected.
|
||||
- **Mass Eigenstates** ($\nu_1$, $\nu_2$, $\nu_3$): These are the states with definite masses that travel through space.
|
||||
|
||||
The probability of a neutrino of flavor $\nu_\alpha$ transforming into a neutrino of flavor $\nu_\beta$ over a distance $L$ is given by the oscillation probability formula:
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
P(\nu_\alpha\to\nu_\beta)=\sin^2(2\theta)\sin^2(\frac{\Delta m^2L}{4E})
|
||||
\label{eq:neutrino_oscillations}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
- $\theta$ - mixing angle between the flavor and mass eigenstates.
|
||||
- $\Delta m^2$ - difference in the squared masses of the mass eigenstates.
|
||||
- $L$ - distance traveled by the neutrino.
|
||||
- $E$ - energy of the neutrino.
|
||||
|
||||
For long time, neutrinos were thought to be massless, but the discovery of neutrino oscillations provided evidence that neutrinos must have non-zero masses.
|
||||
|
||||
The key to understanding why neutrinos must have mass lies in the $\Delta m^2$ term. If neutrinos were massless, $\Delta m^2$ would be zero. This would make the argument of the sine function:
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
\sin^2(\frac{\Delta m^2L}{4E})=\sin^2(0)=0
|
||||
\label{eq:neutrino_oscillations_zero_mass}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
Thus, $\sin^2\left(\frac{\Delta m^2 L}{4E}\right)$ would always be zero, implying that the probability of detecting a neutrino of a different flavor would be zero as well. This means no oscillations would occur.
|
||||
|
||||
However, since neutrinos do oscillate between flavors, the non-zero oscillation probability indicates that $\Delta m^2$ is not zero. This non-zero mass squared difference $\Delta m^2$ implies that the neutrino mass eigenstates are not degenerate; thus, neutrinos must have mass.
|
||||
|
||||
###### Key Points
|
||||
|
||||
- **Mixing Angle ($\theta$)**: Describes how much the flavor eigenstates mix with the mass eigenstates.
|
||||
- **Mass Squared Difference ($\Delta m^2$)**: The difference in squared masses between the mass eigenstates affects the oscillation frequency.
|
||||
- **Energy and Distance**: The oscillation pattern depends on the energy of the neutrino and the distance it travels.
|
||||
|
||||
The term $\sin^2(2\theta)$ reflects the strength of the mixing between the flavor and mass eigenstates, while $\sin^2(\frac{\Delta m^2L}{4E})$ describes the oscillation pattern, which varies with distance and energy. This formula captures the essential features of neutrino oscillations, demonstrating how neutrinos can change flavors as they travel.
|
||||
|
||||
### Gauge Bosons
|
||||
|
||||
Gauge bosons are the force carriers that mediate the fundamental forces of nature. Unlike fermions, gauge bosons are bosons, which follow Bose-Einstein statistics and do not obey the Pauli exclusion principle. They are responsible for transmitting forces between particles.
|
||||
|
||||
1. **Photon ($\gamma$)** - Mediates the electromagnetic force.
|
||||
2. **$W$ and $Z$ bosons ($W^+$, $W^-$, $Z^0$)** - Mediate the weak nuclear force.
|
||||
|
||||
- Both $W$ and $Z$ bosons are massive
|
||||
|
||||
$$
|
||||
m_W\approx80GeV/c^2
|
||||
$$
|
||||
|
||||
$$
|
||||
m_Z\approx91GeV/c^2
|
||||
$$
|
||||
|
||||
3. **Gluons ($g$)** - Mediate the strong nuclear force.
|
||||
4. **Higgs Boson ($H$)** - Excitation of Higgs field.
|
||||
|
||||
**Higgs boson** is often included in discussions about the Standard Model because it is responsible for giving mass to other particles through the Higgs mechanism.
|
||||
|
||||
## Fundamental Forces
|
||||
|
||||
The Standard Model describes three of the four fundamental forces:
|
||||
|
||||
1. **Electromagnetic Force** - Mediated by photons, it affects particles with electric charge.
|
||||
2. **Weak Nuclear Force** - Mediated by $W$ and $Z$ bosons, it is responsible for processes like beta decay.
|
||||
3. **Strong Nuclear Force** - Mediated by gluons, it binds quarks together to form protons, neutrons and other hadrons and holds the atomic nucleus together.
|
||||
|
||||
## Interaction Mechanisms
|
||||
|
||||
### Electromagnetic Interaction
|
||||
|
||||
This is described by Quantum Electrodynamics (QED), where charged particles interact by exchanging photons. The electromagnetic force is long-ranged and can be attractive or repulsive.
|
||||
|
||||
#### Quantum Electrodynamics (QED) Lagrangian
|
||||
|
||||
The QED Lagrangian describes the interactions of electrons, positrons, and photons in the electromagnetic force. It can be expressed as:
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
\mathcal{L}_{QED} = -\frac{1}{4} F_{\mu\nu} F^{\mu\nu} + \bar{\psi} (i \gamma^\mu D_\mu - m) \psi
|
||||
\label{eq:qed_lagrangian}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
1. **Electromagnetic Field Strength Tensor** ($F_{\mu\nu}$):
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
F_{\mu\nu} = \partial_\mu A_\nu - \partial_\nu A_\mu
|
||||
\label{eq:em_field_strength_tensor}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
- **Explanation**: This term describes the field strength of the electromagnetic field. It involves the derivative of the electromagnetic potential $A_\mu$. The field strength tensor is antisymmetric, reflecting the nature of the electromagnetic force.
|
||||
|
||||
2. **Electron Kinetic Term** $(\bar{\psi}(i\gamma^\mu D_\mu-m)\psi)$:
|
||||
|
||||
- **$\bar{\psi}$** - Dirac adjoint of the electron field $\psi$.
|
||||
- **$i \gamma^\mu D_\mu$** - Represents the kinetic term of the electrons, where $\gamma^\mu$ are the gamma matrices associated with the Dirac equation and $D_\mu$ is the covariant derivative.
|
||||
- **Covariant Derivative** ($D_\mu$):
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
D_\mu = \partial_\mu - i e A_\mu
|
||||
\label{eq:covariant_derivative_for_electrons}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
- **Explanation**: This accounts for the interaction of electrons with the electromagnetic field. $e$ is the electric charge, and $A_\mu$ is the electromagnetic potential.
|
||||
|
||||
3. **Electron Mass Term** $(-m)$:
|
||||
- **Explanation**: Represents the mass of the electron, contributing to the electron's energy in the Lagrangian. $(m)$ is the mass of the electron.
|
||||
|
||||
##### Key Points
|
||||
|
||||
- **Photon Field Strength Tensor**: The term $-\frac{1}{4}F_{\mu\nu}F^{\mu\nu}$ describes the field strength of the electromagnetic field, involving the derivative of the electromagnetic potential $(A_\mu)$.
|
||||
- **Electron-Photon Interactions**: The covariant derivative $(D_\mu)$ in the electron term shows how electrons interact with the electromagnetic field. This term ensures that the theory respects gauge invariance under U(1) transformations.
|
||||
- **Mass of Electrons**: The electron mass term shows how electrons acquire mass, contributing to the mass of atoms and molecules. In QED, the mass of the electron is a fundamental parameter of the theory.
|
||||
|
||||
### Weak Interaction
|
||||
|
||||
Described by the Electroweak Theory, it unifies the electromagnetic force and the weak force at high energy levels. The weak force is responsible for changing one type of quark into another, leading to nuclear reactions.
|
||||
|
||||
#### Electroweak Theory Lagrangian
|
||||
|
||||
The Electroweak Lagrangian describes the interactions of leptons, quarks, and gauge bosons in the electroweak force. It can be expressed as:
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
\mathcal{L}_{EW} = -\frac{1}{4} W^a_{\mu\nu} W^{a\mu\nu} - \frac{1}{4} B_{\mu\nu} B^{\mu\nu} + \bar{\psi} (i \gamma^\mu D_\mu - m) \psi
|
||||
\label{eq:electroweak_lagrangian}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
1. **$W$ and $B$ Field Strength Tensors** ($W^a_{\mu\nu}$, $B_{\mu\nu}$):
|
||||
|
||||
- **$W$ Field Strength Tensor** ($W^a_{\mu\nu}$):
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
W^a_{\mu\nu} = \partial_\mu W^a_\nu - \partial_\nu W^a_\mu + g \epsilon^{abc} W^b_\mu W^c_\nu
|
||||
\label{eq:w_field_strength_tensor}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
- **$B$ Field Strength Tensor** ($B_{\mu\nu}$):
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
B_{\mu\nu} = \partial_\mu B_\nu - \partial_\nu B_\mu
|
||||
\label{eq:b_field_strength_tensor}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
- **Explanation**: These terms describe the field strengths of the $W$ and $B$ fields, which are associated with the weak and electromagnetic forces, respectively. The $W$ field strength tensor involves the non-Abelian field strength term, reflecting the non-Abelian nature of the weak force.
|
||||
|
||||
2. **Lepton/Quark Kinetic Term** $(\bar{\psi}(i\gamma^\mu D_\mu-m)\psi)$:
|
||||
|
||||
- **$\bar{\psi}$** - Dirac adjoint of the lepton/quark field $\psi$.
|
||||
- **$i \gamma^\mu D_\mu$** - Represents the kinetic term of the leptons/quarks, where $\gamma^\mu$ are the gamma matrices associated with the Dirac equation and $D_\mu$ is the covariant derivative.
|
||||
- **Covariant Derivative** ($D_\mu$):
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
D_\mu = \partial_\mu - i g' Y B_\mu - i g \frac{\tau^a}{2} W^a_\mu
|
||||
\label{eq:covariant_derivative_for_leptons_quarks}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
- **Explanation**: This accounts for the interaction of leptons/quarks with the $W$ and $B$ fields. $g'$ and $g$ are the coupling constants for the $U(1)$ and $SU(2)$ gauge groups, respectively. $Y$ is the weak hypercharge, and $\frac{\tau^a}{2}$ are the generators of the $SU(2)$ group.
|
||||
|
||||
3. **Lepton/Quark Mass Term** $(-m)$:
|
||||
- **Explanation**: Represents the mass of the leptons/quarks, contributing to the mass of particles. $(m)$ is the mass of the lepton/quark.
|
||||
|
||||
##### Key Points
|
||||
|
||||
- **$W$ and $B$ Field Strength Tensors**: The $W$ and $B$ field strength tensors describe the field strengths of the weak and electromagnetic fields, respectively. The $W$ field strength tensor involves the non-Abelian field strength term, reflecting the non-Abelian nature of the weak force.
|
||||
- **Lepton/Quark Interactions**: The covariant derivative $(D_\mu)$ in the lepton/quark term shows how leptons/quarks interact with the $W$ and $B$ fields. This term ensures that the theory respects gauge invariance under $U(1)$ and $SU(2)$ transformations.
|
||||
- **Mass of Leptons/Quarks**: The lepton/quark mass term shows how leptons/quarks acquire mass, contributing to the mass of particles. In the Electroweak Theory, the masses of leptons and quarks are fundamental parameters of the theory.
|
||||
|
||||
### Strong Interaction
|
||||
|
||||
Described by Quantum Chromodynamics (QCD), it involves quarks exchanging gluons. Quarks come in three "colors" (red, green, blue), and gluons carry a color charge that changes as they interact, ensuring quarks remain confined within protons and neutrons.
|
||||
|
||||
#### Quantum Chromodynamics (QCD) Lagrangian
|
||||
|
||||
The QCD Lagrangian describes the interactions of quarks and gluons, the fundamental constituents of the strong force. The Lagrangian can be expressed as:
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
\mathcal{L}_{QCD} = -\frac{1}{4} G^a_{\mu\nu} G^{a\mu\nu} + \sum_q \bar{q} (i \gamma^\mu D_\mu - m_q) q
|
||||
\label{eq:qcd_lagrangian}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
1. **Gluon Field Strength Tensor** ($G^a_{\mu\nu}$):
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
G^a_{\mu\nu} = \partial_\mu G^a_\nu - \partial_\nu G^a_\mu + g_s f^{abc} G^b_\mu G^c_\nu
|
||||
\label{eq:gluon_field_strength_tensor}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
- **Explanation**: This term describes the field strength of gluons. It involves the derivative of the gluon fields $(\partial_\mu G^a_\nu$ and $\partial_\nu G^a_\mu)$ and the non-Abelian field strength term involving the structure constants $f^{abc}$, which accounts for the interaction between gluons themselves.
|
||||
|
||||
2. **Quark Kinetic Term** $(\bar{q}(i\gamma^\mu D_\mu-m_q)q)$:
|
||||
|
||||
- **$\bar{q}$** - Dirac adjoint of the quark field $q$.
|
||||
- **$i \gamma^\mu D_\mu$** - Represents the kinetic term of the quarks, where $\gamma^\mu$ are the gamma matrices associated with the Dirac equation and $D_\mu$ is the covariant derivative.
|
||||
- **Covariant Derivative** ($D_\mu$):
|
||||
|
||||
$$
|
||||
\begin{equation}
|
||||
D_\mu = \partial_\mu - i g_s \frac{\lambda^a}{2} G^a_\mu
|
||||
\label{eq:quark_covariant_derivative_qcd}
|
||||
\end{equation}
|
||||
$$
|
||||
|
||||
- **Explanation**: This accounts for the interaction of quarks with gluons. $g_s$ is the strong coupling constant, and $\frac{\lambda^a}{2}$ are the generators of the SU(3) color gauge group. $G^a_\mu$ are the gluon fields.
|
||||
|
||||
3. **Quark Mass Term** $(-m_q)$:
|
||||
- **Explanation**: Represents the mass of the quarks, which interacts with the quark fields. $(m_q)$ is the mass of the quark.
|
||||
|
||||
##### Key Points
|
||||
|
||||
- **Color Charge**: Quarks come in three "colors" (red, green, blue) and interact via the exchange of gluons, which also carry color charge. This self-interaction among gluons is unique to non-Abelian gauge theories like QCD.
|
||||
- **Gauge Group**: The symmetry group for QCD is SU(3), reflecting the fact that there are three types of color charges in strong interactions. The structure constants $(f^{abc})$ encode the non-Abelian nature of the theory.
|
||||
- **Confinement**: QCD explains why quarks are never found in isolation but only in color-neutral combinations (hadrons). The interactions are so strong that quarks are confined within hadrons.
|
||||
|
||||
## Higgs Mechanism
|
||||
|
||||
The Higgs boson is an excitation of the Higgs field, discovered in 2012 at CERN. The Higgs mechanism explains how particles acquire mass through their interactions with this field. The Higgs field permeates all of space and gives mass to fundamental particles. The Higgs mechanism is crucial for understanding the origin of mass in the Standard Model.
|
||||
|
||||
### Higgs Field
|
||||
|
||||
The Higgs field is a scalar field that has a non-zero value in the vacuum. It interacts with other particles, giving them mass. The Higgs field is described by a potential that has a "Mexican hat" shape, with a minimum at a non-zero value. This non-zero vacuum expectation value (VEV) of the Higgs field breaks the electroweak symmetry and gives mass to the $W$ and $Z$ bosons.
|
||||
|
||||
## Limitations
|
||||
|
||||
While the Standard Model is incredibly successful, it has limitations:
|
||||
|
||||
- **Gravity**: The Standard Model does not include gravity, which is described by General Relativity and is not quantized.
|
||||
- **Dark Matter and Dark Energy**: These are components of the universe that do not interact via the Standard Model forces.
|
||||
- **Neutrino Masses**: Neutrino masses were a later addition to the Standard Model after the discovery of neutrino oscillations.
|
||||
- **Matter-Antimatter Asymmetry**: The observed dominance of matter over antimatter is not fully explained by the Standard Model.
|
||||
99
content/posts/test-post.md
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
---
|
||||
title: Hello, world
|
||||
description: This is the first post on the gly.cz blog.
|
||||
date: 2026-07-23
|
||||
author: hangerthem
|
||||
categories: ["blog", "hello world"]
|
||||
coverImage: image.png
|
||||
coverImageAlt: A picture of the hello world text in green on a black background.
|
||||
math: true
|
||||
mermaid: true
|
||||
---
|
||||
|
||||
Welcome to the gly.cz blog. Posts here are written in Markdown and turned into static HTML by ==Eleventy==.
|
||||
|
||||
## Writing a post
|
||||
|
||||
Add a Markdown file to `src/blog` with a title, description, and date in its front matter:
|
||||
|
||||
```md
|
||||
---
|
||||
title: A post title
|
||||
description: A short summary.
|
||||
date: 2026-07-22
|
||||
author: hangerthem
|
||||
---
|
||||
|
||||
Your post starts here.
|
||||
```
|
||||
|
||||
The surrounding layout is a React component, while Tailwind Typography styles the generated article HTML.
|
||||
|
||||
You can also use other code blocks in your Markdown, like this:
|
||||
|
||||
```ts
|
||||
function helloWorld() {
|
||||
console.log("Hello, world!");
|
||||
}
|
||||
```
|
||||
|
||||
Or you can use inline code like `console.log("Hello, world!")` in your Markdown.
|
||||
|
||||
### Images
|
||||
|
||||
You can add images to your posts by placing them in the `src/assets/blog`[^1] directory and referencing them in your Markdown:
|
||||
|
||||
```md
|
||||

|
||||
```
|
||||
|
||||
It will be rendered as:
|
||||
|
||||

|
||||
|
||||
> [!TIP] You can also use `>` to add blockquotes to your posts.
|
||||
|
||||
| Column 1 | Column 2 | Column 3 |
|
||||
|----------|----------|----------|
|
||||
| Cell 1 | Cell 2 | Cell 3 |
|
||||
| Cell 4 | Cell 5 | Cell 6 |
|
||||
|
||||
$$
|
||||
\frac{1}{2} + \frac{1}{3} = \frac{5}{6}
|
||||
$$
|
||||
|
||||
1. First item[^2]
|
||||
2. Second item
|
||||
3. Third item
|
||||
|
||||
- First item
|
||||
- Second item
|
||||
- Third item
|
||||
|
||||
---
|
||||
|
||||
[this is a link](https://example.com)
|
||||
|
||||
|
||||
```mermaid
|
||||
graph TD;
|
||||
A[Start] --> B{Is it working?};
|
||||
B -- Yes --> C[Great!];
|
||||
B -- No --> D[Check the code];
|
||||
D --> B
|
||||
```
|
||||
|
||||
Term 1
|
||||
: Definition for term 1.
|
||||
|
||||
Term 2
|
||||
: Definition A for term 2.
|
||||
: Definition B for term 2, on a new line.
|
||||
|
||||
H~2~O
|
||||
|
||||
- [ ] Task 1
|
||||
- [x] Task 2
|
||||
|
||||
[^1]: The `src/assets/blog` ==directory== is where you can place images for your blog posts. You can reference them in your Markdown using the relative path to the image file.
|
||||
[^2]: You can also add footnotes to your posts. This is a footnote reference, and the footnote text is at the bottom of the post.
|
||||
60
lib/mermaid-render.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
import { Browser, launch } from 'puppeteer'
|
||||
|
||||
let browserPromise: Promise<Browser> | null = null
|
||||
|
||||
function getBrowser() {
|
||||
if (!browserPromise) {
|
||||
browserPromise = launch({ headless: true })
|
||||
}
|
||||
return browserPromise
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the Puppeteer browser instance if it exists.
|
||||
* This function is useful for cleaning up resources when the application is shutting down or when the browser is no longer needed.
|
||||
*/
|
||||
export async function closeMermaidBrowser() {
|
||||
if (browserPromise) {
|
||||
const browser = await browserPromise
|
||||
await browser.close()
|
||||
browserPromise = null
|
||||
}
|
||||
}
|
||||
|
||||
const cache = new Map<string, string>()
|
||||
|
||||
/**
|
||||
* Renders a Mermaid chart to SVG using Puppeteer and caches the result.
|
||||
* @param chart - The Mermaid chart definition as a string.
|
||||
* @returns A promise that resolves to the rendered SVG string.
|
||||
*/
|
||||
export async function renderMermaidToSvg(chart: string): Promise<string> {
|
||||
const cached = cache.get(chart)
|
||||
if (cached) return cached
|
||||
|
||||
const browser = await getBrowser()
|
||||
const page = await browser.newPage()
|
||||
|
||||
try {
|
||||
await page.setContent(`
|
||||
<!DOCTYPE html>
|
||||
<html><body><div id="target"></div></body></html>
|
||||
`)
|
||||
await page.addScriptTag({
|
||||
url: 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.min.js',
|
||||
})
|
||||
|
||||
const svg = await page.evaluate(async (source) => {
|
||||
// @ts-expect-error mermaid is loaded globally via the script tag above
|
||||
window.mermaid.initialize({ startOnLoad: false, theme: 'neutral' })
|
||||
// @ts-expect-error same as above
|
||||
const { svg: renderedSvg } = await window.mermaid.render('mermaid-diagram', source)
|
||||
return renderedSvg
|
||||
}, chart)
|
||||
|
||||
cache.set(chart, svg)
|
||||
return svg
|
||||
} finally {
|
||||
await page.close()
|
||||
}
|
||||
}
|
||||
57
lib/posts.ts
|
|
@ -1,57 +0,0 @@
|
|||
import fs from "fs"
|
||||
import path from "path"
|
||||
import matter from "gray-matter"
|
||||
import { remark } from "remark"
|
||||
import html from "remark-html"
|
||||
|
||||
const postsDirectory = path.join(process.cwd(), "content/posts")
|
||||
|
||||
export interface PostMeta {
|
||||
slug: string
|
||||
title: string
|
||||
description: string
|
||||
author: string
|
||||
date: string
|
||||
categories: string[]
|
||||
tags: string[]
|
||||
math: boolean
|
||||
mermaid: boolean
|
||||
}
|
||||
|
||||
export function getAllPostSlugs(): string[] {
|
||||
return fs
|
||||
.readdirSync(postsDirectory)
|
||||
.filter((f) => f.endsWith(".md"))
|
||||
.map((f) => f.replace(/\.md$/, ""))
|
||||
}
|
||||
|
||||
export function getAllPostsMeta(): PostMeta[] {
|
||||
return getAllPostSlugs()
|
||||
.map((slug) => {
|
||||
const fullPath = path.join(postsDirectory, `${slug}.md`)
|
||||
const { data } = matter(fs.readFileSync(fullPath, "utf8"))
|
||||
return { slug, ...(data as Omit<PostMeta, "slug">) }
|
||||
})
|
||||
.sort((a, b) => (a.date < b.date ? 1 : -1))
|
||||
}
|
||||
|
||||
export async function getPostBySlug(slug: string) {
|
||||
const fullPath = path.join(postsDirectory, `${slug}.md`)
|
||||
const { data, content } = matter(fs.readFileSync(fullPath, "utf8"))
|
||||
const processedHtml = await remark().use(html).process(content)
|
||||
|
||||
return {
|
||||
meta: { slug, ...(data as Omit<PostMeta, "slug">) },
|
||||
contentHtml: processedHtml.toString(),
|
||||
}
|
||||
}
|
||||
|
||||
export function getPostsByCategory(category: string): PostMeta[] {
|
||||
return getAllPostsMeta().filter((post) =>
|
||||
post.categories.includes(category),
|
||||
)
|
||||
}
|
||||
|
||||
export function getPostsByTag(tag: string): PostMeta[] {
|
||||
return getAllPostsMeta().filter((post) => post.tags.includes(tag))
|
||||
}
|
||||
180
lib/posts.tsx
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
import matter from 'gray-matter'
|
||||
import { remark } from 'remark'
|
||||
import remarkParse from 'remark-parse'
|
||||
import gfm from 'remark-gfm'
|
||||
import remarkMath from 'remark-math'
|
||||
import remarkRehype from 'remark-rehype'
|
||||
import rehypeHighlight from 'rehype-highlight'
|
||||
import rehypeKatex from 'rehype-katex'
|
||||
import rehypeReact from 'rehype-react'
|
||||
import { cloneElement, isValidElement, type ReactElement, Fragment, type ReactNode } from 'react'
|
||||
import { jsx, jsxs } from 'react/jsx-runtime'
|
||||
import { rehypeCodeMeta } from './rehype-code-meta'
|
||||
import { CodeWrapper } from '@/components/common/CodeWrapper'
|
||||
import { ImageWrapper } from '@/components/common/ImageWrapper'
|
||||
import { ExternalLink } from '@/components/common/ExternalLink'
|
||||
import readingTime from 'reading-time'
|
||||
import { rehypeUnwrapImages } from './rehype-unwrap-images'
|
||||
import { rehypeMermaidSsg } from './rehype-mermaid-ssg'
|
||||
import { stripLeadingMatch } from './react-node-text'
|
||||
import { BlockquoteWrapper } from '@/components/common/BlockquoteWrapper'
|
||||
import type { NoteType } from '@/types/Note.type'
|
||||
import { rehypeMark } from './rehype-mark'
|
||||
import { rehypeDefinition } from './rehype-definition'
|
||||
import { slugify } from '@/utils/slug'
|
||||
|
||||
const postsDirectory = path.join(process.cwd(), 'content/posts')
|
||||
|
||||
function getTextContent(node: ReactNode): string {
|
||||
if (typeof node === 'string') return node
|
||||
if (typeof node === 'number') return String(node)
|
||||
if (Array.isArray(node)) return node.map(getTextContent).join('')
|
||||
if (node && typeof node === 'object' && 'props' in node) {
|
||||
const props = node.props as { children?: ReactNode }
|
||||
return getTextContent(props.children)
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
export interface PostMeta {
|
||||
slug: string
|
||||
title: string
|
||||
description: string
|
||||
author: string
|
||||
date: string
|
||||
categories: string[]
|
||||
tags: string[]
|
||||
math: boolean
|
||||
mermaid: boolean
|
||||
readingTimeText: string
|
||||
coverImage?: string
|
||||
coverImageAlt?: string
|
||||
}
|
||||
|
||||
export function getAllPostSlugs(): string[] {
|
||||
return fs
|
||||
.readdirSync(postsDirectory)
|
||||
.filter((f) => f.endsWith('.md'))
|
||||
.map((f) => f.replace(/\.md$/, ''))
|
||||
}
|
||||
|
||||
export function getAllPostsMeta(): PostMeta[] {
|
||||
return getAllPostSlugs()
|
||||
.map((slug) => {
|
||||
const fullPath = path.join(postsDirectory, `${slug}.md`)
|
||||
const { data } = matter(fs.readFileSync(fullPath, 'utf8'))
|
||||
return Object.assign({ slug }, data as Omit<PostMeta, 'slug'>)
|
||||
})
|
||||
.toSorted((a, b) => (a.date < b.date ? 1 : -1))
|
||||
}
|
||||
|
||||
export async function getPostBySlug(slug: string) {
|
||||
const fullPath = path.join(postsDirectory, `${slug}.md`)
|
||||
const { data, content } = matter(fs.readFileSync(fullPath, 'utf8'))
|
||||
|
||||
let processor = remark().use(remarkParse).use(gfm)
|
||||
|
||||
if (data.math) {
|
||||
processor = processor.use(remarkMath)
|
||||
}
|
||||
|
||||
processor = processor
|
||||
.use(remarkRehype, { allowDangerousHtml: true })
|
||||
.use(rehypeHighlight)
|
||||
.use(rehypeCodeMeta)
|
||||
.use(rehypeMark)
|
||||
.use(rehypeDefinition)
|
||||
|
||||
if (data.math) {
|
||||
processor = processor.use(rehypeKatex, { output: 'mathml' })
|
||||
}
|
||||
|
||||
if (data.mermaid) {
|
||||
processor = processor.use(rehypeMermaidSsg)
|
||||
}
|
||||
|
||||
processor = processor.use(rehypeUnwrapImages).use(rehypeReact, {
|
||||
Fragment,
|
||||
jsx,
|
||||
jsxs,
|
||||
components: {
|
||||
pre: ({ children, ...props }: { children: ReactNode; [key: string]: unknown }) => {
|
||||
const language =
|
||||
typeof props['data-language'] === 'string' ? props['data-language'] : undefined
|
||||
return <CodeWrapper language={language}>{children}</CodeWrapper>
|
||||
},
|
||||
img: ({ src, alt }: { src: string; alt: string }) => <ImageWrapper src={src} alt={alt} />,
|
||||
a: ({ href, children }: { href: string; children: ReactNode }) =>
|
||||
href?.startsWith('http') ? (
|
||||
<ExternalLink href={href}>{children}</ExternalLink>
|
||||
) : (
|
||||
<a href={href}>{children}</a>
|
||||
),
|
||||
blockquote: ({ children }: { children: ReactNode }) => {
|
||||
const textContent = getTextContent(children).trimStart()
|
||||
const type = textContent.match(/^\[!(\w+)\]/)?.[1]?.toLowerCase() as NoteType | undefined
|
||||
return (
|
||||
<BlockquoteWrapper type={type}>
|
||||
{stripLeadingMatch(children, /^\[!(\w+)\]/)}
|
||||
</BlockquoteWrapper>
|
||||
)
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const file = await processor.process(content)
|
||||
const rawContentNode = file.result as ReactNode
|
||||
|
||||
const readingTimeText = readingTime(content).text
|
||||
|
||||
const tableOfContents: { text: string; id: string; level: number }[] = []
|
||||
const seenIds = new Map<string, number>()
|
||||
|
||||
function withHeadingIds(node: ReactNode): ReactNode {
|
||||
if (!isValidElement(node)) return node
|
||||
|
||||
const element = node as ReactElement<{ children?: ReactNode; id?: string }>
|
||||
if (element.type === 'h2' || element.type === 'h3') {
|
||||
const text = getTextContent(element.props.children ?? [])
|
||||
let id = slugify(text)
|
||||
|
||||
const seenCount = seenIds.get(id) ?? 0
|
||||
seenIds.set(id, seenCount + 1)
|
||||
if (seenCount > 0) id = `${id}-${seenCount}`
|
||||
|
||||
const level = element.type === 'h2' ? 2 : 3
|
||||
tableOfContents.push({ text, id, level })
|
||||
|
||||
return cloneElement(element, { id })
|
||||
}
|
||||
|
||||
return node
|
||||
}
|
||||
|
||||
const rawChildren = isValidElement(rawContentNode)
|
||||
? (rawContentNode.props as { children?: ReactNode }).children
|
||||
: rawContentNode
|
||||
const childrenArray = Array.isArray(rawChildren) ? rawChildren : [rawChildren]
|
||||
|
||||
const processedChildren = childrenArray.map(withHeadingIds)
|
||||
|
||||
const processedContent = isValidElement(rawContentNode)
|
||||
? cloneElement(rawContentNode, {}, processedChildren)
|
||||
: rawContentNode
|
||||
|
||||
return {
|
||||
meta: { ...(data as Omit<PostMeta, 'slug'>), readingTimeText },
|
||||
content: processedContent,
|
||||
tableOfContents,
|
||||
}
|
||||
}
|
||||
|
||||
export function getPostsByCategory(category: string): PostMeta[] {
|
||||
return getAllPostsMeta().filter((post) => post.categories.includes(category))
|
||||
}
|
||||
|
||||
export function getPostsByTag(tag: string): PostMeta[] {
|
||||
return getAllPostsMeta().filter((post) => post.tags.includes(tag))
|
||||
}
|
||||
58
lib/react-node-text.ts
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
import { cloneElement, isValidElement, type ReactNode } from "react";
|
||||
|
||||
/**
|
||||
* Recursively traverses a ReactNode tree and extracts the text content.
|
||||
* @param node - The ReactNode to process.
|
||||
* @returns A string containing the concatenated text content of the ReactNode tree.
|
||||
*/
|
||||
export function getTextContent(node: ReactNode): string {
|
||||
if (node === null || typeof node === "boolean") return "";
|
||||
if (typeof node === "string" || typeof node === "number") return String(node);
|
||||
if (Array.isArray(node)) return node.map(getTextContent).join("");
|
||||
if (isValidElement(node)) {
|
||||
const props = node.props as { children?: ReactNode };
|
||||
return getTextContent(props.children);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively traverses a ReactNode tree and removes leading whitespace and a specified pattern from the beginning of text nodes.
|
||||
* @param node - The ReactNode to process.
|
||||
* @param pattern - The regular expression pattern to match and remove from the beginning of text nodes.
|
||||
* @returns A new ReactNode with the leading whitespace and specified pattern removed from text nodes.
|
||||
*/
|
||||
export function stripLeadingMatch(node: ReactNode, pattern: RegExp): ReactNode {
|
||||
if (typeof node === "string") {
|
||||
const trimmed = node.replace(/^\s+/, "");
|
||||
if (pattern.test(trimmed)) {
|
||||
return trimmed.replace(pattern, "").replace(/^\s+/, "");
|
||||
}
|
||||
return node;
|
||||
}
|
||||
if (Array.isArray(node)) {
|
||||
let stripped = false;
|
||||
return node.map((child) => {
|
||||
if (stripped) return child;
|
||||
if (typeof child === "string" && child.trim() === "") return child; // skip whitespace nodes
|
||||
if (typeof child === "string") {
|
||||
const trimmed = child.replace(/^\s+/, "");
|
||||
if (pattern.test(trimmed)) {
|
||||
stripped = true;
|
||||
return trimmed.replace(pattern, "").replace(/^\s+/, "");
|
||||
}
|
||||
return child;
|
||||
}
|
||||
if (isValidElement(child)) {
|
||||
stripped = true;
|
||||
return stripLeadingMatch(child, pattern);
|
||||
}
|
||||
return child;
|
||||
});
|
||||
}
|
||||
if (isValidElement(node)) {
|
||||
const props = node.props as { children?: ReactNode };
|
||||
return cloneElement(node, {}, stripLeadingMatch(props.children, pattern));
|
||||
}
|
||||
return node;
|
||||
}
|
||||
33
lib/rehype-code-meta.tsx
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import type { Root, Element } from 'hast'
|
||||
import type { Plugin } from 'unified'
|
||||
import { visit } from 'unist-util-visit'
|
||||
import { toText } from 'hast-util-to-text'
|
||||
|
||||
/**
|
||||
* A rehype plugin that processes code blocks and adds metadata.
|
||||
* Specifically, it looks for <pre> elements containing <code> elements,
|
||||
* extracts the language from the className, and adds a data-language attribute to the <pre> element.
|
||||
* If the language is "mermaid", it transforms the <pre> into a <div> with a data-mermaid attribute containing the code content.
|
||||
*/
|
||||
export const rehypeCodeMeta: Plugin<[], Root> = () => (tree: Root) => {
|
||||
visit(tree, 'element', (node: Element) => {
|
||||
if (node.tagName !== 'pre') return
|
||||
const codeNode = node.children.find(
|
||||
(c): c is Element => c.type === 'element' && c.tagName === 'code',
|
||||
)
|
||||
if (!codeNode) return
|
||||
|
||||
const classNames = (codeNode.properties?.className ?? []) as string[]
|
||||
const language =
|
||||
classNames.find((c) => c.startsWith('language-'))?.replace('language-', '') ?? 'text'
|
||||
|
||||
if (language === 'mermaid') {
|
||||
node.tagName = 'div'
|
||||
node.properties = { 'data-mermaid': toText(codeNode) }
|
||||
node.children = []
|
||||
return
|
||||
}
|
||||
|
||||
node.properties = { ...node.properties, 'data-language': language }
|
||||
})
|
||||
}
|
||||
72
lib/rehype-definition.tsx
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
import type { Root, Element, ElementContent, Text } from 'hast'
|
||||
import type { Plugin } from 'unified'
|
||||
import { visit } from 'unist-util-visit'
|
||||
|
||||
/**
|
||||
* A rehype plugin that transforms paragraphs containing a leading "Term:" into
|
||||
* definition lists. For example, a paragraph like "Term: Definition" will be
|
||||
* transformed into a <dl> element with a <dt> for the term and a <dd> for the
|
||||
* definition.
|
||||
*/
|
||||
export const rehypeDefinition: Plugin<[], Root> = () => (tree: Root) => {
|
||||
visit(tree, 'element', (node: Element, index, parent) => {
|
||||
if (!parent || typeof index !== 'number') return
|
||||
if (node.tagName !== 'p') return
|
||||
|
||||
const children = node.children
|
||||
|
||||
let splitIndex = -1
|
||||
let colonIndex = -1
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
const child = children[i]
|
||||
if (child.type === 'text') {
|
||||
const idx = child.value.indexOf(':')
|
||||
if (idx !== -1) {
|
||||
splitIndex = i
|
||||
colonIndex = idx
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (splitIndex === -1) return
|
||||
|
||||
const splitText = children[splitIndex] as Text
|
||||
const beforeColon = splitText.value.slice(0, colonIndex)
|
||||
const afterColon = splitText.value.slice(colonIndex + 1).replace(/^\s+/, '')
|
||||
|
||||
const termChildren: ElementContent[] = [
|
||||
...children.slice(0, splitIndex),
|
||||
...(beforeColon ? [{ type: 'text', value: beforeColon } as Text] : []),
|
||||
]
|
||||
|
||||
const definitionChildren: ElementContent[] = [
|
||||
...(afterColon ? [{ type: 'text', value: afterColon } as Text] : []),
|
||||
...children.slice(splitIndex + 1),
|
||||
]
|
||||
|
||||
if (termChildren.length === 0 || definitionChildren.length === 0) return
|
||||
|
||||
const dlNode: Element = {
|
||||
type: 'element',
|
||||
tagName: 'dl',
|
||||
properties: {},
|
||||
children: [
|
||||
{
|
||||
type: 'element',
|
||||
tagName: 'dt',
|
||||
properties: {},
|
||||
children: termChildren,
|
||||
},
|
||||
{
|
||||
type: 'element',
|
||||
tagName: 'dd',
|
||||
properties: {},
|
||||
children: definitionChildren,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
parent.children[index] = dlNode
|
||||
})
|
||||
}
|
||||
52
lib/rehype-mark.tsx
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
import type { Root, ElementContent } from 'hast'
|
||||
import type { Plugin } from 'unified'
|
||||
import { visit } from 'unist-util-visit'
|
||||
|
||||
/**
|
||||
* A rehype plugin that processes text nodes and wraps text enclosed in double equal signs (==) with <mark> tags.
|
||||
* For example, "This is ==highlighted==" will be transformed into "This is <mark>highlighted</mark>".
|
||||
*/
|
||||
export const rehypeMark: Plugin<[], Root> = () => (tree: Root) => {
|
||||
visit(tree, 'text', (node: ElementContent, index, parent) => {
|
||||
if (!parent || typeof index !== 'number') return
|
||||
|
||||
const textNode = node as ElementContent & { value: string }
|
||||
const regex = /==([^=]+)==/g
|
||||
const matches = [...textNode.value.matchAll(regex)]
|
||||
|
||||
if (matches.length === 0) return
|
||||
|
||||
const newNodes: ElementContent[] = []
|
||||
let lastIndex = 0
|
||||
|
||||
for (const match of matches) {
|
||||
const [fullMatch, innerText] = match
|
||||
const matchStartIndex = match.index ?? 0
|
||||
|
||||
if (matchStartIndex > lastIndex) {
|
||||
newNodes.push({
|
||||
type: 'text',
|
||||
value: textNode.value.slice(lastIndex, matchStartIndex),
|
||||
})
|
||||
}
|
||||
|
||||
newNodes.push({
|
||||
type: 'element',
|
||||
tagName: 'mark',
|
||||
properties: {},
|
||||
children: [{ type: 'text', value: innerText }],
|
||||
})
|
||||
|
||||
lastIndex = matchStartIndex + fullMatch.length
|
||||
}
|
||||
|
||||
if (lastIndex < textNode.value.length) {
|
||||
newNodes.push({
|
||||
type: 'text',
|
||||
value: textNode.value.slice(lastIndex),
|
||||
})
|
||||
}
|
||||
|
||||
parent.children.splice(index, 1, ...newNodes)
|
||||
})
|
||||
}
|
||||
39
lib/rehype-mermaid-ssg.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import type { Root, Element } from 'hast'
|
||||
import type { Plugin } from 'unified'
|
||||
import { visit } from 'unist-util-visit'
|
||||
import { fromHtmlIsomorphic } from 'hast-util-from-html-isomorphic'
|
||||
import { renderMermaidToSvg } from './mermaid-render'
|
||||
|
||||
/**
|
||||
* A rehype plugin that processes <div> elements with a data-mermaid attribute and renders the Mermaid chart to SVG.
|
||||
* It replaces the <div> with the rendered SVG or displays an error message if rendering fails.
|
||||
*/
|
||||
export const rehypeMermaidSsg: Plugin<[], Root> = () => async (tree: Root) => {
|
||||
const targets: { node: Element; parent: Element | Root; index: number }[] = []
|
||||
|
||||
visit(tree, 'element', (node: Element, index, parent) => {
|
||||
if (node.tagName === 'div' && node.properties?.['data-mermaid'] && parent && typeof index === 'number') {
|
||||
targets.push({ node, parent: parent as Element | Root, index })
|
||||
}
|
||||
})
|
||||
|
||||
await Promise.all(
|
||||
targets.map(async ({ node, parent, index }) => {
|
||||
const chart = String(node.properties!['data-mermaid'])
|
||||
try {
|
||||
const svg = await renderMermaidToSvg(chart)
|
||||
const svgTree = fromHtmlIsomorphic(svg, { fragment: true })
|
||||
const svgNode = svgTree.children.find((c) => c.type === 'element') as Element | undefined
|
||||
if (svgNode) {
|
||||
; (parent.children as Element[])[index] = svgNode
|
||||
}
|
||||
} catch (err) {
|
||||
node.tagName = 'pre'
|
||||
node.properties = { className: ['text-red-500', 'text-sm'] }
|
||||
node.children = [
|
||||
{ type: 'text', value: `Mermaid render error: ${(err as Error).message}` },
|
||||
]
|
||||
}
|
||||
}),
|
||||
)
|
||||
}
|
||||
26
lib/rehype-unwrap-images.tsx
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import type { Root, Element, ElementContent } from 'hast'
|
||||
import type { Plugin } from 'unified'
|
||||
import { visit } from 'unist-util-visit'
|
||||
|
||||
function isWhitespaceText(node: ElementContent) {
|
||||
return node.type === 'text' && node.value.trim() === ''
|
||||
}
|
||||
|
||||
/**
|
||||
* A rehype plugin that unwraps <img> elements from <p> tags if the <p> contains only the <img> and optional whitespace.
|
||||
* For example, a paragraph like "<p><img src='image.png' alt='An image'></p>" will be transformed into "<img src='image.png' alt='An image'>".
|
||||
*/
|
||||
export const rehypeUnwrapImages: Plugin<[], Root> = () => (tree: Root) => {
|
||||
visit(tree, 'element', (node: Element, index, parent) => {
|
||||
if (node.tagName !== 'p' || !parent || typeof index !== 'number') return
|
||||
|
||||
const meaningfulChildren = node.children.filter((c) => !isWhitespaceText(c))
|
||||
if (
|
||||
meaningfulChildren.length === 1 &&
|
||||
meaningfulChildren[0].type === 'element' &&
|
||||
meaningfulChildren[0].tagName === 'img'
|
||||
) {
|
||||
parent.children[index] = meaningfulChildren[0]
|
||||
}
|
||||
})
|
||||
}
|
||||
36
package.json
|
|
@ -6,19 +6,42 @@
|
|||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "eslint"
|
||||
"lint": "oxlint . && oxfmt --check",
|
||||
"lint:fix": "oxlint . --fix && oxfmt --write",
|
||||
"format": "oxfmt --check",
|
||||
"format:write": "oxfmt --write",
|
||||
"postinstall": "puppeteer browsers install chrome"
|
||||
},
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1",
|
||||
"gray-matter": "^4.0.3",
|
||||
"hast": "^1.0.0",
|
||||
"hast-util-from-html-isomorphic": "^2.0.0",
|
||||
"hast-util-to-text": "^4.0.2",
|
||||
"highlight.js": "^11.11.1",
|
||||
"lucide-react": "^1.28.0",
|
||||
"next": "16.2.12",
|
||||
"oxfmt": "^0.61.0",
|
||||
"oxlint": "^1.76.0",
|
||||
"puppeteer": "^25.4.0",
|
||||
"react": "19.2.4",
|
||||
"react-dom": "19.2.4",
|
||||
"reading-time": "^1.5.0",
|
||||
"rehype-highlight": "^7.0.2",
|
||||
"rehype-katex": "^7.0.1",
|
||||
"rehype-react": "^8.0.0",
|
||||
"remark": "^15.0.1",
|
||||
"remark-html": "^16.0.1"
|
||||
"remark-gfm": "^4.0.1",
|
||||
"remark-math": "^6.0.0",
|
||||
"remark-parse": "^11.0.0",
|
||||
"remark-rehype": "^11.1.2",
|
||||
"tailwind-merge": "^3.6.0",
|
||||
"unified": "^11.0.5",
|
||||
"unist-util-visit": "^5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/hast": "^3.0.4",
|
||||
"@types/node": "^26.1.1",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
|
|
@ -27,12 +50,9 @@
|
|||
"tailwindcss": "^4",
|
||||
"typescript": "^5"
|
||||
},
|
||||
"ignoreScripts": [
|
||||
"sharp",
|
||||
"unrs-resolver"
|
||||
],
|
||||
"trustedDependencies": [
|
||||
"sharp",
|
||||
"unrs-resolver"
|
||||
"unrs-resolver",
|
||||
"puppeteer"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +0,0 @@
|
|||
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
||||
|
Before Width: | Height: | Size: 391 B |
|
|
@ -1 +0,0 @@
|
|||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
||||
|
Before Width: | Height: | Size: 1 KiB |
BIN
public/image.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB |
1658
public/standard_model.svg
Normal file
|
After Width: | Height: | Size: 85 KiB |
|
|
@ -1 +0,0 @@
|
|||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
||||
|
Before Width: | Height: | Size: 128 B |
|
|
@ -1 +0,0 @@
|
|||
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
||||
|
Before Width: | Height: | Size: 385 B |
1
types/Note.type.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export type NoteType = 'warning' | 'tip' | 'info'
|
||||
10
utils/cn.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { clsx, type ClassValue } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
/**
|
||||
* Utility function to merge Tailwind CSS classes
|
||||
* Combines clsx for conditional classes with tailwind-merge for deduplication
|
||||
*/
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
12
utils/slug.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/**
|
||||
* Converts a string into a URL-friendly slug.
|
||||
* @param text - The input string to be converted into a slug.
|
||||
* @returns A URL-friendly slug string.
|
||||
*/
|
||||
export function slugify(text: string): string {
|
||||
return text
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/\s+/g, '-')
|
||||
.replace(/[^\w-]/g, '')
|
||||
}
|
||||