Forgor to publish a bit

This commit is contained in:
HangerThem 2026-08-02 17:49:15 +02:00
parent 66d0efa399
commit 231bdfc079
42 changed files with 3655 additions and 231 deletions

18
.oxfmtrc.json Normal file
View 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
View 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/**"]
}

View file

@ -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>
)
}

View 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>
)
}

View file

@ -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, "&amp;")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;")
.replace(/'/g, "&apos;")
}
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" },
})
}

View file

@ -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;
}

View file

@ -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>
)
}

View file

@ -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
View 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>
)
}

View file

@ -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>
)
}

View file

@ -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
View file

@ -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=="],
}
}

View 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>
)
}

View 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>
)
}

View 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>
)
}

View 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"
/>
);
}

View 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>
)
}

View 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>
)
}

View 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>
)
}

View file

@ -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

View 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.

View 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
![Alt text](image.png)
```
It will be rendered as:
![A picture of the hello world text in green on a black background.](image.png)
> [!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
View 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()
}
}

View file

@ -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
View 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
View 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
View 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
View 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
View 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
View 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}` },
]
}
}),
)
}

View 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]
}
})
}

View file

@ -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"
]
}

View file

@ -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

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View file

@ -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

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 85 KiB

View file

@ -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

View file

@ -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
View file

@ -0,0 +1 @@
export type NoteType = 'warning' | 'tip' | 'info'

10
utils/cn.ts Normal file
View 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
View 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, '')
}