diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..5928ce1 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +node_modules +.next +Dockerfile +.git +.gitignore +*.mdx \ No newline at end of file diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..0efc1c8 --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,25 @@ +name: Build and Deploy Blog + +on: + push: + branches: + - master + workflow_dispatch: + +jobs: + build-and-deploy-local: + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v3 + + - name: Rebuild and Deploy with Docker Compose + run: | + # Use the host's Docker to build the image defined in docker-compose.yml + # The '--no-cache' flag ensures it picks up any changes from your repository + # The 'up -d' command will recreate only the services that have changed + docker-compose up -d --build --no-cache + + # Clean up any old, unused images to save disk space + docker image prune -f \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..57bf94e --- /dev/null +++ b/Dockerfile @@ -0,0 +1,31 @@ +FROM oven/bun:1 AS base +WORKDIR /app + +FROM base AS install +RUN mkdir -p /temp/dev +COPY package.json bun.lock /temp/dev/ +RUN cd /temp/dev && bun install --frozen-lockfile + +RUN mkdir -p /temp/prod +COPY package.json bun.lock /temp/prod/ +RUN cd /temp/prod && bun install --frozen-lockfile --production + +FROM base AS prerelease +COPY --from=install /temp/dev/node_modules node_modules +COPY . . + +ENV NODE_ENV=production +RUN bun run build + +FROM base AS release + +COPY --from=prerelease /app/public ./public +COPY --from=prerelease /app/.next ./.next +COPY --from=prerelease /app/node_modules ./node_modules +COPY --from=prerelease /app/package.json ./package.json + +USER bun +EXPOSE 3000/tcp + +CMD ["bun", "run", "start"] + diff --git a/app/favicon.ico b/app/favicon.ico index 718d6fe..ccd7e30 100644 Binary files a/app/favicon.ico and b/app/favicon.ico differ diff --git a/app/frutiger-bold.woff b/app/frutiger-bold.woff new file mode 100644 index 0000000..fcf723c Binary files /dev/null and b/app/frutiger-bold.woff differ diff --git a/app/frutiger.woff b/app/frutiger.woff new file mode 100644 index 0000000..bbc17d6 Binary files /dev/null and b/app/frutiger.woff differ diff --git a/app/globals.css b/app/globals.css index a2dc41e..8714e84 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,10 +1,25 @@ @import "tailwindcss"; +@plugin "@tailwindcss/typography"; :root { --background: #ffffff; --foreground: #171717; } +@theme { + --color-aero-blue: #7cb9e8; + --color-aero-green: #8ff0a4; + --color-sky-blue: #87ceeb; + --color-grass-green: #7cfc00; + --color-water: #00bfff; + --color-window-title: #0058e1; + + --background-start: var(--color-sky-blue); + --background-end: var(--color-lime-300); + + --font-display: var(--font-frutiger), "Arial", "Helvetica", "sans-serif"; +} + @theme inline { --color-background: var(--background); --color-foreground: var(--foreground); @@ -20,7 +35,27 @@ } body { - background: var(--background); - color: var(--foreground); - font-family: Arial, Helvetica, sans-serif; + background-color: #3cb1e7; + background-image: + /* A subtle white radial gradient for a "lens flare" or glossy spot effect */ radial-gradient( + circle at 10% 20%, + rgba(255, 255, 255, 0.4) 0%, + rgba(255, 255, 255, 0) 25% + ), + /* The main blue sky gradient */ + linear-gradient(to bottom, #54c5f9 0%, #87e0fd 70%), + /* The green hill at the bottom */ + radial-gradient(circle at 50% 100%, #9cff9c 0%, #3cdc5c 40%, #24a844 80%); + background-attachment: fixed; + min-height: 100vh; + color: #333; +} + +::selection { + background-color: #0058e1; + color: white; +} + +.window-shadow { + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2), 0 1px 3px rgba(0, 0, 0, 0.1); } diff --git a/app/layout.tsx b/app/layout.tsx index f7fa87e..1ad3872 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,20 +1,28 @@ import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; import "./globals.css"; -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", - subsets: ["latin"], +import localFont from "next/font/local"; +import SwitchingBackground from "@/components/switching-background"; +import CursorEffect from "@/components/cursor-effect"; +const frutiger = localFont({ + src: [ + { + path: "./frutiger.woff", + weight: "normal", + style: "normal", + }, + { + path: "./frutiger-bold.woff", + weight: "bold", + style: "normal", + }, + ], + variable: "--font-frutiger", }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "Gabriel Kaszewski's Blog", + description: "A personal blog by Gabriel Kaszewski", }; export default function RootLayout({ @@ -24,10 +32,10 @@ export default function RootLayout({ }>) { return ( - - {children} + + + +
{children}
); diff --git a/app/page.tsx b/app/page.tsx index 21b686d..9f3cfbb 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,103 +1,51 @@ -import Image from "next/image"; +import { getSortedPostsData, PostMeta } from "../lib/posts"; +import Link from "next/link"; +import Window from "../components/window"; export default function Home() { - return ( -
-
- Next.js logo -
    -
  1. - Get started by editing{" "} - - app/page.tsx - - . -
  2. -
  3. - Save and see your changes instantly. -
  4. -
+ const allPostsData: PostMeta[] = getSortedPostsData(); -
- - Vercel logomark - Deploy now - - - Read our docs - -
-
- + return ( +
+
+

+ Gabriel's Kaszewski Blog +

+

+ A little corner of the internet from the 2000s. +

+
+ +
+ {/* The list of posts is displayed inside our custom Window component */} + + {allPostsData.length > 0 ? ( +
    + {allPostsData.map(({ id, date, title }) => ( +
  • + +

    {title}

    + + {new Date(date).toLocaleDateString("en-US", { + year: "numeric", + month: "long", + day: "numeric", + })} + + +
  • + ))} +
+ ) : ( +

+ No posts found. Add some markdown files to the 'posts' directory! +

+ )} +
+
); } diff --git a/app/posts/[slug]/page.tsx b/app/posts/[slug]/page.tsx new file mode 100644 index 0000000..ae33f17 --- /dev/null +++ b/app/posts/[slug]/page.tsx @@ -0,0 +1,62 @@ +import Link from "next/link"; +import { getPostData, getAllPostIds } from "@/lib/posts"; +import type { PostData } from "@/lib/posts"; +import Window from "../../../components/window"; +import { MDXRemote } from "next-mdx-remote/rsc"; + +interface PageProps { + params: { + slug: string; + }; +} + +// This function tells Next.js which blog posts exist at build time +export async function generateStaticParams() { + const paths = getAllPostIds(); + return paths.map((path) => ({ slug: path.params.slug })); +} + +// Generates metadata (like the title tag) for each blog post page +export async function generateMetadata({ params }: PageProps) { + const postData = await getPostData(params.slug); + return { + title: `${postData.title} | Gabriel's Kaszewski Blog`, + }; +} + +export default async function Post({ params }: PageProps) { + // Fetch the specific post's content based on the URL slug + const postData: PostData = await getPostData(params.slug); + + return ( +
+ +
+
+ + {new Date(postData.date).toLocaleDateString("en-US", { + year: "numeric", + month: "long", + day: "numeric", + })} + + + {postData.readingTime} + +
+
+ +
+
+
+
+ + ← Back to home + +
+
+ ); +} diff --git a/bun.lock b/bun.lock index 8074768..cc74c0d 100644 --- a/bun.lock +++ b/bun.lock @@ -4,9 +4,16 @@ "": { "name": "blog", "dependencies": { + "@tailwindcss/typography": "^0.5.16", + "cursor-effects": "^1.0.17", + "gray-matter": "^4.0.3", "next": "15.5.2", + "next-mdx-remote": "^5.0.0", "react": "19.1.0", "react-dom": "19.1.0", + "reading-time": "^1.5.0", + "remark": "^15.0.1", + "remark-html": "^16.0.1", }, "devDependencies": { "@tailwindcss/postcss": "^4", @@ -21,6 +28,10 @@ "packages": { "@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="], + "@babel/code-frame": ["@babel/code-frame@7.27.1", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.27.1", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg=="], + + "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.27.1", "", {}, "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow=="], + "@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], "@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.3", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.0" }, "os": "darwin", "cpu": "arm64" }, "sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg=="], @@ -79,6 +90,10 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.30", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q=="], + "@mdx-js/mdx": ["@mdx-js/mdx@3.1.1", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdx": "^2.0.0", "acorn": "^8.0.0", "collapse-white-space": "^2.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-util-scope": "^1.0.0", "estree-walker": "^3.0.0", "hast-util-to-jsx-runtime": "^2.0.0", "markdown-extensions": "^2.0.0", "recma-build-jsx": "^1.0.0", "recma-jsx": "^1.0.0", "recma-stringify": "^1.0.0", "rehype-recma": "^1.0.0", "remark-mdx": "^3.0.0", "remark-parse": "^11.0.0", "remark-rehype": "^11.0.0", "source-map": "^0.7.0", "unified": "^11.0.0", "unist-util-position-from-estree": "^2.0.0", "unist-util-stringify-position": "^4.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ=="], + + "@mdx-js/react": ["@mdx-js/react@3.1.1", "", { "dependencies": { "@types/mdx": "^2.0.0" }, "peerDependencies": { "@types/react": ">=16", "react": ">=16" } }, "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw=="], + "@next/env": ["@next/env@15.5.2", "", {}, "sha512-Qe06ew4zt12LeO6N7j8/nULSOe3fMXE4dM6xgpBQNvdzyK1sv5y4oAP3bq4LamrvGCZtmRYnW8URFCeX5nFgGg=="], "@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.5.2", "", { "os": "darwin", "cpu": "arm64" }, "sha512-8bGt577BXGSd4iqFygmzIfTYizHb0LGWqH+qgIF/2EDxS5JsSdERJKA8WgwDyNBZgTIIA4D8qUtoQHmxIIquoQ=="], @@ -129,18 +144,60 @@ "@tailwindcss/postcss": ["@tailwindcss/postcss@4.1.12", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.1.12", "@tailwindcss/oxide": "4.1.12", "postcss": "^8.4.41", "tailwindcss": "4.1.12" } }, "sha512-5PpLYhCAwf9SJEeIsSmCDLgyVfdBhdBpzX1OJ87anT9IVR0Z9pjM0FNixCAUAHGnMBGB8K99SwAheXrT0Kh6QQ=="], + "@tailwindcss/typography": ["@tailwindcss/typography@0.5.16", "", { "dependencies": { "lodash.castarray": "^4.4.0", "lodash.isplainobject": "^4.0.6", "lodash.merge": "^4.6.2", "postcss-selector-parser": "6.0.10" }, "peerDependencies": { "tailwindcss": ">=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1" } }, "sha512-0wDLwCVF5V3x3b1SGXPCDcdsbDHMBe+lkFzBRaHeLvNi+nrrnZ1lA18u+OTWO8iSWU2GxUOCvlXtDuqftc1oiA=="], + + "@types/debug": ["@types/debug@4.1.12", "", { "dependencies": { "@types/ms": "*" } }, "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ=="], + + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], + + "@types/estree-jsx": ["@types/estree-jsx@1.0.5", "", { "dependencies": { "@types/estree": "*" } }, "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg=="], + + "@types/hast": ["@types/hast@3.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ=="], + + "@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="], + + "@types/mdx": ["@types/mdx@2.0.13", "", {}, "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw=="], + + "@types/ms": ["@types/ms@2.1.0", "", {}, "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA=="], + "@types/node": ["@types/node@20.19.12", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-lSOjyS6vdO2G2g2CWrETTV3Jz2zlCXHpu1rcubLKpz9oj+z/1CceHlj+yq53W+9zgb98nSov/wjEKYDNauD+Hw=="], "@types/react": ["@types/react@19.1.12", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w=="], "@types/react-dom": ["@types/react-dom@19.1.9", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ=="], + "@types/unist": ["@types/unist@2.0.11", "", {}, "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA=="], + + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], + + "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + + "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], + + "argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], + + "astring": ["astring@1.9.0", "", { "bin": { "astring": "bin/astring" } }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="], + + "bail": ["bail@2.0.2", "", {}, "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw=="], + "caniuse-lite": ["caniuse-lite@1.0.30001739", "", {}, "sha512-y+j60d6ulelrNSwpPyrHdl+9mJnQzHBr08xm48Qno0nSk4h3Qojh+ziv2qE6rXf4k3tadF4o1J/1tAbVm1NtnA=="], + "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], + + "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="], + + "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="], + + "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=="], + "chownr": ["chownr@3.0.0", "", {}, "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g=="], "client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="], + "collapse-white-space": ["collapse-white-space@2.1.0", "", {}, "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw=="], + "color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="], "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], @@ -149,18 +206,90 @@ "color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="], + "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="], + + "cssesc": ["cssesc@3.0.0", "", { "bin": { "cssesc": "bin/cssesc" } }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="], + "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], + "cursor-effects": ["cursor-effects@1.0.17", "", {}, "sha512-IUMgMgc9Ii/BZnngHZmg/SpUvHaJAC+zqxmWIU4DnJY9RN5eb2xEGB9yL2jrdihMs+9xLgRuNNPYVaUrhASTNA=="], + + "debug": ["debug@4.4.1", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ=="], + + "decode-named-character-reference": ["decode-named-character-reference@1.2.0", "", { "dependencies": { "character-entities": "^2.0.0" } }, "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q=="], + + "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], + "detect-libc": ["detect-libc@2.0.4", "", {}, "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA=="], + "devlop": ["devlop@1.1.0", "", { "dependencies": { "dequal": "^2.0.0" } }, "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA=="], + "enhanced-resolve": ["enhanced-resolve@5.18.3", "", { "dependencies": { "graceful-fs": "^4.2.4", "tapable": "^2.2.0" } }, "sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww=="], + "esast-util-from-estree": ["esast-util-from-estree@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "unist-util-position-from-estree": "^2.0.0" } }, "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ=="], + + "esast-util-from-js": ["esast-util-from-js@2.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "acorn": "^8.0.0", "esast-util-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw=="], + + "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], + + "estree-util-attach-comments": ["estree-util-attach-comments@3.0.0", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw=="], + + "estree-util-build-jsx": ["estree-util-build-jsx@3.0.1", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "estree-walker": "^3.0.0" } }, "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ=="], + + "estree-util-is-identifier-name": ["estree-util-is-identifier-name@3.0.0", "", {}, "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg=="], + + "estree-util-scope": ["estree-util-scope@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0" } }, "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ=="], + + "estree-util-to-js": ["estree-util-to-js@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "astring": "^1.8.0", "source-map": "^0.7.0" } }, "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg=="], + + "estree-util-visit": ["estree-util-visit@2.0.0", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/unist": "^3.0.0" } }, "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww=="], + + "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="], + + "extend": ["extend@3.0.2", "", {}, "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="], + + "extend-shallow": ["extend-shallow@2.0.1", "", { "dependencies": { "is-extendable": "^0.1.0" } }, "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug=="], + "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], + "gray-matter": ["gray-matter@4.0.3", "", { "dependencies": { "js-yaml": "^3.13.1", "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" } }, "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q=="], + + "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-util-to-estree": ["hast-util-to-estree@3.1.3", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "comma-separated-tokens": "^2.0.0", "devlop": "^1.0.0", "estree-util-attach-comments": "^3.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", "zwitch": "^2.0.0" } }, "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w=="], + + "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-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-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="], + + "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="], + + "inline-style-parser": ["inline-style-parser@0.2.4", "", {}, "sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q=="], + + "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-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="], + "is-decimal": ["is-decimal@2.0.1", "", {}, "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A=="], + + "is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="], + + "is-hexadecimal": ["is-hexadecimal@2.0.1", "", {}, "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg=="], + + "is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], + "jiti": ["jiti@2.5.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w=="], + "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], + + "js-yaml": ["js-yaml@3.14.1", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g=="], + + "kind-of": ["kind-of@6.0.3", "", {}, "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="], + "lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="], "lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="], @@ -183,36 +312,170 @@ "lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.30.1", "", { "os": "win32", "cpu": "x64" }, "sha512-PVqXh48wh4T53F/1CCu8PIPCxLzWyCnn/9T5W1Jpmdy5h9Cwd+0YQS6/LwhHXSafuc61/xg9Lv5OrCby6a++jg=="], + "lodash.castarray": ["lodash.castarray@4.4.0", "", {}, "sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q=="], + + "lodash.isplainobject": ["lodash.isplainobject@4.0.6", "", {}, "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA=="], + + "lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="], + + "longest-streak": ["longest-streak@3.1.0", "", {}, "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g=="], + "magic-string": ["magic-string@0.30.18", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ=="], + "markdown-extensions": ["markdown-extensions@2.0.0", "", {}, "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q=="], + + "mdast-util-from-markdown": ["mdast-util-from-markdown@2.0.2", "", { "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-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA=="], + + "mdast-util-mdx": ["mdast-util-mdx@3.0.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-mdx-expression": "^2.0.0", "mdast-util-mdx-jsx": "^3.0.0", "mdast-util-mdxjs-esm": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w=="], + + "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.0", "", { "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-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA=="], + + "mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="], + + "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="], + + "micromark": ["micromark@4.0.2", "", { "dependencies": { "@types/debug": "^4.0.0", "debug": "^4.0.0", "decode-named-character-reference": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-normalize-identifier": "^2.0.0", "micromark-util-resolve-all": "^2.0.0", "micromark-util-sanitize-uri": "^2.0.0", "micromark-util-subtokenize": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA=="], + + "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-mdx-expression": ["micromark-extension-mdx-expression@3.0.1", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q=="], + + "micromark-extension-mdx-jsx": ["micromark-extension-mdx-jsx@3.0.2", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ=="], + + "micromark-extension-mdx-md": ["micromark-extension-mdx-md@2.0.0", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ=="], + + "micromark-extension-mdxjs": ["micromark-extension-mdxjs@3.0.0", "", { "dependencies": { "acorn": "^8.0.0", "acorn-jsx": "^5.0.0", "micromark-extension-mdx-expression": "^3.0.0", "micromark-extension-mdx-jsx": "^3.0.0", "micromark-extension-mdx-md": "^2.0.0", "micromark-extension-mdxjs-esm": "^3.0.0", "micromark-util-combine-extensions": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ=="], + + "micromark-extension-mdxjs-esm": ["micromark-extension-mdxjs-esm@3.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-core-commonmark": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-position-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A=="], + + "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=="], + + "micromark-factory-mdx-expression": ["micromark-factory-mdx-expression@2.0.3", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "unist-util-position-from-estree": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ=="], + + "micromark-factory-space": ["micromark-factory-space@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg=="], + + "micromark-factory-title": ["micromark-factory-title@2.0.1", "", { "dependencies": { "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-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw=="], + + "micromark-factory-whitespace": ["micromark-factory-whitespace@2.0.1", "", { "dependencies": { "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-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ=="], + + "micromark-util-character": ["micromark-util-character@2.1.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q=="], + + "micromark-util-chunked": ["micromark-util-chunked@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA=="], + + "micromark-util-classify-character": ["micromark-util-classify-character@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q=="], + + "micromark-util-combine-extensions": ["micromark-util-combine-extensions@2.0.1", "", { "dependencies": { "micromark-util-chunked": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg=="], + + "micromark-util-decode-numeric-character-reference": ["micromark-util-decode-numeric-character-reference@2.0.2", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw=="], + + "micromark-util-decode-string": ["micromark-util-decode-string@2.0.1", "", { "dependencies": { "decode-named-character-reference": "^1.0.0", "micromark-util-character": "^2.0.0", "micromark-util-decode-numeric-character-reference": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ=="], + + "micromark-util-encode": ["micromark-util-encode@2.0.1", "", {}, "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw=="], + + "micromark-util-events-to-acorn": ["micromark-util-events-to-acorn@2.0.3", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/unist": "^3.0.0", "devlop": "^1.0.0", "estree-util-visit": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg=="], + + "micromark-util-html-tag-name": ["micromark-util-html-tag-name@2.0.1", "", {}, "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA=="], + + "micromark-util-normalize-identifier": ["micromark-util-normalize-identifier@2.0.1", "", { "dependencies": { "micromark-util-symbol": "^2.0.0" } }, "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q=="], + + "micromark-util-resolve-all": ["micromark-util-resolve-all@2.0.1", "", { "dependencies": { "micromark-util-types": "^2.0.0" } }, "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg=="], + + "micromark-util-sanitize-uri": ["micromark-util-sanitize-uri@2.0.1", "", { "dependencies": { "micromark-util-character": "^2.0.0", "micromark-util-encode": "^2.0.0", "micromark-util-symbol": "^2.0.0" } }, "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ=="], + + "micromark-util-subtokenize": ["micromark-util-subtokenize@2.1.0", "", { "dependencies": { "devlop": "^1.0.0", "micromark-util-chunked": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0" } }, "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA=="], + + "micromark-util-symbol": ["micromark-util-symbol@2.0.1", "", {}, "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q=="], + + "micromark-util-types": ["micromark-util-types@2.0.2", "", {}, "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA=="], + "minipass": ["minipass@7.1.2", "", {}, "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="], "minizlib": ["minizlib@3.0.2", "", { "dependencies": { "minipass": "^7.1.2" } }, "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA=="], "mkdirp": ["mkdirp@3.0.1", "", { "bin": { "mkdirp": "dist/cjs/src/bin.js" } }, "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg=="], + "ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="], + "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], "next": ["next@15.5.2", "", { "dependencies": { "@next/env": "15.5.2", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.5.2", "@next/swc-darwin-x64": "15.5.2", "@next/swc-linux-arm64-gnu": "15.5.2", "@next/swc-linux-arm64-musl": "15.5.2", "@next/swc-linux-x64-gnu": "15.5.2", "@next/swc-linux-x64-musl": "15.5.2", "@next/swc-win32-arm64-msvc": "15.5.2", "@next/swc-win32-x64-msvc": "15.5.2", "sharp": "^0.34.3" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-H8Otr7abj1glFhbGnvUt3gz++0AF1+QoCXEBmd/6aKbfdFwrn0LpA836Ed5+00va/7HQSDD+mOoVhn3tNy3e/Q=="], + "next-mdx-remote": ["next-mdx-remote@5.0.0", "", { "dependencies": { "@babel/code-frame": "^7.23.5", "@mdx-js/mdx": "^3.0.1", "@mdx-js/react": "^3.0.1", "unist-util-remove": "^3.1.0", "vfile": "^6.0.1", "vfile-matter": "^5.0.0" }, "peerDependencies": { "react": ">=16" } }, "sha512-RNNbqRpK9/dcIFZs/esQhuLA8jANqlH694yqoDBK8hkVdJUndzzGmnPHa2nyi90N4Z9VmzuSWNRpr5ItT3M7xQ=="], + + "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=="], + "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], + "postcss-selector-parser": ["postcss-selector-parser@6.0.10", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w=="], + + "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], + "react": ["react@19.1.0", "", {}, "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg=="], "react-dom": ["react-dom@19.1.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g=="], + "reading-time": ["reading-time@1.5.0", "", {}, "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg=="], + + "recma-build-jsx": ["recma-build-jsx@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-build-jsx": "^3.0.0", "vfile": "^6.0.0" } }, "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew=="], + + "recma-jsx": ["recma-jsx@1.0.1", "", { "dependencies": { "acorn-jsx": "^5.0.0", "estree-util-to-js": "^2.0.0", "recma-parse": "^1.0.0", "recma-stringify": "^1.0.0", "unified": "^11.0.0" }, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w=="], + + "recma-parse": ["recma-parse@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "esast-util-from-js": "^2.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ=="], + + "recma-stringify": ["recma-stringify@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "estree-util-to-js": "^2.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g=="], + + "rehype-recma": ["rehype-recma@1.0.0", "", { "dependencies": { "@types/estree": "^1.0.0", "@types/hast": "^3.0.0", "hast-util-to-estree": "^3.0.0" } }, "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw=="], + + "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-mdx": ["remark-mdx@3.1.1", "", { "dependencies": { "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0" } }, "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg=="], + + "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=="], + "scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="], + "section-matter": ["section-matter@1.0.0", "", { "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" } }, "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA=="], + "semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], "sharp": ["sharp@0.34.3", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.4", "semver": "^7.7.2" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.3", "@img/sharp-darwin-x64": "0.34.3", "@img/sharp-libvips-darwin-arm64": "1.2.0", "@img/sharp-libvips-darwin-x64": "1.2.0", "@img/sharp-libvips-linux-arm": "1.2.0", "@img/sharp-libvips-linux-arm64": "1.2.0", "@img/sharp-libvips-linux-ppc64": "1.2.0", "@img/sharp-libvips-linux-s390x": "1.2.0", "@img/sharp-libvips-linux-x64": "1.2.0", "@img/sharp-libvips-linuxmusl-arm64": "1.2.0", "@img/sharp-libvips-linuxmusl-x64": "1.2.0", "@img/sharp-linux-arm": "0.34.3", "@img/sharp-linux-arm64": "0.34.3", "@img/sharp-linux-ppc64": "0.34.3", "@img/sharp-linux-s390x": "0.34.3", "@img/sharp-linux-x64": "0.34.3", "@img/sharp-linuxmusl-arm64": "0.34.3", "@img/sharp-linuxmusl-x64": "0.34.3", "@img/sharp-wasm32": "0.34.3", "@img/sharp-win32-arm64": "0.34.3", "@img/sharp-win32-ia32": "0.34.3", "@img/sharp-win32-x64": "0.34.3" } }, "sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg=="], "simple-swizzle": ["simple-swizzle@0.2.2", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg=="], + "source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], + "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], + "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="], + + "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], + + "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-bom-string": ["strip-bom-string@1.0.0", "", {}, "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g=="], + + "style-to-js": ["style-to-js@1.1.17", "", { "dependencies": { "style-to-object": "1.0.9" } }, "sha512-xQcBGDxJb6jjFCTzvQtfiPn6YvvP2O8U1MDIPNfJQlWMYfktPy+iGsHE7cssjs7y84d9fQaK4UF3RIJaAHSoYA=="], + + "style-to-object": ["style-to-object@1.0.9", "", { "dependencies": { "inline-style-parser": "0.2.4" } }, "sha512-G4qppLgKu/k6FwRpHiGiKPaPTFcG3g4wNVX/Qsfu+RqQM30E7Tyu/TEgxcL9PNLF5pdRLwQdE3YKKf+KF2Dzlw=="], + "styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="], "tailwindcss": ["tailwindcss@4.1.12", "", {}, "sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA=="], @@ -221,14 +484,46 @@ "tar": ["tar@7.4.3", "", { "dependencies": { "@isaacs/fs-minipass": "^4.0.0", "chownr": "^3.0.0", "minipass": "^7.1.2", "minizlib": "^3.0.1", "mkdirp": "^3.0.1", "yallist": "^5.0.0" } }, "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw=="], + "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="], + + "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="], + "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "typescript": ["typescript@5.9.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A=="], "undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="], + "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-is": ["unist-util-is@5.2.1", "", { "dependencies": { "@types/unist": "^2.0.0" } }, "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw=="], + + "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="], + + "unist-util-position-from-estree": ["unist-util-position-from-estree@2.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ=="], + + "unist-util-remove": ["unist-util-remove@3.1.1", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0", "unist-util-visit-parents": "^5.0.0" } }, "sha512-kfCqZK5YVY5yEa89tvpl7KnBBHu2c6CzMkqHUrlOqaRgGOMp0sMvwWOVrbAtj03KhovQB7i96Gda72v/EFE0vw=="], + + "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.0.0", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0", "unist-util-visit-parents": "^6.0.0" } }, "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg=="], + + "unist-util-visit-parents": ["unist-util-visit-parents@5.1.3", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0" } }, "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg=="], + + "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], + + "vfile": ["vfile@6.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "vfile-message": "^4.0.0" } }, "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q=="], + + "vfile-matter": ["vfile-matter@5.0.1", "", { "dependencies": { "vfile": "^6.0.0", "yaml": "^2.0.0" } }, "sha512-o6roP82AiX0XfkyTHyRCMXgHfltUNlXSEqCIS80f+mbAyiQBE2fxtDVMtseyytGx75sihiJFo/zR6r/4LTs2Cw=="], + + "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], + "yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="], + "yaml": ["yaml@2.8.1", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw=="], + + "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], + "@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.5.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg=="], "@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.5.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-97/BJ3iXHww3djw6hYIfErCZFee7qCtrneuLa20UXFCOTCfBM2cvQHjWJ2EG0s0MtdNwInarqCTz35i4wWXHsQ=="], @@ -241,6 +536,46 @@ "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], + "@types/hast/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "@types/mdast/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "estree-util-visit/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "hast-util-to-html/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "hast-util-to-jsx-runtime/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "mdast-util-from-markdown/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "mdast-util-mdx-jsx/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "mdast-util-phrasing/unist-util-is": ["unist-util-is@6.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw=="], + + "mdast-util-to-markdown/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "micromark-util-events-to-acorn/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + "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=="], + + "unified/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "unist-util-position/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "unist-util-position-from-estree/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "unist-util-stringify-position/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "unist-util-visit/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "unist-util-visit/unist-util-is": ["unist-util-is@6.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw=="], + + "unist-util-visit/unist-util-visit-parents": ["unist-util-visit-parents@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw=="], + + "vfile/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "vfile-message/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], + + "mdast-util-phrasing/unist-util-is/@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="], } } diff --git a/components/cursor-effect.tsx b/components/cursor-effect.tsx new file mode 100644 index 0000000..75b59f7 --- /dev/null +++ b/components/cursor-effect.tsx @@ -0,0 +1,25 @@ +"use client"; + +import { useEffect } from "react"; + +export default function CursorEffect() { + useEffect(() => { + let cursor: any; + let isMounted = true; + + import("cursor-effects").then((mod) => { + if (isMounted && mod?.trailingCursor) { + const TrailingCursor = mod.trailingCursor as any; + cursor = new TrailingCursor(); + } + }); + return () => { + isMounted = false; + if (cursor && typeof cursor.destroy === "function") { + cursor.destroy(); + } + }; + }, []); + + return null; +} diff --git a/components/switching-background.tsx b/components/switching-background.tsx new file mode 100644 index 0000000..1ac83da --- /dev/null +++ b/components/switching-background.tsx @@ -0,0 +1,51 @@ +"use client"; // This must be a client component to use React hooks + +import React, { useState, useEffect } from "react"; +import Image from "next/image"; + +// --- Configuration --- +// Add the paths to your 5 background images here. +// Make sure they are in the `public/backgrounds` directory. +const images = [ + "/backgrounds/1.avif", + "/backgrounds/2.avif", + "/backgrounds/3.avif", + "/backgrounds/4.avif", + "/backgrounds/5.avif", +]; + +const SWITCH_INTERVAL = 60000; // 60 seconds + +export default function SwitchingBackground() { + const [currentImageIndex, setCurrentImageIndex] = useState(0); + + useEffect(() => { + // Set up an interval to switch the image + const timer = setInterval(() => { + setCurrentImageIndex((prevIndex) => (prevIndex + 1) % images.length); + }, SWITCH_INTERVAL); + + // Clear the interval when the component unmounts to prevent memory leaks + return () => clearInterval(timer); + }, []); + + return ( +
+ {images.map((src, index) => ( + {`Background + ))} + {/* Adds a subtle glossy overlay effect */} +
+
+ ); +} diff --git a/components/window.tsx b/components/window.tsx new file mode 100644 index 0000000..db05758 --- /dev/null +++ b/components/window.tsx @@ -0,0 +1,76 @@ +import React from "react"; + +const CloseIcon = () => ( + + + +); +const MaximizeIcon = () => ( + + + +); +const MinimizeIcon = () => ( + + + +); + +interface WindowProps { + title: string; + children: React.ReactNode; + className?: string; +} + +export default function Window({ + title, + children, + className = "", +}: WindowProps) { + return ( +
+ {/* Title Bar with gradient and controls */} +
+ {title} +
+
+ +
+
+ +
+
+ +
+
+
+ {/* Content Area */} +
{children}
+
+ ); +} diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..21c97a8 --- /dev/null +++ b/compose.yml @@ -0,0 +1,15 @@ +services: + blog: + build: . + container_name: blog + restart: unless-stopped + labels: + - "traefik.enable=true" + - "traefik.http.routers.blog.rule=Host(`blog.gabrielkaszewski.dev`)" + - "traefik.http.routers.blog.entrypoints=websecure" + - "traefik.http.routers.blog.tls.certresolver=letsencrypt" + networks: + - traefik +networks: + traefik: + external: true diff --git a/lib/posts.ts b/lib/posts.ts new file mode 100644 index 0000000..02b44de --- /dev/null +++ b/lib/posts.ts @@ -0,0 +1,80 @@ +import fs from 'fs'; +import path from 'path'; +import matter from 'gray-matter'; +import readingTime from 'reading-time'; + +const postsDirectory = path.join(process.cwd(), 'posts'); + +export interface PostData { + id: string; + date: string; + title: string; + description: string; + content: string; + readingTime: string; +} + +export interface PostMeta { + id: string; + date: string; + title: string; + description: string; + readingTime: string; +} + +export function getSortedPostsData(): PostMeta[] { + try { + const fileNames = fs.readdirSync(postsDirectory); + const allPostsData = fileNames + .filter(fileName => fileName.endsWith('.mdx')) + .map(fileName => { + const id = fileName.replace(/\.mdx$/, ''); + const fullPath = path.join(postsDirectory, fileName); + const fileContents = fs.readFileSync(fullPath, 'utf8'); + const matterResult = matter(fileContents); + const stats = readingTime(matterResult.content); + + return { + id, + date: matterResult.data.date as string, + title: matterResult.data.title as string, + description: matterResult.data.description as string, + readingTime: stats.text, + }; + }); + + return allPostsData.sort((a, b) => (a.date < b.date ? 1 : -1)); + } catch (error) { + console.log("No 'posts' directory found, returning empty array."); + return []; + } +} + +export function getAllPostIds() { + try { + const fileNames = fs.readdirSync(postsDirectory); + return fileNames.map(fileName => ({ + params: { + slug: fileName.replace(/\.mdx$/, ''), + }, + })); + } catch (error) { + return []; + } +} + +export async function getPostData(id: string): Promise { + const fullPath = path.join(postsDirectory, `${id}.mdx`); + const fileContents = fs.readFileSync(fullPath, 'utf8'); + const matterResult = matter(fileContents); + const stats = readingTime(matterResult.content); + + return { + id, + content: matterResult.content, + date: matterResult.data.date, + title: matterResult.data.title, + description: matterResult.data.description, + readingTime: stats.text, + }; +} \ No newline at end of file diff --git a/next.config.ts b/next.config.ts index e9ffa30..26d96bb 100644 --- a/next.config.ts +++ b/next.config.ts @@ -2,6 +2,8 @@ import type { NextConfig } from "next"; const nextConfig: NextConfig = { /* config options here */ + reactStrictMode: true, + transpilePackages: ['next-mdx-remote'] }; export default nextConfig; diff --git a/package.json b/package.json index 4f6d452..fac3884 100644 --- a/package.json +++ b/package.json @@ -8,9 +8,16 @@ "start": "next start" }, "dependencies": { + "@tailwindcss/typography": "^0.5.16", + "cursor-effects": "^1.0.17", + "gray-matter": "^4.0.3", + "next": "15.5.2", + "next-mdx-remote": "^5.0.0", "react": "19.1.0", "react-dom": "19.1.0", - "next": "15.5.2" + "reading-time": "^1.5.0", + "remark": "^15.0.1", + "remark-html": "^16.0.1" }, "devDependencies": { "typescript": "^5", diff --git a/posts/jak-stres-wplywa-na-czlowieka.mdx b/posts/jak-stres-wplywa-na-czlowieka.mdx new file mode 100644 index 0000000..ed3b654 --- /dev/null +++ b/posts/jak-stres-wplywa-na-czlowieka.mdx @@ -0,0 +1,121 @@ +--- +title: "Jak stres wpływa na człowieka?" +description: "" +date: "2022-02-02" +--- + +Na samym początku, aby określić jak stres wpływa na nasze życie, to musimy dowiedzieć się czym tak, w ogóle jest stres. + +Stres – z angielskiego to słowo znaczy napięcie bądź naprężenie np. takie jakie jest na linie, która jest +zaczepiona między dwoma punktami i siła na nią działa. W naszym kontekście chodzi nam o napięcie +psychiczne czyli psychologiczny stan obciążenia systemu regulacji psychicznej powstałej w wyniku +zaistnienia sytuacji zagrożenia. Jest to dynamiczna relacja adaptacyjna pomiędzy możliwościami +osoby, a wymogami sytuacji, w której nie ma równowagi psychicznej oraz fizycznej. Inaczej mówiąc +stres jest zaburzeniem homestazy spowodowanym czynnikiem fizycznym bądź psychologicznym. + +Pojęcie stresu nie ma zdefiniowanej jednej definciji naukowej, wyróżniamy więc 3 typy definicji +stresu. + +1. Stres jako bodziec – nasze środowisko oraz sytuacje z nim związane mają naturalną zdolność + do wywoływania napięcia i silnych emocji. +2. Stres jako reakcja – reakcja fizjologiczna jak i psychologiczna będąca odpowiedzią na + działanie sytuacji wywołujących stres. +3. Stres jako proces bądź transakcja – relacja między osobą, a otoczeniem, transakcyjny model + Lazarusa + +Skoro wiemy już, że stres powoduje napięcie to teraz wypadałoby poznać jakie reakcje nasz +organizm powoduje na stres. Wyróżniamy trzy typy reakcji: + +1. Dystres – jest to reakcja organizmu na zagrożenie bądź utrudnienie realizacji ważnych celów, + pojawia się w momencie zadziałania bodźca (stresora) +2. Eustres – jest to stres poztywnie motywujący do działania. +3. Neustres – bodziec specyficzny dla danej osoby jest on neutralny, gdy dla innych może być + eustresowy bądź dystresowy. + +Czy stres to jest tylko zjawisko szkodliwe? Niewątpliwe wśród ludzi w powszechnym odbiorze stres +uznawany jest jako zjawisko szkoldiwe, aczkolwiek nie do końca jest to prawda. W rzeczywistości +stres może być zjawiskiem pozytwnym to wszystko zależy od długotrwałości stresu oraz jego sile. +Umiarkowany oraz krótkotrwały stres pozwala nam na lepszą adaptację do otaczjącego nas +środowiska oraz zwiększa nasze możliwości radzenia sobie z nowymi wymaganiami, dzięki czemu +umożliwia nam to rozwój psychiczny. Natomiast stres długotrwały przyczynia sie do rozwoju +zaburzeń psychicznych jak na przykład zaburzenia lękowe oraz deperesyjne. Taki traumatyczny silny +stres może również spowodować PTSD (często go doświadczają weterani wojenni, albo ofiary silnej +przemocy) w ekstremalnych przypadkach może również spowodować zaburzenia osobowości. + +Był sobie taki pan Hans Selye i owy pan stworzył fazy w jakich według niego stres przebiega. + +- Faza alarmowa – początkowa alarmowa reakcja zaskoczenia i niepokoju z powodu + niedoświadczenia i konfrontacji z nową sytuacją. Wyróżniamy w niej dwie subfazy: + +1. Stadium szoku +2. Stadium przeciwdziałania szokowi. Człowiek w tej fazie podejmuje wysiłki obronne. + +- Faza przystosowania inaczej zwana faza odporności - ogranizm uczy się skutecznie i bez + nadmiernych zaburzeń radzić sobie ze stresem. Jeśli się to mu uda to wszystko wraca do normy. Jak + się organizmowi nie uda poradzić ze sytuacją to następuje faza trzecia. +- Faza wyczerpania – stałe pobudzenie całego organizmu, przewlekły stres prowadzi do wyczerpania + zasobów odpornościowych i osłabienia układu odpornościowego, co może prowadzić do chorób + psychosomatycznych. W ekstremalnych przypadkach prowadzi nawet do śmierci. + +Jak środowisko wpływa na nasze reakcje na stres? + +U osób mieszkających w miastach zaobserwowano, że takie osoby wykazują większą aktywność ciała +migdałowatego podczas sytuacji stresowej niż osoby, które mieszkają na wsi. U osób, które dorastały +w dużym mieście zaobserwowano większą aktywność przedniej części zakrętu obręczy. Obserwacje +te prowadzono na osobach rozwiązujących zadania arytmetczne pod presją. Do obserwacji wyników +wykorzystano funkcjonalnego magnetycznego rezonansu jądrowego. + +Jedną z reakcji organizmu na stres może być przybieranie na wadze. + +U osób, które spotkały się z homofobią ze strony otoczenia, może pojawić się stres miejszościwoy tj. +stres, na który są narażone osoby należące do stygmatyzowanych grup mniejszościowych, +dyskryminowanych np. ze względu na orientację, kolor skóry, pochodzenie, wyznanie. Taki stres +może prowadzić do samookaleczania, obniżenia samooceny, stanów lękowych i depresyjnych, +zaburzeń zachowania, jedzenia oraz nawet snu, trudności w nauce, unikanie kontaktów społecznych +bądź wycofanie się z życia społecznego, a nawet do prób samobójczych. + +Skoro już wiemy jakie stres może powodować dla nas reakcje to poznajmy metody obniżania stresu, +aby wydłużyć nasze życie. + +W miarę możliwości najlepiej by było zoptymalizować swoje środowisko, w którym się żyje, jeśli +mieszka się w dużym mieście, gdzie jest hałas, spory ruch i inne typowe rzeczy dla miasta to +wypadałoby się przeprowadzić gdzieś gdzie takich warunków nie ma, na przykład na spokojną wieś +albo do lasu. Natomiast wiadomo, że taki scenariusz jest mało prawdopodobny z wielu powodów +chociażby finansowych. Nie oznacza to, że nie jesteśmy w stanie nic zrobić, by obniżyć nasz poziom +stresu. Wszelaką aktywność fizyczną możemy wykonywać wszędzie, niezależnie gdzie mieszkamy. +Uprawiając sport nie tylko obniżymy nasz stres, ale także poprawimy inne parametry naszego +zdrowia jak chociażby natlenienie albo poziom krwi. Powinniśmy zadbać o regularny zdrowy sen, +gdyż zaniedbanie higeny snu prowadzi również do podwyższonego stresu. Rozmawianie na temat +naszych uczuć bądź obaw z osobami również może obniżyć nasz poziom stresu. Prowadzenie +dziennika również może być sposobem na obniżenie stresu. Ważnym aspektem jest również +odpowiednie nawodnienie, braki wody nie tylko wpływają źle na nasz poziom stresu, ale również +mają negatywny wpływ na nerki i nasze samopoczucie. Ograniczyć spożycie alkoholu, kawy, energy +drinków oraz KONIECZNIE wszelakich papierosów. Również polecałbym godzinę przed snem +odstawienie jakichkolwiek urządzeń elektronicznych jak np. telefonu, ponieważ niebieskie światło +jakie emitują nowoczesne ekrany niekorzystnie wpływa na nasz sen. + +Poza tymi wszystkimi sposobami możemy dodatkowo wprowadzić do naszej diety adaptogeny, które +będą aktywnie pomagały nam w radzeniu sobie ze stresem. Przykładowe rośliny, które pomagają +organizmowi w adaptacji to: + +- Panax ginseng +- Schizandra chinensis +- Rhodiola rosea +- Withania somnifera + +Wnioski + +Stres ma ogromny wpływ na nasze życie, jeśli będzie on długotrwały i silny to definitywnie może nam +je skrócić. Natomiast nie każdy stres jest negatywny, stres krótkotrwały jest bardzo potrzebny do +rozwoju oraz do znajdowania motywacji. Niemniej powinniśmy się starać, aby nasz poziom stresu był +relatywnie niski. Powinniśmy wybrać bądź stworzyć dla siebie takie środowisko, w którym będziemy +czuli się komfortowo oraz bezpiecznie. Natomiast, gdy są pewne zewnętrzne czynniki, na które nie +mamy wpływu to powinniśmy skorzystać ze wszystkich sposobów na obniżenie stresu. + +Gabriel Kaszewski – student I roku Bioinformatyki + +Źródła: + +https://pl.wikipedia.org/wiki/Adaptogen + +https://pl.wikipedia.org/wiki/Stres diff --git a/posts/my-2023-coding-edition.mdx b/posts/my-2023-coding-edition.mdx new file mode 100644 index 0000000..7c4e438 --- /dev/null +++ b/posts/my-2023-coding-edition.mdx @@ -0,0 +1,41 @@ +--- +title: "My 2023 Coding Edition" +description: "" +date: "2023-12-28" +--- + +## Introduction + +Hi! Back in February I wrote a post about my 2023 goals. The roadmap for 2023 [can be found here](https://blog.gabrielkaszewski.dev/posts/roadmap-for-2023/). + +## Rust venture + +In that post I had mentioned that I would like to do some Rust programming, especially to make some 2D games in it and to create apps in Tauri. Well, I did code in Rust this year, but I didn't do any of the things I had mentioned. Not in a sense that I would be satisfied with. + +I managed to make a simple 2d space shooting game in Bevy 😁 which was a recreation of the same game I made in C. [repo for rust game](https://github.com/GKaszewski/asteroids-rs), [repo for C game](https://github.com/GKaszewski/asteroids). + +I wrote a screensaver which was a Conway's game of life. Pretty cool project, I used Raylib for drawing stuff. [repo for screensaver](https://github.com/GKaszewski/screensaver/). + +I also wrote a tetris game, also using Raylib ( I fell in love with that library. It is amazing.) [repo for tetris](https://github.com/GKaszewski/tetris-rs/). + +I tried to write a chip-8 emulator but I can't say that, that project was successful. I mean it kinda works on some ROMs but not for every ROM. So there is a room for improvement. [repo](https://github.com/GKaszewski/chip8) + +I have also wrote some other small stuff like qr-generator web app using axum, a simple CLI tool for converting jpgs and pngs to webp, av1-encoder microservice, and tech tree system for maybe future RTS game. All of those projects are available on my [github](https://github.com/GKaszewski). + +## Machine Learning venture + +I have not done anything with machine learning, maybe next year 😉. Okay that is not entirely true. I have done some stuff with machine learning but it was during my college machine learning course. + +## Game development venture + +I have not managed to finish my Sammy Suricate clone. I have not done anything with VR. I have experimented with Godot, melon.js and C. + +I think that in the future (2024) I am going to focus on Godot. I find that engine really nice to work with. + +I wrote some small games (tic-tac-toe, snake, asteroids) in C this year. It was fun. I really like C, but build system is a pain on Windows so I am planning to switch to zig or rust. + +Also for my bachleor thesis I am making my own game engine in C++ with SFML and EnTT for ECS. Maybe I will write a post about it in the future and make some games in it 😁. + +## Conclusion + +Overall I am satisfied with 2023. I started to learn Rust and Godot. I have done some cool projects. Let's see what 2024 will bring 😁. diff --git a/posts/my-2024-and-2025-roadmap.mdx b/posts/my-2024-and-2025-roadmap.mdx new file mode 100644 index 0000000..7283e6f --- /dev/null +++ b/posts/my-2024-and-2025-roadmap.mdx @@ -0,0 +1,96 @@ +--- +title: "My 2024 and 2025 roadmap" +description: "" +date: "2025-02-06" +--- + +# Introduction + +Hi! I am writing this post on **January 4th, 2025**, which means I was too lazy to write it before the year ended—but no matter, let's get to it now. + +# 2024 - A Year of Rust + +Last year was pretty good for me—I think it was the most productive I've ever been. Naturally, I started tons of projects, most of which I still haven't finished ;) but I did manage to make some of them work. + +In January, I began moving away from React for my portfolio [website](https://gabrielkaszewski.dev/) for one simple reason: I don't think static websites like mine need a UI JavaScript library. When I first created the website, I was learning web development and wanted to showcase my skills to get a job, and React seemed like a good opportunity to do that. + +My website consisted of two 'modules': + +1. REST API + Admin dashboard - written in Django +2. Next.js frontend - used for meta tags and better SEO + +I really didn't like that approach. It made more sense to just use Django and render static HTML... so that's what I did! + +But that wasn't all I did in the first month of 2024. I had this crazy idea to create a simple video editor (you know, one that would allow users to put multiple clips on a timeline, cut fragments, and adjust the audio for each clip) using _FFmpeg_ and Rust. I didn’t finish it—not even close—but if my memory isn't playing tricks on me, I think I did manage to make a CLI version that combined multiple clips together. + +Next, I wrote a **Minesweeper** game in C++ using Raylib. That was pretty fun! The code, however, isn't really good—it's not idiomatic C++, more like C with classes—but the point of the project was just to have fun. That’s why I’m not going to link the repo. However, if someone is interested, they can easily find it on my GitHub. + +## February - Small but Fun Projects + +February, the shortest month of the year! I hopped from project to project, but some were actually finished and published. + +First, a very small one—**Flappy Bird in the console**. Yes, I recreated Flappy Bird using Rust and the _console_engine_ crate. That was a pleasant experience, and in the future, I’d love to create more interactive console-based applications. + +Next, I wrote **two Discord bots**, also in Rust. One was a simple reminder bot where you type `!remindme "a thing" WHEN` (for example, `30m` for 30 minutes). The other was a **vxtiktok bot**, which converted TikTok URLs to vxtiktok URLs so they would embed properly in Discord. Very simple, quick projects! To my surprise, using Rust wasn't a pain at all. + +You might ask, _Why use Rust for that instead of JavaScript?_ Great question! The answer is simple—my VPS only has **2 GiB of RAM**, which isn't much. My tech stack for web services was mostly Python-based (Python uses a lot of memory, just like Node.js). Rust, on the other hand, uses much less memory, and that was a major reason for choosing it. Plus, Rust is actually pretty nice to write in—it's very ergonomic. I love it. + +Next, I started working on a **Missile Commander clone**—a recreation of the old Atari game **Missile Command**. I actually managed to replicate the core gameplay, but since I’m terrible at designing games and coming up with new mechanics, levels, and features, I abandoned it pretty quickly. I even wrote a **level editor** for it! The game and editor were both written in Rust using **macroquad**, as I wanted to export it to the web. Unfortunately, I ran into some errors when trying to export and gave up. + +## March - A Sokoban Game in Java + +In March, I only worked on one toy project—a **Sokoban game in Java** using Raylib. Why Java? No idea. I guess I just wanted to refresh my skills in the language. + +## April - The RTS Struggle + +In April, I really wanted to create an **RTS game**. Unfortunately, I didn’t succeed. Nevertheless, I made an attempt at creating an **RTS engine in Rust** using the _comfy_ crate. Later, I tried moving to Bevy, but pathfinding defeated me. I haven't given up on the idea completely, though—I may go back to it in the future, because I love RTS and strategy games so much. + +While researching RTS mechanics, I wrote my own **quadtree** in Rust and visualized it using Raylib. That was pretty fun and easy. + +I also got into **ray tracing** and, thanks to _Ray Tracing in One Weekend_, I wrote my own **software ray tracer** in Rust. + +Another Rust project from April was an **Otodom scraper** with a frontend in React. Otodom is a website listing real estate for sale or rent, and since I was house-hunting, I needed a better way to filter available listings. So I wrote a simple service using _Axum_ that scrapes the data every ten minutes, allowing me to easily filter through listings. + +Last but not least, I created **better_notepad**, a Notepad-like app because I was annoyed that the default Windows Notepad didn’t close tabs when the app was closed. I wrote mine in C++ with wxWidgets. Later, I learned that you can actually turn that behavior off in the Notepad settings... oops. + +## May - A Nostalgic Social Network + +In May, I started a **2D platformer in Unity**, inspired by **Brave Dwarves 2** (a childhood favorite). I focused on **composition over inheritance**, and I loved that approach—so much that I still use it in all future projects. Unfortunately, I abandoned the game. + +I also built a **tiny social network** inspired by the late 2000s and early 2010s, when social media was more about you and your friends rather than memes, ads, and algorithm-driven feeds. My idea was simple: users could publish short thoughts (up to 128 characters), follow friends, and see only their friends' posts in the feed. I used Django, but I plan to rewrite it in Rust for lower memory usage. I might even make it **decentralized using ActivityPub**, because I recently fell in love with that concept. + +I also built my own **r/place clone** in Rust, using WebSockets via _socket.io_ and plain JavaScript for the client. It worked pretty well! However, I ran into an issue where I was sending data inefficiently, which caused massive memory usage—something like **~100MB per user connection**. I don’t remember if I ever fixed it, but debugging network-related stuff is still a bit of a mystery to me. + +## June - A Grand Strategy Game Attempt + +In June, I made another attempt at an **RTS/Strategy game**, this time a **turn-based grand strategy game** similar to _Civilization_. I used **Bevy** and the **hexx crate**, but as you can imagine, I didn’t get very far—I got stuck on the turn system :p + +Next, I set out to create a **news desktop app** that would aggregate **RSS news feeds** from various sources, including _The Guardian_ and _BBC_, while allowing users to add their own custom feeds. My goal was to integrate it with **local LLMs** or **OpenAI services** via an API key to generate concise article summaries. For the backend, I naturally chose **Rust**, while the frontend was built using **React** with **Tauri** handling the desktop functionality. Unfortunately, I didn’t manage to complete the project :( but I still hope to revisit it someday. + +## August - Boomer shooter endeavor + +In **August**, I experimented with **Godot** and started developing a **boomer shooter**! + +This was yet another project I left unfinished. While I enjoy working with **Godot**, I found its 3D tools a bit too clunky for my workflow. + +## September - My Own Podcast Platform + +In September, I built my own **podcast platform**! I wrote the backend in **Loco.rs** and the frontend in **Svelte**. I was really happy with how it turned out, but after recording just **one episode**, I lost interest. Shame. + +In the meantime, I created a **mod for VTOL VR**, which currently has **623 subscribers**! One day, I would love to create my own **VR game**, but for now, I have **zero ideas** for what it could be :< + +## December - Back to Game Development + +In December, I tried **Advent of Code**, but I gave up after **three days** :p. Instead, I started working again on my **2D platformer game, Mr. Brick Adventures**. This time, I _vow_ to finish it and release it on **Steam**! I’m using **Godot** again, and I have to admit—it’s quite nice for 2D development. I wanted to use Rust, but it was a bit too tedious, so I stuck with GDScript. + +--- + +# 2025 Roadmap + +For **2025**, my main goal is to release my first game, **Mr. Brick Adventures**. + +I also started my first **embedded project**—a simple **LED screen** that displays various data (my stock portfolio, weather, Spotify track info, etc.). So far, I have my **custom protocol** ready and a **server that sends data to the ESP32**. Now, I just need to write the ESP32 firmware. + +As I mentioned before, I want to return to my **social network project**—but this time, I’ll make it **decentralized with ActivityPub**. And of course, I _have_ to return to my **RTS/Strategy game dream**. Will I succeed? Probably not. But we'll see. + +For now, that’s it. See you in the next post! diff --git a/posts/python-introduction.mdx b/posts/python-introduction.mdx new file mode 100644 index 0000000..4f47c83 --- /dev/null +++ b/posts/python-introduction.mdx @@ -0,0 +1,41 @@ +--- +title: "Python Tutorial - Introduction" +description: "Introduction to Python programming language" +date: "2021-04-25" +--- + +# Your first program! + +Hello, today I'll teach you how to code! Seems interesting, doesn't it? Okay, let's start. + +## Set up + +Firstly you'll need to install Python. You can do so by clicking [this link](https://www.python.org/) which will redirect you to the Python official website. +Having installed this, you can download and install any code editor you'd like. +I prefer [Visual Studio Code](https://code.visualstudio.com/) , so I'll go with it. Now, we can finally start writing our first program! + +## Writing code + +Create a new file and name it `hello.py` and open it with your editor of choice. Now write this piece of code. + +```python +print('Hello world') +``` + +## Running code + +To run code, simply type in Terminal/Console `python hello.py` + +## Explanation + +Okay, so what does this code exactly do? Well, it prints text into the console or some other output device. In our case, the text is _Hello world_ . But why is the text in double-quotes? It is this way because otherwise, Python wouldn't know what does it mean. Is it a text or a variable1 or something else. What would happen if we changed the text into something different, let's say _Hello, Darrien!_ I'll give you a moment to think about it. +... +Well, yes you've guessed it. It would print out `Hello, Darien!` to the console. + +## Homework + +Write a program that will greet your family members. + +--- + +1 - Don't worry if you didn't understand what I meant, I'll explain it, in the next tutorial. diff --git a/posts/python-variables.mdx b/posts/python-variables.mdx new file mode 100644 index 0000000..3d2c32d --- /dev/null +++ b/posts/python-variables.mdx @@ -0,0 +1,102 @@ +--- +title: "Python - Variables" +description: "" +date: "2021-04-25" +--- + +# Variables + +## Set up + +As I mentioned in the previous tutorial, we have to put our text that we want to print out in double-quotes otherwise, Python won't know what we mean. +In any programming language, there is something called a variable. A variable is something that holds some data. + +## Writing code + +For example, let's define a variable that will store a number of our fingers. + +```python +fingers = 20 +``` + +Now we have defined a new variable which we've called fingers and it stores number 20. +So in other words this is a variable of Integer type because it stores a number. +There are a lot of different types that a variable can store. + +| Type | Data | +| ------- | --------------------------------------------------------------------------------------------------------------------------- | +| int | Integer numbers e.g 1, 2, 3, 10, 200 | +| float | Real numbers e.g 1.5, 0.49, 3.14 | +| complex | Complex numbers | +| str | Text type e.g 'Hello', "Gabriel", "I love programming" | +| bool | Boolean type (in other words) True or False e.g True, False | +| dict | Dictionary type, can store key and its value e.g `fruits_price = {'Orange': 100, 'Apple' : 50}` | +| list | With this type we can store multiple elements of the same type e.g names=['Anna', 'Sofie', 'Mike', 'Kate', 'Pedro', 'Juan'] | + +We can also modify the values of variables. For example, +let's write a program that will ask the user how are they. + +Create a file and rename it to _greetings.py_ + +```python +answer = '' +print('Hello, how are you?) +answer = input() +print('Good to hear that you are' + answer) +``` + +As you can see, we can assign value to a variable whenever we want. +Also, we can concatenate two texts with each other. +If we had two numbers, we could easily add, subtract, divide, and multiply them. + +Let's write a simple calculator then. Actually it is going to be an adder because of simplicity. + +Create a file and rename it to _adder.py_ + +```python +firstNumber, secondNumber, output = 0,0,0 +print('Welcome to Adder!\nYour first number:') +firstNumber = input() +print('Second number:') +secondNumber = input() +output = firstNumber + secondNumber +print('The answer is: ', output) +``` + +## Running code + +To run the first snippet run `python greetings.py`, for the second run `python adder.py` + +## Explanation + +It is time for an explanation. First of all, what does **input()** do? +The answer is that the **input()** command reads what user types or sends into the standard input device. +Because of it we can read and interpret data from outside. + +What is **string concatenation**? +Concatenation is basically adding things with each other and **string concatenation** is adding multiple strings into one. + +Why we can add something like that `print('Good to hear that you are' + answer)` but this `print('The answer is: ', output)` we do in a different way? +This is a great question! +As I said before python has types and it uses them to recognize what is what. +Okay, firstly I encourage you to try and experiment with those snippets and see the outcome yourself. +But if you are not interested in that, I'll tell you what would happen. + +If we changed this line `print('Good to hear that you are' + answer)` into `print('Good to hear that you are', answer)`, +nothing would change. But if we changed `print('The answer is: ', output)` into `print('The answer is: ' + output)`, +the program would display something completely different. +For example if the first number was 11 and the second was 20 then +the displayed message would display **The answer is: 1120**. Interesting, huh? +But why is that? + +As you can see **1120** is the same as **'11'**+**'20'** and not **11** + **20**. +Because we add to the string **'The answer is: '** a number, +what python actually does is that it converts **output** into a string and concatenate it. +But when we pass **output** after the comma, Python doesn't convert it into a string, +it just passes the data and **print()** displays that. +In the first scenario `print('Good to hear that you are', answer)` nothing changes +because **answer** is also a string so concatenation works the way we expect it. + +## Homework + +No homework for today 😊 diff --git a/posts/roadmap-for-2023.mdx b/posts/roadmap-for-2023.mdx new file mode 100644 index 0000000..0cd05b6 --- /dev/null +++ b/posts/roadmap-for-2023.mdx @@ -0,0 +1,33 @@ +--- +title: "ROADMAP for 2023" +description: "" +date: "2023-02-28" +--- + +## My roadmap for 2023 + +### 🧑‍💻 programming edition ✨ + +### Preface + +I've been thinking about writing this post since January. I sat down to write it several times at a time, but somehow I wasn't able to write it. Today, however, something nudged me and I took the plunge. + +### 🖱️ Technologies ⚙️ + +Okay then, let's start with the technologies I would like to learn or play with. +At the very beginning it will be Rust. I've been thinking about **Rust** for quite some time, but somehow I've never moved it before more than out of curiosity some article/video I read or watched related to it. In January/February I started doing more 'practical' things in Rust, I write that in quotes because it's still not anything useful, but it was so-called testing the waters. I did naturally hello-world and some simple calculator in the console and an attempt to create an endless runner using [Bevy engine](https://bevyengine.org/). Unfortunately, the runner was abandoned due to college sessions and a flurry of tasks at work. +Nevertheless, Rust got me interested and I feel like writing some simple 2D games in it especially since it has options to export to WebAssembly which suits me because I plan to target mainly the web for my projects. [Tauri](https://tauri.app/) also uses Rust, for those who don't know Tauri is a replacement for [Electron](https://www.electronjs.org/), it allows cross-platform application development. I have two ideas for applications just in Tauri, but about them later. + +The second technology is **Machine Learning**. Machine learning has become more and more popular lately; the famous [Chat GPT](https://chat.openai.com/), or [stable-diffusion](https://stablediffusionweb.com/), [MidJourney](https://www.midjourney.com/) and many other machine learning projects. Machine learning has interested me a lot since middle school, but somehow I can't grasp it. I understand the theory and how neural networks work, but I can't create a model that recognizes how many fingers we show, for example. I'd like to grasp this eventually and create one project I've been considering for about a year. It's a project that involves automatic audio de-noising, I know [OBS](https://obsproject.com/) has such filters, although I'd like to make my own software for this, yes for educational purposes. My next project is to automatically create .srt files based on song lyrics and audio. In January I created a [mod](https://github.com/GKaszewski/BeatLyrics) for [BeatSaber](https://beatsaber.com/) that adds song lyrics, unfortunately, the mod requires an srt file with the given time and lyrics. I would like to automate the process of creating these files, just using artificial intelligence to do it. + +![ai-generated-image](https://gabrielkaszewski.dev/media/K00zak_pixar-style_puppy_chasing_its_tail_with_transparent_back_9e3efbe7-0427-42db-b71a-902ddf60f40c.png)_A dog generated by MidJourney AI_ + +The last thing is **game dev** in a broad sense. Creating games in **_Typescript_**, making some games in VR in [Unity](https://unity.com/), finishing a clone of **_Sammy Suricate_**, and super if I could make some simple strategy game. I love RTS games. + +![sammy-clone](https://gabrielkaszewski.dev/media/screenshot-2022-12-28T19-05-22-0041341Z.png)_My Sammy Suricate clone. Made in Unity_ + +### Conclusion (none) + +That's pretty much it at the moment, it's pretty late and I think I'll keep updating this post as something else pops into this crazy head of mine. For now, this is my farewell to you and I wish you a good day. + +![cat](https://gabrielkaszewski.dev/media/cat.jpg)_Aaaaaand this is my cat. Piernik ✨_ diff --git a/posts/rust-little-adventure.mdx b/posts/rust-little-adventure.mdx new file mode 100644 index 0000000..b726d1f --- /dev/null +++ b/posts/rust-little-adventure.mdx @@ -0,0 +1,43 @@ +--- +title: "My Rust little adventure" +description: "" +date: "2023-07-21" +--- + +In the previous post I have written that I would have wanted to get into Rust. In July, I finally started writing in Rust 😉. It has been a quite pleasant adventure, I am not going to lie. I have written several projects in it. + +## Mandelbrot set + +Okay, so the first 'project' that I did in Rust was a simple program that creates Mandelbrot's set image. The code for that was provided by the book _Programming Rust: Fast, Safe Systems Development 2nd Edition_ +I did it because it seemed cool and in High School I made similar program but in Java. +This one was more interesting because it used multithreading. +![mandelbrot](https://gabrielkaszewski.dev/media/output.png) +But that was just a **hello world** program, I did not write my 'own' code. + +**Repo:** [mandelbrot](https://github.com/GKaszewski/mandelbrot) + +## Chip8 emulator + +This was my second program. It was more *advanced*than Mandelbrot but still quite simple I think... +Chip8 is actually just an interpreted programming language that was used in 8 bit microprocessors in the 70s. Entire specs are just 11 pages, operation set is quite well documented and the entire process of implementing them was quite pleasant and fast. +My emulator is somewhat functional I would say, although it has some issues with keyboard handling and sound is not implemented **yet**. The emulator passed cortex+ test but somehow flags test still fails and I have no clue why and how to fix it, so I am going to work on that maybe in the future. Nevertheless it was a fun project. +![imb logo](https://user-images.githubusercontent.com/42281413/255027071-9767cc67-808b-4262-80b1-9719fe4812e8.jpg) + +I used raylib for window and drawing context, honestly I think that raylib is just an awesome library for projects like this. Anyone who would like to create some project that requires drawing, displaying window and handling sound&keyboard I would recommend you to try raylib. + +Repo: [chip8](https://github.com/GKaszewski/chip8) + +## Screensaver + +I wanted to create my own screen saver 😎. I had no idea what I wanted to make though, finally I'd had decided on making Conway's game of life as a screen saver. I have also used raylib for this project, see how useful it is. +I thought that writing own screen saver were going to be difficult to some extent, but turned out it really was not. All I had to do was to run window in fullscreen without any decorations and just parse some CLI arguments... and that was pretty much it. Oh I also had to handle any user activity and make it to close the app. Anyway it was much fun, I will probably make another one soon, something with Minecraft theme I think... + +Repo: [screensaver](https://github.com/GKaszewski/screensaver) + +## Asteroids + +The last project that I have been working on is asteroids game. It is actually just a remake of my C project (I used SDL2 for that one). In this one I am using **Bevy engine** and I have to admit it is pretty handy and straight-forward to use. I love the data driven design. I have yet still to add HUD, power-ups, boss fight and second-player feature to the game and then I will publish it on my website. In the future I am planning to make my first **commercial game** with Bevy. But we will see. + +### Conclusion + +Rust is fun, I had no idea that I would find myself in that language but I am pleasantly surprised. Same thing was with Python 😜. I really love the eco-system of Rust. Cargo is just the best. I hated in C and C++ the linking and compiling of external libraries and setting up the toolchain, in Rust all of those problems just fade away. The match feature is also cool. diff --git a/posts/spanish-inquisition-update-3-0-1.mdx b/posts/spanish-inquisition-update-3-0-1.mdx new file mode 100644 index 0000000..e22527b --- /dev/null +++ b/posts/spanish-inquisition-update-3-0-1.mdx @@ -0,0 +1,48 @@ +--- +title: "Spanish Inquisition - 3.0.1 UPDATE" +description: "" +date: "2022-05-22" +--- + +Hello everyone! I am happy to present you a brand new update for my game 🎮 [Spanish Inquisition](https://gamejolt.com/games/spanish-inquisition/425125). + +In this update, I mainly fixed bugs and changed UI. + +## Main menu + +![img](https://i.imgur.com/ZZGQ2ib.png) + +## New settings + +![img](https://i.imgur.com/8PZ61v1.png) + +## Small change + +![img](https://i.imgur.com/KK7hhmZ.png) + +## Better be active! + +![img](https://i.imgur.com/cmfaTNP.png) + +### Changelog + +- Redesigned main menu, settings, pause menu, and game over screen. +- Added win screen **sic!** +- Now player can see their health. +- If you don't move for longer than 10 seconds, you'll take damage. The time after you take damage shortens by **half** every time. +- Add highscore +- If you play with hints settings on, you will get 5 points per guess. +- Hint settings and highscore now save. +- After win you can see how many words you have guessed and how many you did skip. +- If you skip a word, you'll get minus 10 or 5 points depending on your game settings. +- Enemies now remember the word. +- You won't get the same word multiple times. + +### Roadmap for 4.0.0 update + +- Add WebGL version +- Allow the player to extend the dictionary +- Add achievements. +- Add some powerups (word pass etc) +- Add particles +- Make better UI diff --git a/public/backgrounds/1.avif b/public/backgrounds/1.avif new file mode 100644 index 0000000..9a2d893 Binary files /dev/null and b/public/backgrounds/1.avif differ diff --git a/public/backgrounds/2.avif b/public/backgrounds/2.avif new file mode 100644 index 0000000..30c0d4d Binary files /dev/null and b/public/backgrounds/2.avif differ diff --git a/public/backgrounds/3.avif b/public/backgrounds/3.avif new file mode 100644 index 0000000..1edd031 Binary files /dev/null and b/public/backgrounds/3.avif differ diff --git a/public/backgrounds/4.avif b/public/backgrounds/4.avif new file mode 100644 index 0000000..53f6568 Binary files /dev/null and b/public/backgrounds/4.avif differ diff --git a/public/backgrounds/5.avif b/public/backgrounds/5.avif new file mode 100644 index 0000000..2e6f803 Binary files /dev/null and b/public/backgrounds/5.avif differ diff --git a/public/books.avif b/public/books.avif new file mode 100644 index 0000000..0854580 Binary files /dev/null and b/public/books.avif differ diff --git a/public/file.svg b/public/file.svg deleted file mode 100644 index 004145c..0000000 --- a/public/file.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/globe.svg b/public/globe.svg deleted file mode 100644 index 567f17b..0000000 --- a/public/globe.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/next.svg b/public/next.svg deleted file mode 100644 index 5174b28..0000000 --- a/public/next.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg deleted file mode 100644 index 7705396..0000000 --- a/public/vercel.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/window.svg b/public/window.svg deleted file mode 100644 index b2b2a44..0000000 --- a/public/window.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file