diff --git a/Dockerfile b/Dockerfile index 4066d88..62c3946 100644 --- a/Dockerfile +++ b/Dockerfile @@ -54,20 +54,6 @@ RUN pnpm run build FROM node:24-alpine AS runtime -# Install runtime dependencies for Playwright -RUN apk add --no-cache \ - chromium \ - nss \ - freetype \ - freetype-dev \ - harfbuzz \ - ca-certificates \ - ttf-freefont - -# Tell Playwright to use the installed Chromium -ENV PLAYWRIGHT_BROWSERS_PATH=/usr/bin -ENV PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/chromium-browser - WORKDIR /app # Copy built application diff --git a/README.md b/README.md index 9026385..aa7cf7f 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,6 @@ My personal website built with Astro and Preact! - **Blog Posts** - **Projects** - **Talks** -- **Terminal View** - -** Nix with flakes enabled is required for local development! Install it on your OS of choice OR use NixOS! ## Development @@ -18,10 +15,6 @@ My personal website built with Astro and Preact! # Install dependencies pnpm i -# Start development server -pnpm nix # Build with flakes -pnpm dev - # Build for production pnpm build ``` diff --git a/flake.lock b/flake.lock deleted file mode 100644 index 80a25ac..0000000 --- a/flake.lock +++ /dev/null @@ -1,61 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1753250450, - "narHash": "sha256-i+CQV2rPmP8wHxj0aq4siYyohHwVlsh40kV89f3nw1s=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "fc02ee70efb805d3b2865908a13ddd4474557ecf", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixos-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} diff --git a/flake.nix b/flake.nix deleted file mode 100644 index 46e1bbe..0000000 --- a/flake.nix +++ /dev/null @@ -1,120 +0,0 @@ -# flake.nix -{ - description = "A portable development environment for atridotdad with Nix Flakes"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-utils.url = "github:numtide/flake-utils"; - }; - - outputs = { self, nixpkgs, flake-utils }: - flake-utils.lib.eachDefaultSystem (system: - let - pkgs = nixpkgs.legacyPackages.${system}; - - isDarwin = pkgs.stdenv.isDarwin; - isLinux = pkgs.stdenv.isLinux; - - commonDevTools = with pkgs; [ - nodejs_24 - nodePackages.pnpm - git - curl - ]; - - # Common libraries needed for Playwright - playwrightCommonLibs = with pkgs; [ - glib - nss - nspr - dbus - atk - at-spi2-atk - at-spi2-core - cups - expat - libxkbcommon - cairo - pango - fontconfig - freetype - harfbuzz - icu - libpng - gnutls - ]; - - # Linux-specific libraries for Playwright - playwrightLinuxSpecificLibs = with pkgs; [ - glibc - libgcc - xorg.libX11 - xorg.libxcb - xorg.libXext - xorg.libXfixes - xorg.libXrandr - xorg.libXcomposite - xorg.libXdamage - xorg.libXcursor - xorg.libXi - xorg.libXrender - xorg.libXtst - mesa - libglvnd - libdrm - udev - alsa-lib - ]; - - playwrightSelfDownloadLibs = playwrightCommonLibs ++ (if isLinux then playwrightLinuxSpecificLibs else []); - - playwrightLibPath = pkgs.lib.makeBinPath playwrightSelfDownloadLibs; - - in - { - devShells.default = pkgs.mkShell { - packages = commonDevTools ++ ( - if isDarwin - then playwrightCommonLibs # For macOS, Playwright will download Chromium. - else [ pkgs.chromium ] ++ playwrightSelfDownloadLibs # For Linux, provide Chromium and its dependencies - ); - - PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = if isDarwin then "0" else "1"; - - PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH = pkgs.lib.optionalString isLinux "${pkgs.chromium}/bin/chromium"; - PUPPETEER_SKIP_CHROMIUM_DOWNLOAD = if isDarwin then "false" else "true"; - PUPPETEER_EXECUTABLE_PATH = pkgs.lib.optionalString isLinux "${pkgs.chromium}/bin/chromium"; - - shellHook = '' - echo "🚀 atridotdad development environment loaded!" - echo "Node version: $(node --version)" - echo "pnpm version: $(pnpm --version)" - - ${pkgs.lib.optionalString isDarwin '' - echo "Chromium path: Playwright will download its own for macOS" - - export LD_LIBRARY_PATH="${playwrightLibPath}:$LD_LIBRARY_PATH" - - PLAYWRIGHT_BROWSERS_PATH="''${TMPDIR:-$HOME/.cache}/ms-playwright" - export PLAYWRIGHT_BROWSERS_PATH - - if [ ! -d "$PLAYWRIGHT_BROWSERS_PATH" ] || [ -z "$(ls -A "$PLAYWRIGHT_BROWSERS_PATH")" ]; then - echo "🌐 Installing Playwright browsers (for macOS)..." - pnpm exec playwright install chromium - else - echo "✅ Playwright browsers already installed (for macOS)." - fi - ''} - - ${pkgs.lib.optionalString isLinux '' - echo "Chromium path: ${pkgs.chromium}/bin/chromium" - ''} - - if [ ! -d "node_modules" ]; then - echo "📦 Installing pnpm dependencies..." - pnpm install --frozen-lockfile - fi - ''; - }; - }); -} diff --git a/package.json b/package.json index 5d55593..8805565 100644 --- a/package.json +++ b/package.json @@ -16,26 +16,27 @@ "@astrojs/rss": "^4.0.14", "@iarna/toml": "^2.2.5", "@preact/signals": "^2.5.1", + "@react-pdf/renderer": "^4.3.1", "@tailwindcss/typography": "^0.5.19", "@tailwindcss/vite": "^4.1.17", - "astro": "^5.16.0", + "astro": "^5.16.3", "astro-icon": "^1.1.5", - "lucide-preact": "^0.554.0", - "playwright": "^1.56.1", - "preact": "^10.27.2", + "lucide-preact": "^0.555.0", + "preact": "^10.28.0", + "react": "^19.2.0", "sharp": "^0.34.5", "tailwindcss": "^4.1.17" }, "devDependencies": { "@iconify-json/mdi": "^1.2.3", - "@iconify-json/simple-icons": "^1.2.59", + "@iconify-json/simple-icons": "^1.2.61", + "@types/react": "^19.2.7", "daisyui": "^5.5.5" }, "pnpm": { "onlyBuiltDependencies": [ "@tailwindcss/oxide", "esbuild", - "puppeteer", "sharp" ] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a21216c..0e5677c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -10,13 +10,13 @@ importers: dependencies: '@astrojs/mdx': specifier: ^4.3.12 - version: 4.3.12(astro@5.16.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3)) + version: 4.3.12(astro@5.16.3(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3)) '@astrojs/node': specifier: ^9.5.1 - version: 9.5.1(astro@5.16.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3)) + version: 9.5.1(astro@5.16.3(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3)) '@astrojs/preact': specifier: ^4.1.3 - version: 4.1.3(@babel/core@7.28.5)(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(preact@10.27.2) + version: 4.1.3(@babel/core@7.28.5)(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(preact@10.28.0) '@astrojs/rss': specifier: ^4.0.14 version: 4.0.14 @@ -25,7 +25,10 @@ importers: version: 2.2.5 '@preact/signals': specifier: ^2.5.1 - version: 2.5.1(preact@10.27.2) + version: 2.5.1(preact@10.28.0) + '@react-pdf/renderer': + specifier: ^4.3.1 + version: 4.3.1(react@19.2.0) '@tailwindcss/typography': specifier: ^0.5.19 version: 0.5.19(tailwindcss@4.1.17) @@ -33,20 +36,20 @@ importers: specifier: ^4.1.17 version: 4.1.17(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)) astro: - specifier: ^5.16.0 - version: 5.16.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3) + specifier: ^5.16.3 + version: 5.16.3(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3) astro-icon: specifier: ^1.1.5 version: 1.1.5 lucide-preact: - specifier: ^0.554.0 - version: 0.554.0(preact@10.27.2) - playwright: - specifier: ^1.56.1 - version: 1.56.1 + specifier: ^0.555.0 + version: 0.555.0(preact@10.28.0) preact: - specifier: ^10.27.2 - version: 10.27.2 + specifier: ^10.28.0 + version: 10.28.0 + react: + specifier: ^19.2.0 + version: 19.2.0 sharp: specifier: ^0.34.5 version: 0.34.5 @@ -58,8 +61,11 @@ importers: specifier: ^1.2.3 version: 1.2.3 '@iconify-json/simple-icons': - specifier: ^1.2.59 - version: 1.2.59 + specifier: ^1.2.61 + version: 1.2.61 + '@types/react': + specifier: ^19.2.7 + version: 19.2.7 daisyui: specifier: ^5.5.5 version: 5.5.5 @@ -190,6 +196,10 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/runtime@7.28.4': + resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} + engines: {node: '>=6.9.0'} + '@babel/template@7.27.2': resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} @@ -371,11 +381,11 @@ packages: '@iconify-json/mdi@1.2.3': resolution: {integrity: sha512-O3cLwbDOK7NNDf2ihaQOH5F9JglnulNDFV7WprU2dSoZu3h3cWH//h74uQAB87brHmvFVxIOkuBX2sZSzYhScg==} - '@iconify-json/simple-icons@1.2.59': - resolution: {integrity: sha512-fYx/InyQsWFW4wVxWka3CGDJ6m/fXoTqWBSl+oA3FBXO5RhPAb6S3Y5bRgCPnrYevErH8VjAL0TZevIqlN2PhQ==} + '@iconify-json/simple-icons@1.2.61': + resolution: {integrity: sha512-DG6z3VEAxtDEw/SuZssZ/E8EvhjBhFQqxpEo3uckRKiia3LfZHmM4cx4RsaO2qX1Bqo9uadR5c/hYavvUQVuHw==} - '@iconify/tools@4.1.4': - resolution: {integrity: sha512-s6BcNUcCxQ3S6cvhlsoWzOuBt8qKXdVyXB9rT57uSJ/ARHD7dVM43+5ERBWn3tmkMWXeJ/s9DPVc3dUasayzeA==} + '@iconify/tools@4.2.0': + resolution: {integrity: sha512-WRxPva/ipxYkqZd1+CkEAQmd86dQmrwH0vwK89gmp2Kh2WyyVw57XbPng0NehP3x4V1LzLsXUneP1uMfTMZmUA==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -520,6 +530,10 @@ packages: cpu: [x64] os: [win32] + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -573,6 +587,49 @@ packages: preact: ^10.4.0 || ^11.0.0-0 vite: '>=2.0.0' + '@react-pdf/fns@3.1.2': + resolution: {integrity: sha512-qTKGUf0iAMGg2+OsUcp9ffKnKi41RukM/zYIWMDJ4hRVYSr89Q7e3wSDW/Koqx3ea3Uy/z3h2y3wPX6Bdfxk6g==} + + '@react-pdf/font@4.0.3': + resolution: {integrity: sha512-N1qQDZr6phXYQOp033Hvm2nkUkx2LkszjGPbmRavs9VOYzi4sp31MaccMKptL24ii6UhBh/z9yPUhnuNe/qHwA==} + + '@react-pdf/image@3.0.3': + resolution: {integrity: sha512-lvP5ryzYM3wpbO9bvqLZYwEr5XBDX9jcaRICvtnoRqdJOo7PRrMnmB4MMScyb+Xw10mGeIubZAAomNAG5ONQZQ==} + + '@react-pdf/layout@4.4.1': + resolution: {integrity: sha512-GVzdlWoZWldRDzlWj3SttRXmVDxg7YfraAohwy+o9gb9hrbDJaaAV6jV3pc630Evd3K46OAzk8EFu8EgPDuVuA==} + + '@react-pdf/pdfkit@4.0.4': + resolution: {integrity: sha512-/nITLggsPlB66bVLnm0X7MNdKQxXelLGZG6zB5acF5cCgkFwmXHnLNyxYOUD4GMOMg1HOPShXDKWrwk2ZeHsvw==} + + '@react-pdf/png-js@3.0.0': + resolution: {integrity: sha512-eSJnEItZ37WPt6Qv5pncQDxLJRK15eaRwPT+gZoujP548CodenOVp49GST8XJvKMFt9YqIBzGBV/j9AgrOQzVA==} + + '@react-pdf/primitives@4.1.1': + resolution: {integrity: sha512-IuhxYls1luJb7NUWy6q5avb1XrNaVj9bTNI40U9qGRuS6n7Hje/8H8Qi99Z9UKFV74bBP3DOf3L1wV2qZVgVrQ==} + + '@react-pdf/reconciler@1.1.4': + resolution: {integrity: sha512-oTQDiR/t4Z/Guxac88IavpU2UgN7eR0RMI9DRKvKnvPz2DUasGjXfChAdMqDNmJJxxV26mMy9xQOUV2UU5/okg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@react-pdf/render@4.3.1': + resolution: {integrity: sha512-v1WAaAhQShQZGcBxfjkEThGCHVH9CSuitrZ1bIOLvB5iBKM14abYK5D6djKhWCwF6FTzYeT2WRjRMVgze/ND2A==} + + '@react-pdf/renderer@4.3.1': + resolution: {integrity: sha512-dPKHiwGTaOsKqNWCHPYYrx8CDfAGsUnV4tvRsEu0VPGxuot1AOq/M+YgfN/Pb+MeXCTe2/lv6NvA8haUtj3tsA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@react-pdf/stylesheet@6.1.1': + resolution: {integrity: sha512-Iyw0A3wRIeQLN4EkaKf8yF9MvdMxiZ8JjoyzLzDHSxnKYoOA4UGu84veCb8dT9N8MxY5x7a0BUv/avTe586Plg==} + + '@react-pdf/textkit@6.0.0': + resolution: {integrity: sha512-fDt19KWaJRK/n2AaFoVm31hgGmpygmTV7LsHGJNGZkgzXcFyLsx+XUl63DTDPH3iqxj3xUX128t104GtOz8tTw==} + + '@react-pdf/types@2.9.1': + resolution: {integrity: sha512-5GoCgG0G5NMgpPuHbKG2xcVRQt7+E5pg3IyzVIIozKG3nLcnsXW4zy25vG1ZBQA0jmo39q34au/sOnL/0d1A4w==} + '@rollup/pluginutils@4.2.1': resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} engines: {node: '>= 8.0.0'} @@ -696,23 +753,23 @@ packages: cpu: [x64] os: [win32] - '@shikijs/core@3.15.0': - resolution: {integrity: sha512-8TOG6yG557q+fMsSVa8nkEDOZNTSxjbbR8l6lF2gyr6Np+jrPlslqDxQkN6rMXCECQ3isNPZAGszAfYoJOPGlg==} + '@shikijs/core@3.17.1': + resolution: {integrity: sha512-VWsduykcibGU0WMi66PflThDWyqEeTOiWdCRa3wmsZuishh+1PDSOh5gGxHdSrOtS+v1pmYaxodk/JNzwusElA==} - '@shikijs/engine-javascript@3.15.0': - resolution: {integrity: sha512-ZedbOFpopibdLmvTz2sJPJgns8Xvyabe2QbmqMTz07kt1pTzfEvKZc5IqPVO/XFiEbbNyaOpjPBkkr1vlwS+qg==} + '@shikijs/engine-javascript@3.17.1': + resolution: {integrity: sha512-Ars0DVJITQrkOl5Swwy+94NL/BlOi/w1NSFbPGkcsln7Dv+M2qHaVpNHwdtWCC4/arzvjuHbyWBUsWExDHPDLw==} - '@shikijs/engine-oniguruma@3.15.0': - resolution: {integrity: sha512-HnqFsV11skAHvOArMZdLBZZApRSYS4LSztk2K3016Y9VCyZISnlYUYsL2hzlS7tPqKHvNqmI5JSUJZprXloMvA==} + '@shikijs/engine-oniguruma@3.17.1': + resolution: {integrity: sha512-fsXPy4va/4iblEGS+22nP5V08IwwBcM+8xHUzSON0QmHm29/AJRghA95w9VDnxuwp9wOdJxEhfPkKp6vqcsN+w==} - '@shikijs/langs@3.15.0': - resolution: {integrity: sha512-WpRvEFvkVvO65uKYW4Rzxs+IG0gToyM8SARQMtGGsH4GDMNZrr60qdggXrFOsdfOVssG/QQGEl3FnJ3EZ+8w8A==} + '@shikijs/langs@3.17.1': + resolution: {integrity: sha512-YTBVN+L2j7zBuOVjNZ2XiSNQEkm/7wZ1TSc5UO77GJPcg7Rk25WSscWA7y8pW7Bo25JIU0EWchUkq/UQjOJlJA==} - '@shikijs/themes@3.15.0': - resolution: {integrity: sha512-8ow2zWb1IDvCKjYb0KiLNrK4offFdkfNVPXb1OZykpLCzRU6j+efkY+Y7VQjNlNFXonSw+4AOdGYtmqykDbRiQ==} + '@shikijs/themes@3.17.1': + resolution: {integrity: sha512-aohwwqNUB5h2ATfgrqYRPl8vyazqCiQ2wIV4xq+UzaBRHpqLMGSemkasK+vIEpl0YaendoaKUsDfpwhCqyHIaQ==} - '@shikijs/types@3.15.0': - resolution: {integrity: sha512-BnP+y/EQnhihgHy4oIAN+6FFtmfTekwOLsQbRw9hOKwqgNy8Bdsjq8B05oAt/ZgvIWWFrshV71ytOrlPfYjIJw==} + '@shikijs/types@3.17.1': + resolution: {integrity: sha512-yUFLiCnZHHJ16KbVbt3B1EzBUadU3OVpq0PEyb301m5BbuFKApQYBzJGhrK48hH/tYWSjzwcj7BSmYbBc0zntQ==} '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} @@ -849,8 +906,8 @@ packages: '@types/node@24.10.1': resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} - '@types/tar@6.1.13': - resolution: {integrity: sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==} + '@types/react@19.2.7': + resolution: {integrity: sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==} '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -864,6 +921,9 @@ packages: '@ungap/structured-clone@1.3.0': resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==} + abs-svg-path@0.1.1: + resolution: {integrity: sha512-d8XPSGjfyzlXC3Xx891DJRyZfqk5JU0BJrDQcsWomFIV1/BIzPW5HDH5iDdWpqWaav0YVIEzT1RHTwWr0FFshA==} + acorn-jsx@5.3.2: resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} peerDependencies: @@ -910,17 +970,11 @@ packages: astro-icon@1.1.5: resolution: {integrity: sha512-CJYS5nWOw9jz4RpGWmzNQY7D0y2ZZacH7atL2K9DeJXJVaz7/5WrxeyIxO8KASk1jCM96Q4LjRx/F3R+InjJrw==} - astro@5.16.0: - resolution: {integrity: sha512-GaDRs2Mngpw3dr2vc085GnORh98NiXxwIjg/EoQQQl/icZt3Z7s0BRsYHDZ8swkZbOA6wZsqWJdrNirl+iKcDg==} + astro@5.16.3: + resolution: {integrity: sha512-KzDk41F9Dspf5fM/Ls4XZhV4/csjJcWBrlenbnp5V3NGwU1zEaJz/HIyrdKdf5yw+FgwCeD2+Yos1Xkx9gnI0A==} engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'} hasBin: true - asynckit@0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - - axios@1.13.2: - resolution: {integrity: sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==} - axobject-query@4.1.0: resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} engines: {node: '>= 0.4'} @@ -936,13 +990,20 @@ packages: base-64@1.0.0: resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} + base64-js@0.0.8: + resolution: {integrity: sha512-3XSA2cR/h/73EzlXXdU6YNycmYI7+kicTxks4eJg2g39biHR84slg2+des+p7iHYhbRg/udIS4TD53WabcOUkw==} + engines: {node: '>= 0.4'} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.8.30: - resolution: {integrity: sha512-aTUKW4ptQhS64+v2d6IkPzymEzzhw+G0bA1g3uBRV3+ntkH+svttKseW5IOR4Ed6NUVKqnY7qT3dKvzQ7io4AA==} + baseline-browser-mapping@2.8.32: + resolution: {integrity: sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==} hasBin: true + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} @@ -953,6 +1014,9 @@ packages: brotli@1.3.3: resolution: {integrity: sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==} + browserify-zlib@0.2.0: + resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} + browserslist@4.28.0: resolution: {integrity: sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -961,16 +1025,12 @@ packages: buffer-crc32@0.2.13: resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - call-bind-apply-helpers@1.0.2: - resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} - engines: {node: '>= 0.4'} - camelcase@8.0.0: resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} engines: {node: '>=16'} - caniuse-lite@1.0.30001756: - resolution: {integrity: sha512-4HnCNKbMLkLdhJz3TToeVWHSnfJvPaq6vu/eRP0Ahub/07n484XHhBF5AJoSGHdVrS8tKFauUQz8Bp9P7LVx7A==} + caniuse-lite@1.0.30001757: + resolution: {integrity: sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==} ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -994,17 +1054,17 @@ packages: cheerio-select@2.1.0: resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} - cheerio@1.0.0: - resolution: {integrity: sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==} - engines: {node: '>=18.17'} + cheerio@1.1.2: + resolution: {integrity: sha512-IkxPpb5rS/d1IiLbHMgfPuS0FgiWTtFIm/Nj+2woXDLTZ7fOT2eqzgYbdMlLweqlHbsZjxEChoVK+7iph7jyQg==} + engines: {node: '>=20.18.1'} chokidar@4.0.3: resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} engines: {node: '>= 14.16.0'} - chownr@2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} ci-info@4.3.1: resolution: {integrity: sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==} @@ -1025,9 +1085,11 @@ packages: collapse-white-space@2.1.0: resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==} - combined-stream@1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} @@ -1055,13 +1117,16 @@ packages: cookie-es@1.2.2: resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} - cookie@1.0.2: - resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} crossws@0.3.5: resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + css-select@5.2.2: resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} @@ -1090,6 +1155,9 @@ packages: resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + daisyui@5.5.5: resolution: {integrity: sha512-ekvI93ZkWIJoCOtDl0D2QMxnWvTejk9V5nWBqRv+7t0xjiBXqAK5U6o6JE2RPvlIC3EqwNyUoIZSdHX9MZK3nw==} @@ -1108,10 +1176,6 @@ packages: defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} - delayed-stream@1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} @@ -1164,15 +1228,14 @@ packages: resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} engines: {node: '>=4'} - dunder-proto@1.0.1: - resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} - engines: {node: '>= 0.4'} - ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - electron-to-chromium@1.5.259: - resolution: {integrity: sha512-I+oLXgpEJzD6Cwuwt1gYjxsDmu/S/Kd41mmLA3O+/uH2pFRO/DvOjUyGozL8j3KeLV6WyZ7ssPwELMsXCcsJAQ==} + electron-to-chromium@1.5.262: + resolution: {integrity: sha512-NlAsMteRHek05jRUxUR0a5jpjYq9ykk6+kO0yRaMi5moe7u0fVIOeQ3Y30A8dIiWFBNUoQGi1ljb1i5VtS9WQQ==} + + emoji-regex-xs@1.0.0: + resolution: {integrity: sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -1202,25 +1265,9 @@ packages: resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==} engines: {node: '>=0.12'} - es-define-property@1.0.1: - resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} - engines: {node: '>= 0.4'} - - es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} - es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} - engines: {node: '>= 0.4'} - - es-set-tostringtag@2.1.0: - resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} - engines: {node: '>= 0.4'} - esast-util-from-estree@2.0.0: resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} @@ -1274,6 +1321,10 @@ packages: eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + exsolve@1.0.8: resolution: {integrity: sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==} @@ -1308,46 +1359,21 @@ packages: resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} engines: {node: '>=8'} - follow-redirects@1.15.11: - resolution: {integrity: sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - fontace@0.3.1: resolution: {integrity: sha512-9f5g4feWT1jWT8+SbL85aLIRLIXUaDygaM2xPXRmzPYxrOMNok79Lr3FGJoKVNKibE0WCunNiEVG2mwuE+2qEg==} fontkit@2.0.4: resolution: {integrity: sha512-syetQadaUEDNdxdugga9CpEYVaQIxOwk7GlwZWWZ19//qW4zE5bknOKeMBDYAASwnpaSHKJITRLMF9m1fp3s6g==} - form-data@4.0.5: - resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} - engines: {node: '>= 6'} - fresh@2.0.0: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} - fs-minipass@2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - - fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} - engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} - os: [darwin] - fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] - function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} - gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -1356,14 +1382,6 @@ packages: resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} engines: {node: '>=18'} - get-intrinsic@1.3.0: - resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} - engines: {node: '>= 0.4'} - - get-proto@1.0.1: - resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} - engines: {node: '>= 0.4'} - get-stream@5.2.0: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} @@ -1375,28 +1393,12 @@ packages: resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} - gopd@1.2.0: - resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} - engines: {node: '>= 0.4'} - graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} h3@1.15.4: resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} - has-symbols@1.1.0: - resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} - engines: {node: '>= 0.4'} - - has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} - - hasown@2.0.2: - resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} - engines: {node: '>= 0.4'} - hast-util-from-html@2.0.3: resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} @@ -1437,14 +1439,20 @@ packages: resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} hasBin: true + hsl-to-hex@1.0.0: + resolution: {integrity: sha512-K6GVpucS5wFf44X0h2bLVRDsycgJmf9FF2elg+CrqD8GcFU8c6vYhgXn8NjUkFCwj+xDFb70qgLbTUm6sxwPmA==} + + hsl-to-rgb-for-reals@1.1.1: + resolution: {integrity: sha512-LgOWAkrN0rFaQpfdWBQlv/VhkOxb5AsBjk6NQVx4yEzWS923T07X0M1Y0VNko2H52HeSpZrZNNMJ0aFqsdVzQg==} + html-escaper@3.0.3: resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} - htmlparser2@9.1.0: - resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} + htmlparser2@10.0.0: + resolution: {integrity: sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==} http-cache-semantics@4.2.0: resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} @@ -1453,6 +1461,9 @@ packages: resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} engines: {node: '>= 0.8'} + hyphen@1.10.6: + resolution: {integrity: sha512-fXHXcGFTXOvZTSkPJuGOQf5Lv5T/R2itiiCVPg9LxAje5D00O0pP83yJShFq5V89Ly//Gt6acj7z8pbBr34stw==} + iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -1475,6 +1486,9 @@ packages: is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} @@ -1499,10 +1513,16 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + is-wsl@3.1.0: resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} engines: {node: '>=16'} + jay-peg@1.1.1: + resolution: {integrity: sha512-D62KEuBxz/ip2gQKOEhk/mx14o7eiFRaU+VNNSP4MOiIkwb/D6B3G1Mfas7C/Fit8EsSV2/IWjZElx/Gs6A4ww==} + jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -1601,9 +1621,8 @@ packages: resolution: {integrity: sha512-utfs7Pr5uJyyvDETitgsaqSyjCb2qNRAtuqUeWIAKztsOYdcACf2KtARYXg2pSvhkt+9NfoaNY7fxjl6nuMjIQ==} engines: {node: '>= 12.0.0'} - local-pkg@0.5.1: - resolution: {integrity: sha512-9rrA30MRRP3gBD3HTGnC6cDFpaE1kVDWxWgqWJUN0RvDNAo+Nz/9GxB+nHOH0ifbVFy0hSA1V6vFDvnx54lTEQ==} - engines: {node: '>=14'} + linebreak@1.1.0: + resolution: {integrity: sha512-MHp03UImeVhB7XZtjd0E4n6+3xr5Dq/9xI/5FptGk5FrbDR3zagPa2DS6U8ks/3HjbKWG9Q1M2ufOzxV2qLYSQ==} local-pkg@1.1.2: resolution: {integrity: sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==} @@ -1612,14 +1631,18 @@ packages: longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} lru-cache@5.1.1: resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} - lucide-preact@0.554.0: - resolution: {integrity: sha512-+d6euadQLdgeUyoHYDYdFi4jTfAD7G+S5vE03I2PxeETek0R+G4Z3eS8/X77EAf+2Nfzx3iLS8sAR3Jt9zzxMQ==} + lucide-preact@0.555.0: + resolution: {integrity: sha512-NcVrZL6iMRNhEXrqDRGFLL6fL5shDKc2v3wSazuG/E973qf/0zCSfHxUqk8f5oNrUgrPjUUnOZeQneVfaej5aw==} peerDependencies: preact: ^10.5.13 @@ -1636,10 +1659,6 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} - math-intrinsics@1.1.0: - resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} - engines: {node: '>= 0.4'} - mdast-util-definitions@6.0.0: resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==} @@ -1682,8 +1701,8 @@ packages: mdast-util-phrasing@4.1.0: resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} - mdast-util-to-hast@13.2.0: - resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==} + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} mdast-util-to-markdown@2.1.2: resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} @@ -1700,6 +1719,9 @@ packages: mdn-data@2.12.2: resolution: {integrity: sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==} + media-engine@1.0.3: + resolution: {integrity: sha512-aa5tG6sDoK+k70B9iEX1NeyfT8ObCKhNDs6lJVpwF6r8vhUfuKMslIcirq6HIUYuuUYLefcEQOn9bSBOvawtwg==} + micromark-core-commonmark@2.0.3: resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} @@ -1805,42 +1827,21 @@ packages: micromark@4.0.2: resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} - mime-db@1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - mime-db@1.54.0: resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} - mime-types@2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - mime-types@3.0.2: resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} engines: {node: '>=18'} - minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} - minipass@4.2.8: - resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} - engines: {node: '>=8'} - - minipass@5.0.0: - resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} - engines: {node: '>=8'} - - minizlib@2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - - mkdirp@1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true + minizlib@3.1.0: + resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} + engines: {node: '>= 18'} mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} @@ -1880,9 +1881,16 @@ packages: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + normalize-svg-path@1.1.0: + resolution: {integrity: sha512-r9KHKG2UUeB5LoTouwDzBy2VxXlHsiM6fyLQvnJa0S5hrhzqElH/CH7TUGhT1fVvIYBIKf3OpY4YJ4CK+iaqHg==} + nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + ofetch@1.5.1: resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} @@ -1914,18 +1922,24 @@ packages: resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} engines: {node: '>=14.16'} - package-manager-detector@1.5.0: - resolution: {integrity: sha512-uBj69dVlYe/+wxj8JOpr97XfsxH/eumMt6HqjNTmJDf/6NO9s+0uxeOneIz3AsPt2m6y9PqzDzd3ATcU17MNfw==} + package-manager-detector@1.6.0: + resolution: {integrity: sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==} pako@0.2.9: resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + parse-entities@4.0.2: resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} parse-latin@7.0.0: resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==} + parse-svg-path@0.1.2: + resolution: {integrity: sha512-JyPSBnkTJ0AI8GGJLfMXvKq42cj5c006fnLz6fXy6zfoVjJizi8BNTpu8on8ziI1cKy9d9DGNuY17Ce7wuejpQ==} + parse5-htmlparser2-tree-adapter@7.1.0: resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} @@ -1935,9 +1949,6 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} - pathe@1.1.2: - resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -1964,20 +1975,13 @@ packages: pkg-types@2.3.0: resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} - playwright-core@1.56.1: - resolution: {integrity: sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==} - engines: {node: '>=18'} - hasBin: true - - playwright@1.56.1: - resolution: {integrity: sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==} - engines: {node: '>=18'} - hasBin: true - postcss-selector-parser@6.0.10: resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} engines: {node: '>=4'} + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + postcss@8.5.6: resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} engines: {node: ^10 || ^12 || >=14} @@ -1987,8 +1991,8 @@ packages: peerDependencies: preact: '>=10 || >= 11.0.0-0' - preact@10.27.2: - resolution: {integrity: sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==} + preact@10.28.0: + resolution: {integrity: sha512-rytDAoiXr3+t6OIP3WGlDd0ouCUG1iCWzkcY3++Nreuoi17y6T5i/zRhe6uYfoVcxq6YU+sBtJouuRDsq8vvqA==} prismjs@1.30.0: resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} @@ -1998,21 +2002,24 @@ packages: resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} engines: {node: '>= 6'} + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + property-information@6.5.0: resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} property-information@7.1.0: resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} - proxy-from-env@1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - pump@3.0.3: resolution: {integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==} quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + queue@6.0.2: + resolution: {integrity: sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==} + radix3@1.1.2: resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} @@ -2020,6 +2027,13 @@ packages: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react@19.2.0: + resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} + engines: {node: '>=0.10.0'} + readdirp@4.1.2: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} @@ -2081,6 +2095,10 @@ packages: remark-stringify@11.0.0: resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==} + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + restructure@3.0.2: resolution: {integrity: sha512-gSfoiOEA0VPE6Tukkrr7I0RBdE0s7H1eFCDBk05l1KIQT1UIKNc5JZy6jdyW6eYH3aR3g5b3PuL77rq0hvwtAw==} @@ -2101,12 +2119,18 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} sax@1.4.3: resolution: {integrity: sha512-yqYn1JhPczigF94DMS+shiDMjDowYO6y9+wB/4WgO0Y19jWYk0lQ4tuG5KI7kj4FTp1wxPj5IFfcrz/s1c3jjQ==} + scheduler@0.25.0-rc-603e6108-20241029: + resolution: {integrity: sha512-pFwF6H1XrSdYYNLfOcGlM28/j8CGLu8IvdrxqhjWULe2bPcKiKW4CV+OWqR/9fT52mywx65l7ysNkjLKBda7eA==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -2130,12 +2154,15 @@ packages: resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} - shiki@3.15.0: - resolution: {integrity: sha512-kLdkY6iV3dYbtPwS9KXU7mjfmDm25f5m0IPNFnaXO7TBPcvbUOY72PYXSuSqDzwp+vlH/d7MXpHlKO/x+QoLXw==} + shiki@3.17.1: + resolution: {integrity: sha512-KbAPJo6pQpfjupOg5HW0fk/OSmeBfzza2IjZ5XbNKbqhZaCoxro/EyOgesaLvTdyDfrsAUDA6L4q14sc+k9i7g==} simple-code-frame@1.3.0: resolution: {integrity: sha512-MB4pQmETUBlNs62BBeRjIFGeuy/x6gGKh7+eRUemn1rCFhqo7K+4slPqsyizCbcbYLnaYqaoZ2FWsZ/jN06D8w==} + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -2170,6 +2197,9 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-entities@4.0.4: resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} @@ -2190,6 +2220,9 @@ packages: style-to-object@1.0.14: resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + svg-arc-to-cubic-bezier@3.2.0: + resolution: {integrity: sha512-djbJ/vZKZO+gPoSDThGNpKDO+o+bAeA4XQKovvkNCqnIS2t+S4qnLAGQhyyrulhCFRl1WWzAp0wUDV8PpTVU3g==} + svgo@3.3.2: resolution: {integrity: sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw==} engines: {node: '>=14.0.0'} @@ -2207,9 +2240,9 @@ packages: resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} engines: {node: '>=6'} - tar@6.2.1: - resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} - engines: {node: '>=10'} + tar@7.5.2: + resolution: {integrity: sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==} + engines: {node: '>=18'} tiny-inflate@1.0.3: resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} @@ -2266,9 +2299,9 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} - undici@6.22.0: - resolution: {integrity: sha512-hU/10obOIu62MGYjdskASR3CUAiYaFTtC9Pa6vHyf//mAipSvSQg6od2CnJswq7fvzNS3zJhxoRkgNVaHurWKw==} - engines: {node: '>=18.17'} + undici@7.16.0: + resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} + engines: {node: '>=20.18.1'} unicode-properties@1.4.1: resolution: {integrity: sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg==} @@ -2392,6 +2425,10 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + vite-compatible-readable-stream@3.6.1: + resolution: {integrity: sha512-t20zYkrSf868+j/p31cRIGN28Phrjm3nRSLR2fyc2tiWi4cZGVdv68yNlwnIINTkMTmPoMiSlc0OadaO7DXZaQ==} + engines: {node: '>= 6'} + vite-prerender-plugin@0.5.12: resolution: {integrity: sha512-EiwhbMn+flg14EysbLTmZSzq8NGTxhytgK3bf4aGRF1evWLGwZiHiUJ1KZDvbxgKbMf2pG6fJWGEa3UZXOnR1g==} peerDependencies: @@ -2477,8 +2514,9 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} @@ -2499,6 +2537,9 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} + yoga-layout@3.2.1: + resolution: {integrity: sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ==} + zod-to-json-schema@3.25.0: resolution: {integrity: sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==} peerDependencies: @@ -2520,7 +2561,7 @@ snapshots: '@antfu/install-pkg@1.1.0': dependencies: - package-manager-detector: 1.5.0 + package-manager-detector: 1.6.0 tinyexec: 1.0.2 '@antfu/utils@8.1.1': {} @@ -2545,7 +2586,7 @@ snapshots: remark-parse: 11.0.0 remark-rehype: 11.1.2 remark-smartypants: 3.0.2 - shiki: 3.15.0 + shiki: 3.17.1 smol-toml: 1.5.2 unified: 11.0.5 unist-util-remove-position: 5.0.0 @@ -2555,12 +2596,12 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/mdx@4.3.12(astro@5.16.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3))': + '@astrojs/mdx@4.3.12(astro@5.16.3(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3))': dependencies: '@astrojs/markdown-remark': 6.3.9 '@mdx-js/mdx': 3.1.1 acorn: 8.15.0 - astro: 5.16.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3) + astro: 5.16.3(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3) es-module-lexer: 1.7.0 estree-util-visit: 2.0.0 hast-util-to-html: 9.0.5 @@ -2574,21 +2615,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@astrojs/node@9.5.1(astro@5.16.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3))': + '@astrojs/node@9.5.1(astro@5.16.3(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3))': dependencies: '@astrojs/internal-helpers': 0.7.5 - astro: 5.16.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3) + astro: 5.16.3(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3) send: 1.2.0 server-destroy: 1.0.1 transitivePeerDependencies: - supports-color - '@astrojs/preact@4.1.3(@babel/core@7.28.5)(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(preact@10.27.2)': + '@astrojs/preact@4.1.3(@babel/core@7.28.5)(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(preact@10.28.0)': dependencies: - '@preact/preset-vite': 2.10.2(@babel/core@7.28.5)(preact@10.27.2)(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)) - '@preact/signals': 2.5.1(preact@10.27.2) - preact: 10.27.2 - preact-render-to-string: 6.6.3(preact@10.27.2) + '@preact/preset-vite': 2.10.2(@babel/core@7.28.5)(preact@10.28.0)(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)) + '@preact/signals': 2.5.1(preact@10.28.0) + preact: 10.28.0 + preact-render-to-string: 6.6.3(preact@10.28.0) vite: 6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - '@babel/core' @@ -2732,6 +2773,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/runtime@7.28.4': {} + '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 @@ -2848,25 +2891,22 @@ snapshots: dependencies: '@iconify/types': 2.0.0 - '@iconify-json/simple-icons@1.2.59': + '@iconify-json/simple-icons@1.2.61': dependencies: '@iconify/types': 2.0.0 - '@iconify/tools@4.1.4': + '@iconify/tools@4.2.0': dependencies: '@iconify/types': 2.0.0 '@iconify/utils': 2.3.0 - '@types/tar': 6.1.13 - axios: 1.13.2 - cheerio: 1.0.0 + cheerio: 1.1.2 domhandler: 5.0.3 extract-zip: 2.0.1 - local-pkg: 0.5.1 - pathe: 1.1.2 + local-pkg: 1.1.2 + pathe: 2.0.3 svgo: 3.3.2 - tar: 6.2.1 + tar: 7.5.2 transitivePeerDependencies: - - debug - supports-color '@iconify/types@2.0.0': {} @@ -2980,6 +3020,10 @@ snapshots: '@img/sharp-win32-x64@0.34.5': optional: true + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -3031,12 +3075,12 @@ snapshots: '@oslojs/encoding@1.1.0': {} - '@preact/preset-vite@2.10.2(@babel/core@7.28.5)(preact@10.27.2)(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))': + '@preact/preset-vite@2.10.2(@babel/core@7.28.5)(preact@10.28.0)(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-react-jsx': 7.27.1(@babel/core@7.28.5) '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.28.5) - '@prefresh/vite': 2.4.11(preact@10.27.2)(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)) + '@prefresh/vite': 2.4.11(preact@10.28.0)(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)) '@rollup/pluginutils': 4.2.1 babel-plugin-transform-hook-names: 1.0.2(@babel/core@7.28.5) debug: 4.4.3 @@ -3049,31 +3093,132 @@ snapshots: '@preact/signals-core@1.12.1': {} - '@preact/signals@2.5.1(preact@10.27.2)': + '@preact/signals@2.5.1(preact@10.28.0)': dependencies: '@preact/signals-core': 1.12.1 - preact: 10.27.2 + preact: 10.28.0 '@prefresh/babel-plugin@0.5.2': {} - '@prefresh/core@1.5.9(preact@10.27.2)': + '@prefresh/core@1.5.9(preact@10.28.0)': dependencies: - preact: 10.27.2 + preact: 10.28.0 '@prefresh/utils@1.2.1': {} - '@prefresh/vite@2.4.11(preact@10.27.2)(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))': + '@prefresh/vite@2.4.11(preact@10.28.0)(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2))': dependencies: '@babel/core': 7.28.5 '@prefresh/babel-plugin': 0.5.2 - '@prefresh/core': 1.5.9(preact@10.27.2) + '@prefresh/core': 1.5.9(preact@10.28.0) '@prefresh/utils': 1.2.1 '@rollup/pluginutils': 4.2.1 - preact: 10.27.2 + preact: 10.28.0 vite: 6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2) transitivePeerDependencies: - supports-color + '@react-pdf/fns@3.1.2': {} + + '@react-pdf/font@4.0.3': + dependencies: + '@react-pdf/pdfkit': 4.0.4 + '@react-pdf/types': 2.9.1 + fontkit: 2.0.4 + is-url: 1.2.4 + + '@react-pdf/image@3.0.3': + dependencies: + '@react-pdf/png-js': 3.0.0 + jay-peg: 1.1.1 + + '@react-pdf/layout@4.4.1': + dependencies: + '@react-pdf/fns': 3.1.2 + '@react-pdf/image': 3.0.3 + '@react-pdf/primitives': 4.1.1 + '@react-pdf/stylesheet': 6.1.1 + '@react-pdf/textkit': 6.0.0 + '@react-pdf/types': 2.9.1 + emoji-regex-xs: 1.0.0 + queue: 6.0.2 + yoga-layout: 3.2.1 + + '@react-pdf/pdfkit@4.0.4': + dependencies: + '@babel/runtime': 7.28.4 + '@react-pdf/png-js': 3.0.0 + browserify-zlib: 0.2.0 + crypto-js: 4.2.0 + fontkit: 2.0.4 + jay-peg: 1.1.1 + linebreak: 1.1.0 + vite-compatible-readable-stream: 3.6.1 + + '@react-pdf/png-js@3.0.0': + dependencies: + browserify-zlib: 0.2.0 + + '@react-pdf/primitives@4.1.1': {} + + '@react-pdf/reconciler@1.1.4(react@19.2.0)': + dependencies: + object-assign: 4.1.1 + react: 19.2.0 + scheduler: 0.25.0-rc-603e6108-20241029 + + '@react-pdf/render@4.3.1': + dependencies: + '@babel/runtime': 7.28.4 + '@react-pdf/fns': 3.1.2 + '@react-pdf/primitives': 4.1.1 + '@react-pdf/textkit': 6.0.0 + '@react-pdf/types': 2.9.1 + abs-svg-path: 0.1.1 + color-string: 1.9.1 + normalize-svg-path: 1.1.0 + parse-svg-path: 0.1.2 + svg-arc-to-cubic-bezier: 3.2.0 + + '@react-pdf/renderer@4.3.1(react@19.2.0)': + dependencies: + '@babel/runtime': 7.28.4 + '@react-pdf/fns': 3.1.2 + '@react-pdf/font': 4.0.3 + '@react-pdf/layout': 4.4.1 + '@react-pdf/pdfkit': 4.0.4 + '@react-pdf/primitives': 4.1.1 + '@react-pdf/reconciler': 1.1.4(react@19.2.0) + '@react-pdf/render': 4.3.1 + '@react-pdf/types': 2.9.1 + events: 3.3.0 + object-assign: 4.1.1 + prop-types: 15.8.1 + queue: 6.0.2 + react: 19.2.0 + + '@react-pdf/stylesheet@6.1.1': + dependencies: + '@react-pdf/fns': 3.1.2 + '@react-pdf/types': 2.9.1 + color-string: 1.9.1 + hsl-to-hex: 1.0.0 + media-engine: 1.0.3 + postcss-value-parser: 4.2.0 + + '@react-pdf/textkit@6.0.0': + dependencies: + '@react-pdf/fns': 3.1.2 + bidi-js: 1.0.3 + hyphen: 1.10.6 + unicode-properties: 1.4.1 + + '@react-pdf/types@2.9.1': + dependencies: + '@react-pdf/font': 4.0.3 + '@react-pdf/primitives': 4.1.1 + '@react-pdf/stylesheet': 6.1.1 + '@rollup/pluginutils@4.2.1': dependencies: estree-walker: 2.0.2 @@ -3153,33 +3298,33 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.53.3': optional: true - '@shikijs/core@3.15.0': + '@shikijs/core@3.17.1': dependencies: - '@shikijs/types': 3.15.0 + '@shikijs/types': 3.17.1 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 hast-util-to-html: 9.0.5 - '@shikijs/engine-javascript@3.15.0': + '@shikijs/engine-javascript@3.17.1': dependencies: - '@shikijs/types': 3.15.0 + '@shikijs/types': 3.17.1 '@shikijs/vscode-textmate': 10.0.2 oniguruma-to-es: 4.3.4 - '@shikijs/engine-oniguruma@3.15.0': + '@shikijs/engine-oniguruma@3.17.1': dependencies: - '@shikijs/types': 3.15.0 + '@shikijs/types': 3.17.1 '@shikijs/vscode-textmate': 10.0.2 - '@shikijs/langs@3.15.0': + '@shikijs/langs@3.17.1': dependencies: - '@shikijs/types': 3.15.0 + '@shikijs/types': 3.17.1 - '@shikijs/themes@3.15.0': + '@shikijs/themes@3.17.1': dependencies: - '@shikijs/types': 3.15.0 + '@shikijs/types': 3.17.1 - '@shikijs/types@3.15.0': + '@shikijs/types@3.17.1': dependencies: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 @@ -3299,10 +3444,9 @@ snapshots: dependencies: undici-types: 7.16.0 - '@types/tar@6.1.13': + '@types/react@19.2.7': dependencies: - '@types/node': 24.10.1 - minipass: 4.2.8 + csstype: 3.2.3 '@types/unist@2.0.11': {} @@ -3315,6 +3459,8 @@ snapshots: '@ungap/structured-clone@1.3.0': {} + abs-svg-path@0.1.1: {} + acorn-jsx@5.3.2(acorn@8.15.0): dependencies: acorn: 8.15.0 @@ -3346,14 +3492,13 @@ snapshots: astro-icon@1.1.5: dependencies: - '@iconify/tools': 4.1.4 + '@iconify/tools': 4.2.0 '@iconify/types': 2.0.0 '@iconify/utils': 2.3.0 transitivePeerDependencies: - - debug - supports-color - astro@5.16.0(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3): + astro@5.16.3(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)(rollup@4.53.3)(typescript@5.8.3): dependencies: '@astrojs/compiler': 2.13.0 '@astrojs/internal-helpers': 0.7.5 @@ -3369,7 +3514,7 @@ snapshots: ci-info: 4.3.1 clsx: 2.1.1 common-ancestor-path: 1.0.1 - cookie: 1.0.2 + cookie: 1.1.1 cssesc: 3.0.0 debug: 4.4.3 deterministic-object-hash: 2.0.2 @@ -3393,13 +3538,13 @@ snapshots: neotraverse: 0.6.18 p-limit: 6.2.0 p-queue: 8.1.1 - package-manager-detector: 1.5.0 + package-manager-detector: 1.6.0 piccolore: 0.1.3 picomatch: 4.0.3 prompts: 2.4.2 rehype: 13.0.2 semver: 7.7.3 - shiki: 3.15.0 + shiki: 3.17.1 smol-toml: 1.5.2 svgo: 4.0.0 tinyexec: 1.0.2 @@ -3455,16 +3600,6 @@ snapshots: - uploadthing - yaml - asynckit@0.4.0: {} - - axios@1.13.2: - dependencies: - follow-redirects: 1.15.11 - form-data: 4.0.5 - proxy-from-env: 1.1.0 - transitivePeerDependencies: - - debug - axobject-query@4.1.0: {} babel-plugin-transform-hook-names@1.0.2(@babel/core@7.28.5): @@ -3475,9 +3610,15 @@ snapshots: base-64@1.0.0: {} + base64-js@0.0.8: {} + base64-js@1.5.1: {} - baseline-browser-mapping@2.8.30: {} + baseline-browser-mapping@2.8.32: {} + + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 boolbase@1.0.0: {} @@ -3496,24 +3637,23 @@ snapshots: dependencies: base64-js: 1.5.1 + browserify-zlib@0.2.0: + dependencies: + pako: 1.0.11 + browserslist@4.28.0: dependencies: - baseline-browser-mapping: 2.8.30 - caniuse-lite: 1.0.30001756 - electron-to-chromium: 1.5.259 + baseline-browser-mapping: 2.8.32 + caniuse-lite: 1.0.30001757 + electron-to-chromium: 1.5.262 node-releases: 2.0.27 update-browserslist-db: 1.1.4(browserslist@4.28.0) buffer-crc32@0.2.13: {} - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - camelcase@8.0.0: {} - caniuse-lite@1.0.30001756: {} + caniuse-lite@1.0.30001757: {} ccount@2.0.1: {} @@ -3536,25 +3676,25 @@ snapshots: domhandler: 5.0.3 domutils: 3.2.2 - cheerio@1.0.0: + cheerio@1.1.2: dependencies: cheerio-select: 2.1.0 dom-serializer: 2.0.0 domhandler: 5.0.3 domutils: 3.2.2 encoding-sniffer: 0.2.1 - htmlparser2: 9.1.0 + htmlparser2: 10.0.0 parse5: 7.3.0 parse5-htmlparser2-tree-adapter: 7.1.0 parse5-parser-stream: 7.1.2 - undici: 6.22.0 + undici: 7.16.0 whatwg-mimetype: 4.0.0 chokidar@4.0.3: dependencies: readdirp: 4.1.2 - chownr@2.0.0: {} + chownr@3.0.0: {} ci-info@4.3.1: {} @@ -3566,9 +3706,12 @@ snapshots: collapse-white-space@2.1.0: {} - combined-stream@1.0.8: + color-name@1.1.4: {} + + color-string@1.9.1: dependencies: - delayed-stream: 1.0.0 + color-name: 1.1.4 + simple-swizzle: 0.2.4 comma-separated-tokens@2.0.3: {} @@ -3586,12 +3729,14 @@ snapshots: cookie-es@1.2.2: {} - cookie@1.0.2: {} + cookie@1.1.1: {} crossws@0.3.5: dependencies: uncrypto: 0.1.3 + crypto-js@4.2.0: {} + css-select@5.2.2: dependencies: boolbase: 1.0.0 @@ -3623,6 +3768,8 @@ snapshots: dependencies: css-tree: 2.2.1 + csstype@3.2.3: {} + daisyui@5.5.5: {} debug@4.4.3: @@ -3635,8 +3782,6 @@ snapshots: defu@6.1.4: {} - delayed-stream@1.0.0: {} - depd@2.0.0: {} dequal@2.0.3: {} @@ -3681,15 +3826,11 @@ snapshots: dset@3.1.4: {} - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - ee-first@1.1.1: {} - electron-to-chromium@1.5.259: {} + electron-to-chromium@1.5.262: {} + + emoji-regex-xs@1.0.0: {} emoji-regex@10.6.0: {} @@ -3715,23 +3856,8 @@ snapshots: entities@6.0.1: {} - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - es-module-lexer@1.7.0: {} - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - esast-util-from-estree@2.0.0: dependencies: '@types/estree-jsx': 1.0.5 @@ -3820,6 +3946,8 @@ snapshots: eventemitter3@5.0.1: {} + events@3.3.0: {} + exsolve@1.0.8: {} extend@3.0.2: {} @@ -3850,8 +3978,6 @@ snapshots: flattie@1.1.1: {} - follow-redirects@1.15.11: {} - fontace@0.3.1: dependencies: '@types/fontkit': 2.0.8 @@ -3869,50 +3995,15 @@ snapshots: unicode-properties: 1.4.1 unicode-trie: 2.0.0 - form-data@4.0.5: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - hasown: 2.0.2 - mime-types: 2.1.35 - fresh@2.0.0: {} - fs-minipass@2.1.0: - dependencies: - minipass: 3.3.6 - - fsevents@2.3.2: - optional: true - fsevents@2.3.3: optional: true - function-bind@1.1.2: {} - gensync@1.0.0-beta.2: {} get-east-asian-width@1.4.0: {} - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - get-stream@5.2.0: dependencies: pump: 3.0.3 @@ -3921,8 +4012,6 @@ snapshots: globals@15.15.0: {} - gopd@1.2.0: {} - graceful-fs@4.2.11: {} h3@1.15.4: @@ -3937,16 +4026,6 @@ snapshots: ufo: 1.6.1 uncrypto: 0.1.3 - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - hast-util-from-html@2.0.3: dependencies: '@types/hast': 3.0.4 @@ -3983,7 +4062,7 @@ snapshots: hast-util-from-parse5: 8.0.3 hast-util-to-parse5: 8.0.0 html-void-elements: 3.0.0 - mdast-util-to-hast: 13.2.0 + mdast-util-to-hast: 13.2.1 parse5: 7.3.0 unist-util-position: 5.0.0 unist-util-visit: 5.0.0 @@ -4020,7 +4099,7 @@ snapshots: comma-separated-tokens: 2.0.3 hast-util-whitespace: 3.0.0 html-void-elements: 3.0.0 - mdast-util-to-hast: 13.2.0 + mdast-util-to-hast: 13.2.1 property-information: 7.1.0 space-separated-tokens: 2.0.2 stringify-entities: 4.0.4 @@ -4077,16 +4156,22 @@ snapshots: he@1.2.0: {} + hsl-to-hex@1.0.0: + dependencies: + hsl-to-rgb-for-reals: 1.1.1 + + hsl-to-rgb-for-reals@1.1.1: {} + html-escaper@3.0.3: {} html-void-elements@3.0.0: {} - htmlparser2@9.1.0: + htmlparser2@10.0.0: dependencies: domelementtype: 2.3.0 domhandler: 5.0.3 domutils: 3.2.2 - entities: 4.5.0 + entities: 6.0.1 http-cache-semantics@4.2.0: {} @@ -4098,6 +4183,8 @@ snapshots: statuses: 2.0.2 toidentifier: 1.0.1 + hyphen@1.10.6: {} + iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -4117,6 +4204,8 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 + is-arrayish@0.3.4: {} + is-decimal@2.0.1: {} is-docker@3.0.0: {} @@ -4131,10 +4220,16 @@ snapshots: is-plain-obj@4.1.0: {} + is-url@1.2.4: {} + is-wsl@3.1.0: dependencies: is-inside-container: 1.0.0 + jay-peg@1.1.1: + dependencies: + restructure: 3.0.2 + jiti@2.6.1: {} js-tokens@4.0.0: {} @@ -4200,10 +4295,10 @@ snapshots: lightningcss-win32-arm64-msvc: 1.30.2 lightningcss-win32-x64-msvc: 1.30.2 - local-pkg@0.5.1: + linebreak@1.1.0: dependencies: - mlly: 1.8.0 - pkg-types: 1.3.1 + base64-js: 0.0.8 + unicode-trie: 2.0.0 local-pkg@1.1.2: dependencies: @@ -4213,15 +4308,19 @@ snapshots: longest-streak@3.1.0: {} + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + lru-cache@10.4.3: {} lru-cache@5.1.1: dependencies: yallist: 3.1.1 - lucide-preact@0.554.0(preact@10.27.2): + lucide-preact@0.555.0(preact@10.28.0): dependencies: - preact: 10.27.2 + preact: 10.28.0 magic-string@0.30.21: dependencies: @@ -4237,8 +4336,6 @@ snapshots: markdown-table@3.0.4: {} - math-intrinsics@1.1.0: {} - mdast-util-definitions@6.0.0: dependencies: '@types/mdast': 4.0.4 @@ -4380,7 +4477,7 @@ snapshots: '@types/mdast': 4.0.4 unist-util-is: 6.0.1 - mdast-util-to-hast@13.2.0: + mdast-util-to-hast@13.2.1: dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 @@ -4414,6 +4511,8 @@ snapshots: mdn-data@2.12.2: {} + media-engine@1.0.3: {} + micromark-core-commonmark@2.0.3: dependencies: decode-named-character-reference: 1.2.0 @@ -4678,32 +4777,17 @@ snapshots: transitivePeerDependencies: - supports-color - mime-db@1.52.0: {} - mime-db@1.54.0: {} - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - mime-types@3.0.2: dependencies: mime-db: 1.54.0 - minipass@3.3.6: + minipass@7.1.2: {} + + minizlib@3.1.0: dependencies: - yallist: 4.0.0 - - minipass@4.2.8: {} - - minipass@5.0.0: {} - - minizlib@2.1.2: - dependencies: - minipass: 3.3.6 - yallist: 4.0.0 - - mkdirp@1.0.4: {} + minipass: 7.1.2 mlly@1.8.0: dependencies: @@ -4737,10 +4821,16 @@ snapshots: normalize-path@3.0.0: {} + normalize-svg-path@1.1.0: + dependencies: + svg-arc-to-cubic-bezier: 3.2.0 + nth-check@2.1.1: dependencies: boolbase: 1.0.0 + object-assign@4.1.1: {} + ofetch@1.5.1: dependencies: destr: 2.0.5 @@ -4776,10 +4866,12 @@ snapshots: p-timeout@6.1.4: {} - package-manager-detector@1.5.0: {} + package-manager-detector@1.6.0: {} pako@0.2.9: {} + pako@1.0.11: {} + parse-entities@4.0.2: dependencies: '@types/unist': 2.0.11 @@ -4799,6 +4891,8 @@ snapshots: unist-util-visit-children: 3.0.0 vfile: 6.0.3 + parse-svg-path@0.1.2: {} + parse5-htmlparser2-tree-adapter@7.1.0: dependencies: domhandler: 5.0.3 @@ -4812,8 +4906,6 @@ snapshots: dependencies: entities: 6.0.1 - pathe@1.1.2: {} - pathe@2.0.3: {} pend@1.2.0: {} @@ -4838,30 +4930,24 @@ snapshots: exsolve: 1.0.8 pathe: 2.0.3 - playwright-core@1.56.1: {} - - playwright@1.56.1: - dependencies: - playwright-core: 1.56.1 - optionalDependencies: - fsevents: 2.3.2 - postcss-selector-parser@6.0.10: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 + postcss-value-parser@4.2.0: {} + postcss@8.5.6: dependencies: nanoid: 3.3.11 picocolors: 1.1.1 source-map-js: 1.2.1 - preact-render-to-string@6.6.3(preact@10.27.2): + preact-render-to-string@6.6.3(preact@10.28.0): dependencies: - preact: 10.27.2 + preact: 10.28.0 - preact@10.27.2: {} + preact@10.28.0: {} prismjs@1.30.0: {} @@ -4870,12 +4956,16 @@ snapshots: kleur: 3.0.3 sisteransi: 1.0.5 + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + property-information@6.5.0: {} property-information@7.1.0: {} - proxy-from-env@1.1.0: {} - pump@3.0.3: dependencies: end-of-stream: 1.4.5 @@ -4883,10 +4973,18 @@ snapshots: quansync@0.2.11: {} + queue@6.0.2: + dependencies: + inherits: 2.0.4 + radix3@1.1.2: {} range-parser@1.2.1: {} + react-is@16.13.1: {} + + react@19.2.0: {} + readdirp@4.1.2: {} recma-build-jsx@1.0.0: @@ -4992,7 +5090,7 @@ snapshots: dependencies: '@types/hast': 3.0.4 '@types/mdast': 4.0.4 - mdast-util-to-hast: 13.2.0 + mdast-util-to-hast: 13.2.1 unified: 11.0.5 vfile: 6.0.3 @@ -5009,6 +5107,8 @@ snapshots: mdast-util-to-markdown: 2.1.2 unified: 11.0.5 + require-from-string@2.0.2: {} + restructure@3.0.2: {} retext-latin@4.0.0: @@ -5064,10 +5164,14 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.53.3 fsevents: 2.3.3 + safe-buffer@5.2.1: {} + safer-buffer@2.1.2: {} sax@1.4.3: {} + scheduler@0.25.0-rc-603e6108-20241029: {} + semver@6.3.1: {} semver@7.7.3: {} @@ -5123,14 +5227,14 @@ snapshots: '@img/sharp-win32-ia32': 0.34.5 '@img/sharp-win32-x64': 0.34.5 - shiki@3.15.0: + shiki@3.17.1: dependencies: - '@shikijs/core': 3.15.0 - '@shikijs/engine-javascript': 3.15.0 - '@shikijs/engine-oniguruma': 3.15.0 - '@shikijs/langs': 3.15.0 - '@shikijs/themes': 3.15.0 - '@shikijs/types': 3.15.0 + '@shikijs/core': 3.17.1 + '@shikijs/engine-javascript': 3.17.1 + '@shikijs/engine-oniguruma': 3.17.1 + '@shikijs/langs': 3.17.1 + '@shikijs/themes': 3.17.1 + '@shikijs/types': 3.17.1 '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 @@ -5138,6 +5242,10 @@ snapshots: dependencies: kolorist: 1.8.0 + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + sisteransi@1.0.5: {} smol-toml@1.5.2: {} @@ -5164,6 +5272,10 @@ snapshots: get-east-asian-width: 1.4.0 strip-ansi: 7.1.2 + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + stringify-entities@4.0.4: dependencies: character-entities-html4: 2.1.0 @@ -5187,6 +5299,8 @@ snapshots: dependencies: inline-style-parser: 0.2.7 + svg-arc-to-cubic-bezier@3.2.0: {} + svgo@3.3.2: dependencies: '@trysound/sax': 0.2.0 @@ -5211,14 +5325,13 @@ snapshots: tapable@2.3.0: {} - tar@6.2.1: + tar@7.5.2: dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 5.0.0 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.1.0 + yallist: 5.0.0 tiny-inflate@1.0.3: {} @@ -5253,7 +5366,7 @@ snapshots: undici-types@7.16.0: {} - undici@6.22.0: {} + undici@7.16.0: {} unicode-properties@1.4.1: dependencies: @@ -5361,6 +5474,12 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 + vite-compatible-readable-stream@3.6.1: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + vite-prerender-plugin@0.5.12(vite@6.4.1(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.2)): dependencies: kolorist: 1.8.0 @@ -5415,7 +5534,7 @@ snapshots: yallist@3.1.1: {} - yallist@4.0.0: {} + yallist@5.0.0: {} yargs-parser@21.1.1: {} @@ -5432,6 +5551,8 @@ snapshots: yoctocolors@2.1.2: {} + yoga-layout@3.2.1: {} + zod-to-json-schema@3.25.0(zod@3.25.76): dependencies: zod: 3.25.76 diff --git a/src/components/ResumeDownloadButton.tsx b/src/components/ResumeDownloadButton.tsx index 389f40a..770c445 100644 --- a/src/components/ResumeDownloadButton.tsx +++ b/src/components/ResumeDownloadButton.tsx @@ -15,7 +15,7 @@ export default function ResumeDownloadButton({ setError(null); try { - const response = await fetch(`/api/resume/pdf?t=${Date.now()}`); + const response = await fetch(`/api/resume/generate?t=${Date.now()}`); if (!response.ok) { throw new Error( diff --git a/src/components/ResumeSettingsModal.tsx b/src/components/ResumeSettingsModal.tsx index 413b234..51e0ffa 100644 --- a/src/components/ResumeSettingsModal.tsx +++ b/src/components/ResumeSettingsModal.tsx @@ -107,7 +107,7 @@ export default function ResumeSettingsModal({ setError(null); try { - const response = await fetch("/api/resume/pdf", { + const response = await fetch("/api/resume/generate", { method: "POST", headers: { "Content-Type": "text/plain", diff --git a/src/pages/api/resume/generate.ts b/src/pages/api/resume/generate.ts new file mode 100644 index 0000000..6306171 --- /dev/null +++ b/src/pages/api/resume/generate.ts @@ -0,0 +1,193 @@ +import type { APIRoute } from "astro"; +import { config } from "../../../config"; +import * as TOML from "@iarna/toml"; +import { renderToStream } from "@react-pdf/renderer"; +import { ResumeDocument } from "../../../pdf/ResumeDocument"; +import React from "react"; + +async function getSimpleIconPath(iconName: string): Promise { + try { + const response = await fetch( + `https://cdn.jsdelivr.net/npm/simple-icons@v10/icons/${iconName.toLowerCase()}.svg`, + ); + if (!response.ok) { + console.warn(`Failed to fetch icon: ${iconName}`); + return ""; + } + const svgContent = await response.text(); + const match = svgContent.match(/d="([^"]+)"/); + return match ? match[1] : ""; + } catch (error) { + console.warn(`Error fetching icon ${iconName}:`, error); + return ""; + } +} + +function getMdiIconPath(iconName: string): string { + const iconMap: { [key: string]: string } = { + "mdi:email": + "M20,8L12,13L4,8V6L12,11L20,6M20,4H4C2.89,4 2,4.89 2,6V18A2,2 0 0,0 4,20H20A2,2 0 0,0 22,18V6C2.89,4 20,4.89 20,4Z", + "mdi:phone": + "M6.62,10.79C8.06,13.62 10.38,15.94 13.21,17.38L15.41,15.18C15.69,14.9 16.08,14.82 16.43,14.93C17.55,15.3 18.75,15.5 20,15.5A1,1 0 0,1 21,16.5V20A1,1 0 0,1 20,21A17,17 0 0,1 3,4A1,1 0 0,1 4,3H7.5A1,1 0 0,1 8.5,4C8.5,5.25 8.7,6.45 9.07,7.57C9.18,7.92 9.1,8.31 8.82,8.59L6.62,10.79Z", + "mdi:download": "M5,20H19V18H5M19,9H15V3H9V9H5L12,16L19,9Z", + "mdi:link": + "M3.9,12C3.9,10.29 5.29,8.9 7,8.9H11V7H7A5,5 0 0,0 2,12A5,5 0 0,0 7,17H11V15.1H7C5.29,15.1 3.9,13.71 3.9,12M8,13H16V11H8V13M17,7H13V8.9H17C18.71,8.9 20.1,10.29 20.1,12C20.1,13.71 18.71,15.1 17,15.1H13V17H17A5,5 0 0,0 22,12A5,5 0 0,0 17,7Z", + }; + return iconMap[iconName] || ""; +} + +interface ResumeData { + basics: { + name: string; + email: string; + phone?: string; + website?: string; + profiles: { + network: string; + username: string; + url: string; + }[]; + }; + layout?: { + left_column?: string[]; + right_column?: string[]; + }; + summary: { + content: string; + }; + experience: { + company: string; + position: string; + location: string; + date: string; + description: string[]; + url?: string; + }[]; + education: { + institution: string; + degree: string; + field: string; + date: string; + details?: string[]; + }[]; + skills: { + name: string; + level: number; + }[]; + volunteer: { + organization: string; + position: string; + date: string; + }[]; + awards: { + title: string; + organization: string; + date: string; + description?: string; + }[]; +} + +const fetchProfileIcons = async (profiles: any[]) => { + const profileIcons: { [key: string]: string } = {}; + if (profiles) { + for (const profile of profiles) { + const iconName = profile.network.toLowerCase(); + profileIcons[profile.network] = await getSimpleIconPath(iconName); + } + } + return profileIcons; +}; + +const generatePDF = async (data: ResumeData) => { + const resumeConfig = config.resumeConfig; + + const profileIcons = await fetchProfileIcons(data.basics.profiles); + const icons = { + ...profileIcons, + email: getMdiIconPath("mdi:email"), + phone: getMdiIconPath("mdi:phone"), + }; + + return await renderToStream( + ResumeDocument({ data, resumeConfig, icons }) + ); +}; + +export const GET: APIRoute = async ({ request }) => { + try { + if (!config.resumeConfig.tomlFile || !config.resumeConfig.tomlFile.trim()) { + return new Response("Resume not configured", { status: 404 }); + } + + let tomlContent: string; + + if (config.resumeConfig.tomlFile.startsWith("/")) { + const url = new URL(request.url); + const baseUrl = `${url.protocol}//${url.host}`; + const response = await fetch(`${baseUrl}${config.resumeConfig.tomlFile}`); + + if (!response.ok) { + throw new Error( + `Failed to fetch resume: ${response.status} ${response.statusText}`, + ); + } + + tomlContent = await response.text(); + } else { + tomlContent = config.resumeConfig.tomlFile; + } + + const resumeData: ResumeData = TOML.parse( + tomlContent, + ) as unknown as ResumeData; + + const stream = await generatePDF(resumeData); + + return new Response(stream as any, { + headers: { + "Content-Type": "application/pdf", + "Content-Disposition": `attachment; filename="Atridad_Lahiji_Resume.pdf"`, + }, + }); + } catch (error) { + console.error("Error generating PDF:", error); + return new Response("Error generating PDF", { status: 500 }); + } +}; + +export const POST: APIRoute = async ({ request }) => { + try { + const tomlContent = await request.text(); + + if (!tomlContent.trim()) { + return new Response("TOML content is required", { status: 400 }); + } + + let resumeData: ResumeData; + try { + resumeData = TOML.parse(tomlContent) as unknown as ResumeData; + } catch (parseError) { + return new Response( + `Invalid TOML format: ${parseError instanceof Error ? parseError.message : "Unknown error"}`, + { status: 400 }, + ); + } + + if (!resumeData.basics?.name) { + return new Response("Resume must include basics.name", { status: 400 }); + } + + const stream = await generatePDF(resumeData); + const filename = `${resumeData.basics.name.replace(/[^a-zA-Z0-9]/g, "_")}_Resume.pdf`; + + return new Response(stream as any, { + headers: { + "Content-Type": "application/pdf", + "Content-Disposition": `attachment; filename="${filename}"`, + }, + }); + } catch (error) { + console.error("Error generating PDF:", error); + return new Response("Error generating PDF", { status: 500 }); + } +}; diff --git a/src/pages/api/resume/pdf.ts b/src/pages/api/resume/pdf.ts deleted file mode 100644 index 106ee25..0000000 --- a/src/pages/api/resume/pdf.ts +++ /dev/null @@ -1,498 +0,0 @@ -import type { APIRoute } from "astro"; -import { chromium } from "playwright"; -import { config } from "../../../config"; -import * as TOML from "@iarna/toml"; - -// Helper function to fetch and return SVG icon from Simple Icons CDN -async function getSimpleIcon(iconName: string): Promise { - try { - const response = await fetch( - `https://cdn.jsdelivr.net/npm/simple-icons@v10/icons/${iconName.toLowerCase()}.svg`, - ); - if (!response.ok) { - console.warn(`Failed to fetch icon: ${iconName}`); - return ""; - } - const svgContent = await response.text(); - return svgContent.replace( - "', - "mdi:phone": - '', - "mdi:download": - '', - "mdi:link": - '', - }; - return iconMap[iconName] || ""; -} - -interface ResumeData { - basics: { - name: string; - email: string; - phone?: string; - website?: string; - profiles: { - network: string; - username: string; - url: string; - }[]; - }; - layout?: { - left_column?: string[]; - right_column?: string[]; - }; - summary: { - content: string; - }; - experience: { - company: string; - position: string; - location: string; - date: string; - description: string[]; - url?: string; - }[]; - education: { - institution: string; - degree: string; - field: string; - date: string; - details?: string[]; - }[]; - skills: { - name: string; - level: number; - }[]; - volunteer: { - organization: string; - position: string; - date: string; - }[]; - awards: { - title: string; - organization: string; - date: string; - description?: string; - }[]; -} - -// Template helper functions -const createSection = ( - title: string, - content: string, - spacing = "space-y-3", -) => ` -
-

- ${title} -

-
- ${content} -
-
-`; - -const createExperienceItem = (exp: any) => ` -
-

${exp.position}

-
- ${exp.company} - - ${exp.date} - - ${exp.location} -
-
    - ${exp.description.map((item: string) => `
  • ${item}
  • `).join("")} -
-
-`; - -const createSkillItem = (skill: any) => { - const progressValue = skill.level * 20; - return ` -
-
- ${skill.name} - ${skill.level}/5 -
-
-
-
-
- `; -}; - -const createEducationItem = (edu: any) => { - const detailsList = edu.details - ? edu.details - .map((detail: string) => `
  • ${detail}
  • `) - .join("") - : ""; - - return ` -
    -

    ${edu.institution}

    -
    - ${edu.degree} in ${edu.field} - - ${edu.date} -
    - ${detailsList ? `
      ${detailsList}
    ` : ""} -
    - `; -}; - -const createVolunteerItem = (vol: any) => ` -
    -

    ${vol.organization}

    -
    - ${vol.position} - - ${vol.date} -
    -
    -`; - -const createAwardItem = (award: any) => ` -
    -

    ${award.title}

    -
    - ${award.organization} - - ${award.date} -
    - ${award.description ? `
    ${award.description}
    ` : ""} -
    -`; - -const createHead = (name: string) => ` - - - - ${name} - Resume - - - -`; - -const createHeader = ( - basics: any, - emailIcon: string, - phoneIcon: string, - profileIcons: { [key: string]: string }, -) => ` -
    -

    ${basics.name}

    -
    - ${basics.email ? `
    ${emailIcon} ${basics.email}
    ` : ""} - ${basics.phone ? `
    ${phoneIcon} ${basics.phone}
    ` : ""} - ${ - basics.profiles - ?.map((profile: any) => { - const icon = profileIcons[profile.network] || ""; - const displayUrl = profile.url - .replace(/^https?:\/\//, "") - .replace(/\/$/, ""); - return `
    ${icon} ${displayUrl}
    `; - }) - .join("") || "" - } -
    -
    -`; - -const createSummarySection = (summary: any, resumeConfig: any) => { - if ( - !summary || - !summary.content || - resumeConfig.sections.summary?.enabled === false - ) - return ""; - - return ` -
    -

    - ${resumeConfig.sections.summary?.title || "Summary"} -

    -
    ${summary.content}
    -
    - `; -}; - -const createColumnSections = ( - sectionNames: string[], - sections: { [key: string]: string }, - resumeConfig: any, -) => { - const sectionConfig = { - experience: { - title: resumeConfig.sections.experience?.title || "Experience", - enabled: resumeConfig.sections.experience?.enabled !== false, - spacing: "space-y-3", - }, - skills: { - title: resumeConfig.sections.skills?.title || "Skills", - enabled: resumeConfig.sections.skills?.enabled !== false, - spacing: "space-y-1", - }, - education: { - title: resumeConfig.sections.education?.title || "Education", - enabled: resumeConfig.sections.education?.enabled !== false, - spacing: "space-y-3", - }, - volunteer: { - title: resumeConfig.sections.volunteer?.title || "Volunteer Work", - enabled: resumeConfig.sections.volunteer?.enabled !== false, - spacing: "space-y-2", - }, - awards: { - title: resumeConfig.sections.awards?.title || "Awards & Recognition", - enabled: resumeConfig.sections.awards?.enabled !== false, - spacing: "space-y-2", - }, - }; - - return sectionNames - .map((sectionName) => { - const config = sectionConfig[sectionName as keyof typeof sectionConfig]; - const content = sections[sectionName]; - - // Skip if section doesn't exist in config, has no content, or is disabled - if (!config || !content || content.trim() === "" || !config.enabled) - return ""; - - return createSection(config.title, content, config.spacing); - }) - .filter((section) => section !== "") - .join(""); -}; - -const fetchProfileIcons = async (profiles: any[]) => { - const profileIcons: { [key: string]: string } = {}; - if (profiles) { - for (const profile of profiles) { - const iconName = profile.network.toLowerCase(); - profileIcons[profile.network] = await getSimpleIcon(iconName); - } - } - return profileIcons; -}; - -const generateResumeHTML = async (data: ResumeData): Promise => { - const resumeConfig = config.resumeConfig; - // Use layout from TOML data, fallback to site config, then to default - const layout = data.layout - ? { - leftColumn: data.layout.left_column || [ - "experience", - "volunteer", - "awards", - ], - rightColumn: data.layout.right_column || ["skills", "education"], - } - : resumeConfig.layout || { - leftColumn: ["experience", "volunteer", "awards"], - rightColumn: ["skills", "education"], - }; - - // Pre-fetch icons - const profileIcons = await fetchProfileIcons(data.basics.profiles); - const emailIcon = getMdiIcon("mdi:email"); - const phoneIcon = getMdiIcon("mdi:phone"); - - // Generate section content - const sections = { - experience: Array.isArray(data.experience) - ? data.experience.map(createExperienceItem).join("") - : "", - skills: Array.isArray(data.skills) - ? data.skills.map(createSkillItem).join("") - : "", - education: Array.isArray(data.education) - ? data.education.map(createEducationItem).join("") - : "", - volunteer: Array.isArray(data.volunteer) - ? data.volunteer.map(createVolunteerItem).join("") - : "", - awards: Array.isArray(data.awards) - ? data.awards.map(createAwardItem).join("") - : "", - }; - - return ` - - - ${createHead(data.basics.name)} - -
    - ${createHeader(data.basics, emailIcon, phoneIcon, profileIcons)} - ${createSummarySection(data.summary, resumeConfig)} -
    -
    - ${createColumnSections(layout.leftColumn ?? [], sections, resumeConfig)} -
    -
    - ${createColumnSections(layout.rightColumn ?? [], sections, resumeConfig)} -
    -
    -
    - - - `; -}; - -async function generatePDFFromToml(tomlContent: string): Promise { - const resumeData: ResumeData = TOML.parse( - tomlContent, - ) as unknown as ResumeData; - const htmlContent = await generateResumeHTML(resumeData); - - const browser = await chromium.launch({ - headless: true, - executablePath: - process.env.PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH || - (process.env.NODE_ENV === "production" - ? "/usr/bin/chromium-browser" - : undefined), - args: [ - "--no-sandbox", - "--disable-setuid-sandbox", - "--disable-dev-shm-usage", - "--disable-gpu", - "--disable-web-security", - "--disable-features=VizDisplayCompositor", - ], - }); - - const page = await browser.newPage(); - await page.setContent(htmlContent, { waitUntil: "networkidle" }); - - const pdfBuffer = await page.pdf({ - format: "A4", - margin: { - top: "0.2in", - bottom: "0.2in", - left: "0.2in", - right: "0.2in", - }, - printBackground: true, - scale: 0.9, - }); - - await browser.close(); - return pdfBuffer; -} - -export const GET: APIRoute = async ({ request }) => { - try { - if (!config.resumeConfig.tomlFile || !config.resumeConfig.tomlFile.trim()) { - return new Response("Resume not configured", { status: 404 }); - } - - let tomlContent: string; - - // Check if tomlFile is a path (starts with /) or raw content - if (config.resumeConfig.tomlFile.startsWith("/")) { - // It's a file path - fetch it - const url = new URL(request.url); - const baseUrl = `${url.protocol}//${url.host}`; - - const response = await fetch(`${baseUrl}${config.resumeConfig.tomlFile}`); - - if (!response.ok) { - throw new Error( - `Failed to fetch resume: ${response.status} ${response.statusText}`, - ); - } - - tomlContent = await response.text(); - } else { - // It's raw TOML content - tomlContent = config.resumeConfig.tomlFile; - } - - const pdfBuffer = await generatePDFFromToml(tomlContent); - - return new Response(pdfBuffer, { - headers: { - "Content-Type": "application/pdf", - "Content-Disposition": `attachment; filename="Atridad_Lahiji_Resume.pdf"`, - "Cache-Control": "no-cache, no-store, must-revalidate", - Pragma: "no-cache", - Expires: "0", - }, - }); - } catch (error) { - console.error("Error generating PDF:", error); - return new Response("Error generating PDF", { status: 500 }); - } -}; - -export const POST: APIRoute = async ({ request }) => { - try { - const tomlContent = await request.text(); - - if (!tomlContent.trim()) { - return new Response("TOML content is required", { status: 400 }); - } - - // Validate TOML content - let resumeData: ResumeData; - try { - resumeData = TOML.parse(tomlContent) as unknown as ResumeData; - } catch (parseError) { - return new Response( - `Invalid TOML format: ${parseError instanceof Error ? parseError.message : "Unknown error"}`, - { status: 400 }, - ); - } - - // Basic validation - if (!resumeData.basics?.name) { - return new Response("Resume must include basics.name", { status: 400 }); - } - - const pdfBuffer = await generatePDFFromToml(tomlContent); - - const filename = `${resumeData.basics.name.replace(/[^a-zA-Z0-9]/g, "_")}_Resume.pdf`; - - return new Response(pdfBuffer, { - headers: { - "Content-Type": "application/pdf", - "Content-Disposition": `attachment; filename="${filename}"`, - "Cache-Control": "no-cache, no-store, must-revalidate", - Pragma: "no-cache", - Expires: "0", - }, - }); - } catch (error) { - console.error("Error generating PDF:", error); - return new Response("Error generating PDF", { status: 500 }); - } -}; diff --git a/src/pdf/ResumeDocument.tsx b/src/pdf/ResumeDocument.tsx new file mode 100644 index 0000000..5afcab4 --- /dev/null +++ b/src/pdf/ResumeDocument.tsx @@ -0,0 +1,333 @@ +/** @jsxImportSource react */ +import React from "react"; +import { + Document, + Page, + Text, + View, + StyleSheet, + Link, + Svg, + Path, + Font, +} from "@react-pdf/renderer"; + +const styles = StyleSheet.create({ + page: { + padding: 24, + fontFamily: "Helvetica", + fontSize: 8, + lineHeight: 1.3, + color: "#111827", + }, + header: { + marginBottom: 10, + paddingBottom: 6, + borderBottomWidth: 1, + borderBottomColor: "#D1D5DB", + alignItems: "center", + flexDirection: "column", + display: "flex", + }, + name: { + fontSize: 16, + fontWeight: "bold", + marginBottom: 6, + textAlign: "center", + }, + contactRow: { + flexDirection: "row", + justifyContent: "center", + alignItems: "center", + flexWrap: "wrap", + color: "#4B5563", + fontSize: 8, + marginTop: 2, + }, + contactItem: { + flexDirection: "row", + alignItems: "center", + marginHorizontal: 8, + marginBottom: 2, + }, + icon: { + width: 9, + height: 9, + marginRight: 4, + }, + section: { + marginBottom: 8, + }, + sectionTitle: { + fontSize: 10, + fontWeight: "bold", + borderBottomWidth: 1, + borderBottomColor: "#D1D5DB", + marginBottom: 4, + paddingBottom: 2, + }, + columns: { + flexDirection: "row", + }, + column: { + flex: 1, + marginLeft: 8, + marginRight: 8, + }, + // Experience + experienceItem: { + marginBottom: 6, + paddingLeft: 8, + borderLeftWidth: 2, + borderLeftColor: "#2563EB", + }, + itemTitle: { + fontSize: 9, + fontWeight: "bold", + marginBottom: 1, + }, + itemSubtitle: { + fontSize: 8, + color: "#4B5563", + marginBottom: 1, + }, + list: { + marginLeft: 8, + }, + listItem: { + flexDirection: "row", + marginBottom: 1, + }, + bullet: { + width: 8, + fontSize: 8, + marginRight: 2, + }, + listContent: { + flex: 1, + color: "#374151", + fontSize: 8, + }, + // Skills + skillItem: { + marginBottom: 2, + }, + skillHeader: { + flexDirection: "row", + justifyContent: "space-between", + marginBottom: 1, + }, + progressBarBg: { + height: 4, + backgroundColor: "#E5E7EB", // bg-gray-200 + borderRadius: 2, + }, + progressBarFill: { + height: 4, + backgroundColor: "#2563EB", // bg-blue-600 + borderRadius: 2, + }, + // Education + educationItem: { + marginBottom: 6, + paddingLeft: 8, + borderLeftWidth: 2, + borderLeftColor: "#16A34A", + }, + // Volunteer + volunteerItem: { + marginBottom: 4, + paddingLeft: 8, + borderLeftWidth: 2, + borderLeftColor: "#9333EA", + }, + // Awards + awardItem: { + marginBottom: 4, + paddingLeft: 8, + borderLeftWidth: 2, + borderLeftColor: "#CA8A04", + }, + summary: { + marginBottom: 8, + color: "#374151", + fontSize: 8, + }, +}); + +const Icon = ({ path, color = "currentColor" }: { path: string; color?: string }) => ( + + + +); + +interface ResumeDocumentProps { + data: any; + resumeConfig: any; + icons: { [key: string]: string }; // Map of icon name to SVG path +} + +export const ResumeDocument = ({ data, resumeConfig, icons }: ResumeDocumentProps) => { + const layout = data.layout + ? { + leftColumn: data.layout.left_column || ["experience", "volunteer", "awards"], + rightColumn: data.layout.right_column || ["skills", "education"], + } + : resumeConfig.layout || { + leftColumn: ["experience", "volunteer", "awards"], + rightColumn: ["skills", "education"], + }; + + const renderSectionContent = (sectionName: string) => { + switch (sectionName) { + case "experience": + return data.experience?.map((exp: any, i: number) => ( + + {exp.position} + + {exp.company} • {exp.date} • {exp.location} + + + {exp.description?.map((desc: string, j: number) => ( + + + {desc} + + ))} + + + )); + case "skills": + return data.skills?.map((skill: any, i: number) => ( + + + {skill.name} + {skill.level}/5 + + + + + + )); + case "education": + return data.education?.map((edu: any, i: number) => ( + + {edu.institution} + + {edu.degree} in {edu.field} • {edu.date} + + {edu.details && ( + + {edu.details.map((detail: string, j: number) => ( + + + {detail} + + ))} + + )} + + )); + case "volunteer": + return data.volunteer?.map((vol: any, i: number) => ( + + {vol.organization} + + {vol.position} • {vol.date} + + + )); + case "awards": + return data.awards?.map((award: any, i: number) => ( + + {award.title} + + {award.organization} • {award.date} + + {award.description && ( + {award.description} + )} + + )); + default: + return null; + } + }; + + const renderColumn = (sectionNames: string[]) => { + return sectionNames.map((name) => { + const config = resumeConfig.sections[name]; + const content = renderSectionContent(name); + + // Check if section has content (simple check) + const hasContent = data[name] && data[name].length > 0; + + if (!config || !hasContent || config.enabled === false) return null; + + return ( + + {config.title} + {content} + + ); + }); + }; + + return ( + + + {/* Header */} + + {data.basics.name} + + {data.basics.email && ( + + {icons["email"] && } + {data.basics.email} + + )} + {data.basics.phone && ( + + {icons["phone"] && } + {data.basics.phone} + + )} + {data.basics.profiles?.map((profile: any, i: number) => ( + + {icons[profile.network] && } + + {profile.url.replace(/^https?:\/\//, "").replace(/\/$/, "")} + + + ))} + + + + {/* Summary */} + {data.summary && resumeConfig.sections.summary?.enabled !== false && ( + + + {resumeConfig.sections.summary?.title || "Summary"} + + {data.summary.content} + + )} + + {/* Columns */} + + + {renderColumn(layout.leftColumn)} + + + {renderColumn(layout.rightColumn)} + + + + + ); +};