From a64e2a8a44396b36512c398780826ba559c1d992 Mon Sep 17 00:00:00 2001 From: Elias Almqvist Date: Thu, 27 Feb 2025 22:31:32 -0800 Subject: [PATCH] blog stuff --- content/essays/example.mdx | 15 + package.json | 6 + pnpm-lock.yaml | 556 +++++++++++++++++++++++++++++++------ src/app/[...dir]/page.tsx | 68 ++++- src/app/layout.tsx | 8 + src/app/posts/page.tsx | 60 ++++ 6 files changed, 619 insertions(+), 94 deletions(-) create mode 100644 content/essays/example.mdx create mode 100644 src/app/posts/page.tsx diff --git a/content/essays/example.mdx b/content/essays/example.mdx new file mode 100644 index 0000000..db2b89a --- /dev/null +++ b/content/essays/example.mdx @@ -0,0 +1,15 @@ +--- +title: "Example Essay with Math" +createdAt: "2024-03-20" +updatedAt: "2024-03-20" +--- + +# Example Essay with Math + +This is an example of an essay with both inline math $E = mc^2$ and block math: + +$$ +\frac{-b \pm \sqrt{b^2 - 4ac}}{2a} +$$ + +You can write normal markdown and **MDX** content here. \ No newline at end of file diff --git a/package.json b/package.json index fcee09c..7e0a7a6 100644 --- a/package.json +++ b/package.json @@ -28,18 +28,24 @@ "clsx": "^2.1.0", "cmdk": "^1.0.0", "geist": "^1.3.0", + "gray-matter": "^4.0.3", + "katex": "^0.16.21", "lucide-react": "^0.363.0", "next": "14.1.4", + "next-mdx-remote": "^5.0.0", "next-themes": "^0.3.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-icons": "^5.0.1", + "rehype-katex": "^7.0.1", + "remark-math": "^6.0.0", "tailwind-merge": "^2.2.2", "tailwindcss-animate": "^1.0.7", "three": "^0.163.0", "zustand": "^4.5.2" }, "devDependencies": { + "@types/katex": "^0.16.7", "@types/node": "^20.11.30", "@types/react": "^18.2.73", "@types/react-dom": "^18.2.23", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 08bd1dd..881b73e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,22 +16,22 @@ importers: version: 3.0.1(@types/react@18.2.73)(react@18.2.0) '@next/mdx': specifier: ^14.1.4 - version: 14.1.4(@mdx-js/loader@3.0.1)(@mdx-js/react@3.0.1) + version: 14.1.4(@mdx-js/loader@3.0.1(webpack@5.91.0))(@mdx-js/react@3.0.1(@types/react@18.2.73)(react@18.2.0)) '@radix-ui/react-dialog': specifier: ^1.0.5 - version: 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@radix-ui/react-icons': specifier: ^1.3.0 version: 1.3.0(react@18.2.0) '@radix-ui/react-separator': specifier: ^1.0.3 - version: 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@radix-ui/react-slot': specifier: ^1.0.2 version: 1.0.2(@types/react@18.2.73)(react@18.2.0) '@react-three/fiber': specifier: ^8.16.1 - version: 8.16.1(react-dom@18.2.0)(react@18.2.0)(three@0.163.0) + version: 8.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(three@0.163.0) '@tailwindcss/typography': specifier: ^0.5.12 version: 0.5.12(tailwindcss@3.4.3) @@ -43,10 +43,10 @@ importers: version: 0.162.0 '@vercel/analytics': specifier: ^1.2.2 - version: 1.2.2(next@14.1.4)(react@18.2.0) + version: 1.2.2(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0) '@vercel/speed-insights': specifier: ^1.0.10 - version: 1.0.10(next@14.1.4)(react@18.2.0) + version: 1.0.10(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0) class-variance-authority: specifier: ^0.7.0 version: 0.7.0 @@ -55,19 +55,28 @@ importers: version: 2.1.0 cmdk: specifier: ^1.0.0 - version: 1.0.0(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + version: 1.0.0(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) geist: specifier: ^1.3.0 - version: 1.3.0(next@14.1.4) + version: 1.3.0(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)) + gray-matter: + specifier: ^4.0.3 + version: 4.0.3 + katex: + specifier: ^0.16.21 + version: 0.16.21 lucide-react: specifier: ^0.363.0 version: 0.363.0(react@18.2.0) next: specifier: 14.1.4 - version: 14.1.4(react-dom@18.2.0)(react@18.2.0) + version: 14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + next-mdx-remote: + specifier: ^5.0.0 + version: 5.0.0(@types/react@18.2.73)(react@18.2.0) next-themes: specifier: ^0.3.0 - version: 0.3.0(react-dom@18.2.0)(react@18.2.0) + version: 0.3.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: ^18.2.0 version: 18.2.0 @@ -77,6 +86,12 @@ importers: react-icons: specifier: ^5.0.1 version: 5.0.1(react@18.2.0) + rehype-katex: + specifier: ^7.0.1 + version: 7.0.1 + remark-math: + specifier: ^6.0.0 + version: 6.0.0 tailwind-merge: specifier: ^2.2.2 version: 2.2.2 @@ -90,6 +105,9 @@ importers: specifier: ^4.5.2 version: 4.5.2(@types/react@18.2.73)(react@18.2.0) devDependencies: + '@types/katex': + specifier: ^0.16.7 + version: 0.16.7 '@types/node': specifier: ^20.11.30 version: 20.11.30 @@ -128,6 +146,14 @@ packages: resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} engines: {node: '>=10'} + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + '@babel/runtime@7.24.1': resolution: {integrity: sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==} engines: {node: '>=6.9.0'} @@ -533,6 +559,9 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/katex@0.16.7': + resolution: {integrity: sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==} + '@types/mdast@4.0.3': resolution: {integrity: sha512-LsjtqsyF+d2/yFOYaN22dHZI1Cpwkrj+g06G8+qtUKlhovPW89YhqSnfKtMbkgmEtYpH2gydRNULd6y8mciAFg==} @@ -696,6 +725,7 @@ packages: acorn-import-assertions@1.9.0: resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==} + deprecated: package has been renamed to acorn-import-attributes peerDependencies: acorn: ^8 @@ -743,6 +773,9 @@ packages: arg@5.0.2: resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -936,6 +969,10 @@ packages: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -1044,6 +1081,10 @@ packages: resolution: {integrity: sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==} engines: {node: '>=10.13.0'} + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + es-abstract@1.23.2: resolution: {integrity: sha512-60s3Xv2T2p1ICykc7c+DNDPLDMm9t4QxCOUU0K9JxiLjM3C1zB9YVdN7tjxrFd4+AkZ8CdX1ovUga4P2+1e+/w==} engines: {node: '>= 0.4'} @@ -1175,6 +1216,11 @@ packages: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + esquery@1.5.0: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} engines: {node: '>=0.10'} @@ -1217,6 +1263,10 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} @@ -1351,6 +1401,10 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + gray-matter@4.0.3: + resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} + engines: {node: '>=6.0'} + has-bigints@1.0.2: resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} @@ -1377,15 +1431,39 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + hast-util-from-dom@5.0.1: + resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==} + + hast-util-from-html-isomorphic@2.0.0: + resolution: {integrity: sha512-zJfpXq44yff2hmE0XmwEOzdWin5xwH+QIhMLOScpX91e/NSGPsAzNCvLQDIEPyO2TXi+lBmU6hjLIhV8MwP2kw==} + + hast-util-from-html@2.0.3: + resolution: {integrity: sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==} + + hast-util-from-parse5@8.0.3: + resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==} + + hast-util-is-element@3.0.0: + resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==} + + hast-util-parse-selector@4.0.0: + resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} + hast-util-to-estree@3.1.0: resolution: {integrity: sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==} hast-util-to-jsx-runtime@2.3.0: resolution: {integrity: sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==} + hast-util-to-text@4.0.2: + resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==} + hast-util-whitespace@3.0.0: resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + hastscript@9.0.1: + resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -1463,6 +1541,10 @@ packages: is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -1576,6 +1658,10 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + js-yaml@4.1.0: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true @@ -1600,9 +1686,17 @@ packages: resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} engines: {node: '>=4.0'} + katex@0.16.21: + resolution: {integrity: sha512-XvqR7FgOHtWupfMiigNzmh+MgUVmDGU2kXZm899ZkPfcuoPuFxyHmXsgATDpFZDAXCI8tvinaVcDo8PIIJSo4A==} + hasBin: true + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + language-subtag-registry@0.3.22: resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} @@ -1669,6 +1763,9 @@ packages: mdast-util-from-markdown@2.0.0: resolution: {integrity: sha512-n7MTOr/z+8NAX/wmhhDji8O3bRvPTV/U0oTCaZJkjhPSKTPhS3xufVhKGF8s1pJ7Ox4QgoIU7KHseh09S+9rTA==} + mdast-util-math@3.0.0: + resolution: {integrity: sha512-Tl9GBNeG/AhJnQM221bJR2HPvLOSnLE/T9cJI9tlc6zwQk2nPk/4f0cHkOdEixQPC/j8UtKDdITswvLAy1OZ1w==} + mdast-util-mdx-expression@2.0.0: resolution: {integrity: sha512-fGCu8eWdKUKNu5mohVGkhBXCXGnOTLuFqOvGMvdikr+J1w7lDJgxThOKpwRWzzbyXAU2hhSwsmssOY4yTokluw==} @@ -1706,6 +1803,9 @@ packages: micromark-core-commonmark@2.0.0: resolution: {integrity: sha512-jThOz/pVmAYUtkroV3D5c1osFXAMv9e0ypGDOIZuCeAe91/sD6BoE2Sjzt30yuXtwOYUmySOhMas/PVyh02itA==} + micromark-extension-math@3.1.0: + resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} + micromark-extension-mdx-expression@3.0.0: resolution: {integrity: sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==} @@ -1837,6 +1937,12 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + next-mdx-remote@5.0.0: + resolution: {integrity: sha512-RNNbqRpK9/dcIFZs/esQhuLA8jANqlH694yqoDBK8hkVdJUndzzGmnPHa2nyi90N4Z9VmzuSWNRpr5ItT3M7xQ==} + engines: {node: '>=14', npm: '>=7'} + peerDependencies: + react: '>=16' + next-themes@0.3.0: resolution: {integrity: sha512-/QHIrsYpd6Kfk7xakK4svpDI5mmXP0gfvCoJdGpZQ2TOrQZmsW0QxjaiLn8wbIKjtm4BTSqLoix4lxYYOnLJ/w==} peerDependencies: @@ -1930,6 +2036,9 @@ packages: parse-entities@4.0.1: resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} + parse5@7.2.1: + resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2034,6 +2143,9 @@ packages: property-information@6.4.1: resolution: {integrity: sha512-OHYtXfu5aI2sS2LWFSN5rgJjrQ4pCy8i1jubJLe2QvMF8JJ++HXTUIVWFLfXJoaOfvYYjk2SN8J2wFUWIGXT4w==} + property-information@7.0.0: + resolution: {integrity: sha512-7D/qOz/+Y4X/rzSB6jKxKUsQnphO046ei8qxG59mtM3RG3DHgTK81HrxrmoDVINJb8NKT5ZsRbwHvQ6B68Iyhg==} + punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2121,6 +2233,12 @@ packages: resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} + rehype-katex@7.0.1: + resolution: {integrity: sha512-OiM2wrZ/wuhKkigASodFoo8wimG3H12LWQaH8qSPVJn9apWKFSH3YOCtbKpBorTVw/eI7cuT21XBbvwEswbIOA==} + + remark-math@6.0.0: + resolution: {integrity: sha512-MMqgnP74Igy+S3WwnhQ7kqGlEerTETXMvJhrUzDikVZ2/uogJCb+WHUg97hK9/jcfc0dkD73s3LN8zU49cTEtA==} + remark-mdx@3.0.1: resolution: {integrity: sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==} @@ -2177,6 +2295,10 @@ packages: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} + section-matter@1.0.0: + resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} + engines: {node: '>=4'} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -2238,6 +2360,9 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} @@ -2276,6 +2401,10 @@ packages: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} + strip-bom-string@1.0.0: + resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==} + engines: {node: '>=0.10.0'} + strip-bom@3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -2439,6 +2568,12 @@ packages: unified@11.0.4: resolution: {integrity: sha512-apMPnyLjAX+ty4OrNap7yumyVAMlKx5IWU2wlzzUdYJO9A8f1p9m/gywF/GM2ZDFcjQPrx59Mc90KwmxsoklxQ==} + unist-util-find-after@5.0.0: + resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==} + + unist-util-is@5.2.1: + resolution: {integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==} + unist-util-is@6.0.0: resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==} @@ -2451,9 +2586,15 @@ packages: unist-util-remove-position@5.0.0: resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==} + unist-util-remove@3.1.1: + resolution: {integrity: sha512-kfCqZK5YVY5yEa89tvpl7KnBBHu2c6CzMkqHUrlOqaRgGOMp0sMvwWOVrbAtj03KhovQB7i96Gda72v/EFE0vw==} + unist-util-stringify-position@4.0.0: resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + unist-util-visit-parents@5.1.3: + resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==} + unist-util-visit-parents@6.0.1: resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==} @@ -2497,6 +2638,12 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + vfile-location@5.0.3: + resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} + + vfile-matter@5.0.0: + resolution: {integrity: sha512-jhPSqlj8hTSkTXOqyxbUeZAFFVq/iwu/jukcApEqc/7DOidaAth6rDc0Zgg0vWpzUnWkwFP7aK28l6nBmxMqdQ==} + vfile-message@4.0.2: resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==} @@ -2507,6 +2654,9 @@ packages: resolution: {integrity: sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==} engines: {node: '>=10.13.0'} + web-namespaces@2.0.1: + resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==} + webpack-sources@3.2.3: resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} engines: {node: '>=10.13.0'} @@ -2597,6 +2747,14 @@ snapshots: '@alloc/quick-lru@5.2.0': {} + '@babel/code-frame@7.26.2': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.0.0 + + '@babel/helper-validator-identifier@7.25.9': {} + '@babel/runtime@7.24.1': dependencies: regenerator-runtime: 0.14.1 @@ -2715,11 +2873,12 @@ snapshots: dependencies: glob: 10.3.10 - '@next/mdx@14.1.4(@mdx-js/loader@3.0.1)(@mdx-js/react@3.0.1)': + '@next/mdx@14.1.4(@mdx-js/loader@3.0.1(webpack@5.91.0))(@mdx-js/react@3.0.1(@types/react@18.2.73)(react@18.2.0))': dependencies: + source-map: 0.7.4 + optionalDependencies: '@mdx-js/loader': 3.0.1(webpack@5.91.0) '@mdx-js/react': 3.0.1(@types/react@18.2.73)(react@18.2.0) - source-map: 0.7.4 '@next/swc-darwin-arm64@14.1.4': optional: true @@ -2770,66 +2929,72 @@ snapshots: '@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.73)(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 - '@types/react': 18.2.73 react: 18.2.0 + optionalDependencies: + '@types/react': 18.2.73 '@radix-ui/react-context@1.0.1(@types/react@18.2.73)(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 - '@types/react': 18.2.73 react: 18.2.0 + optionalDependencies: + '@types/react': 18.2.73 - '@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)': + '@radix-ui/react-dialog@1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 '@radix-ui/primitive': 1.0.1 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0) '@radix-ui/react-context': 1.0.1(@types/react@18.2.73)(react@18.2.0) - '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.73)(react@18.2.0) - '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-focus-scope': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@radix-ui/react-id': 1.0.1(@types/react@18.2.73)(react@18.2.0) - '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@radix-ui/react-slot': 1.0.2(@types/react@18.2.73)(react@18.2.0) '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.73)(react@18.2.0) - '@types/react': 18.2.73 - '@types/react-dom': 18.2.23 aria-hidden: 1.2.4 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-remove-scroll: 2.5.5(@types/react@18.2.73)(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.73 + '@types/react-dom': 18.2.23 - '@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)': + '@radix-ui/react-dismissable-layer@1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 '@radix-ui/primitive': 1.0.1 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0) '@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.73)(react@18.2.0) - '@types/react': 18.2.73 - '@types/react-dom': 18.2.23 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.73 + '@types/react-dom': 18.2.23 '@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.73)(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 - '@types/react': 18.2.73 react: 18.2.0 + optionalDependencies: + '@types/react': 18.2.73 - '@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)': + '@radix-ui/react-focus-scope@1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0) - '@types/react': 18.2.73 - '@types/react-dom': 18.2.23 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.73 + '@types/react-dom': 18.2.23 '@radix-ui/react-icons@1.3.0(react@18.2.0)': dependencies: @@ -2839,80 +3004,90 @@ snapshots: dependencies: '@babel/runtime': 7.24.1 '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.73)(react@18.2.0) - '@types/react': 18.2.73 react: 18.2.0 + optionalDependencies: + '@types/react': 18.2.73 - '@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)': + '@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.73 - '@types/react-dom': 18.2.23 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.73 + '@types/react-dom': 18.2.23 - '@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)': + '@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0) '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.73)(react@18.2.0) - '@types/react': 18.2.73 - '@types/react-dom': 18.2.23 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.73 + '@types/react-dom': 18.2.23 - '@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)': + '@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 '@radix-ui/react-slot': 1.0.2(@types/react@18.2.73)(react@18.2.0) - '@types/react': 18.2.73 - '@types/react-dom': 18.2.23 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.73 + '@types/react-dom': 18.2.23 - '@radix-ui/react-separator@1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0)': + '@radix-ui/react-separator@1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.73 - '@types/react-dom': 18.2.23 + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.73 + '@types/react-dom': 18.2.23 '@radix-ui/react-slot@1.0.2(@types/react@18.2.73)(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.73)(react@18.2.0) - '@types/react': 18.2.73 react: 18.2.0 + optionalDependencies: + '@types/react': 18.2.73 '@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.73)(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 - '@types/react': 18.2.73 react: 18.2.0 + optionalDependencies: + '@types/react': 18.2.73 '@radix-ui/react-use-controllable-state@1.0.1(@types/react@18.2.73)(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0) - '@types/react': 18.2.73 react: 18.2.0 + optionalDependencies: + '@types/react': 18.2.73 '@radix-ui/react-use-escape-keydown@1.0.3(@types/react@18.2.73)(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.73)(react@18.2.0) - '@types/react': 18.2.73 react: 18.2.0 + optionalDependencies: + '@types/react': 18.2.73 '@radix-ui/react-use-layout-effect@1.0.1(@types/react@18.2.73)(react@18.2.0)': dependencies: '@babel/runtime': 7.24.1 - '@types/react': 18.2.73 react: 18.2.0 + optionalDependencies: + '@types/react': 18.2.73 - '@react-three/fiber@8.16.1(react-dom@18.2.0)(react@18.2.0)(three@0.163.0)': + '@react-three/fiber@8.16.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(three@0.163.0)': dependencies: '@babel/runtime': 7.24.1 '@types/react-reconciler': 0.26.7 @@ -2921,13 +3096,14 @@ snapshots: buffer: 6.0.3 its-fine: 1.1.3(react@18.2.0) react: 18.2.0 - react-dom: 18.2.0(react@18.2.0) react-reconciler: 0.27.0(react@18.2.0) - react-use-measure: 2.1.1(react-dom@18.2.0)(react@18.2.0) + react-use-measure: 2.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0) scheduler: 0.21.0 suspend-react: 0.1.3(react@18.2.0) three: 0.163.0 zustand: 3.7.2(react@18.2.0) + optionalDependencies: + react-dom: 18.2.0(react@18.2.0) '@rushstack/eslint-patch@1.10.1': {} @@ -2977,6 +3153,8 @@ snapshots: '@types/json5@0.0.29': {} + '@types/katex@0.16.7': {} + '@types/mdast@4.0.3': dependencies: '@types/unist': 3.0.2 @@ -3032,6 +3210,7 @@ snapshots: '@typescript-eslint/visitor-keys': 6.21.0 debug: 4.3.4 eslint: 8.57.0 + optionalDependencies: typescript: 5.4.3 transitivePeerDependencies: - supports-color @@ -3053,6 +3232,7 @@ snapshots: minimatch: 9.0.3 semver: 7.6.0 ts-api-utils: 1.3.0(typescript@5.4.3) + optionalDependencies: typescript: 5.4.3 transitivePeerDependencies: - supports-color @@ -3064,15 +3244,16 @@ snapshots: '@ungap/structured-clone@1.2.0': {} - '@vercel/analytics@1.2.2(next@14.1.4)(react@18.2.0)': + '@vercel/analytics@1.2.2(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)': dependencies: - next: 14.1.4(react-dom@18.2.0)(react@18.2.0) - react: 18.2.0 server-only: 0.0.1 + optionalDependencies: + next: 14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + react: 18.2.0 - '@vercel/speed-insights@1.0.10(next@14.1.4)(react@18.2.0)': - dependencies: - next: 14.1.4(react-dom@18.2.0)(react@18.2.0) + '@vercel/speed-insights@1.0.10(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react@18.2.0)': + optionalDependencies: + next: 14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 '@webassemblyjs/ast@1.12.1': @@ -3195,6 +3376,10 @@ snapshots: arg@5.0.2: {} + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + argparse@2.0.1: {} aria-hidden@1.2.4: @@ -3395,10 +3580,10 @@ snapshots: clsx@2.1.0: {} - cmdk@1.0.0(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0): + cmdk@1.0.0(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: - '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) - '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-dialog': 1.0.5(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.23)(@types/react@18.2.73)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) transitivePeerDependencies: @@ -3419,6 +3604,8 @@ snapshots: commander@4.1.1: {} + commander@8.3.0: {} + concat-map@0.0.1: {} cross-spawn@7.0.3: @@ -3516,6 +3703,8 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.2.1 + entities@4.5.0: {} + es-abstract@1.23.2: dependencies: array-buffer-byte-length: 1.0.1 @@ -3621,11 +3810,12 @@ snapshots: '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) eslint-plugin-jsx-a11y: 6.8.0(eslint@8.57.0) eslint-plugin-react: 7.34.1(eslint@8.57.0) eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0) + optionalDependencies: typescript: 5.4.3 transitivePeerDependencies: - eslint-import-resolver-webpack @@ -3639,13 +3829,13 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0): + eslint-import-resolver-typescript@3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0): dependencies: debug: 4.3.4 enhanced-resolve: 5.16.0 eslint: 8.57.0 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) - eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) fast-glob: 3.3.2 get-tsconfig: 4.7.3 is-core-module: 2.13.1 @@ -3656,19 +3846,19 @@ snapshots: - eslint-import-resolver-webpack - supports-color - eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + eslint-module-utils@2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): dependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.3) debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.3) eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1)(eslint@8.57.0) + eslint-import-resolver-typescript: 3.6.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.29.1(eslint@8.57.0))(eslint@8.57.0) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): + eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0): dependencies: - '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.3) array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 @@ -3677,7 +3867,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0)(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.21.0(eslint@8.57.0)(typescript@5.4.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.1)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -3687,6 +3877,8 @@ snapshots: object.values: 1.2.0 semver: 6.3.1 tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 6.21.0(eslint@8.57.0)(typescript@5.4.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -3799,6 +3991,8 @@ snapshots: acorn-jsx: 5.3.2(acorn@8.11.3) eslint-visitor-keys: 3.4.3 + esprima@4.0.1: {} + esquery@1.5.0: dependencies: estraverse: 5.3.0 @@ -3843,6 +4037,10 @@ snapshots: events@3.3.0: {} + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + extend@3.0.2: {} fast-deep-equal@3.1.3: {} @@ -3913,9 +4111,9 @@ snapshots: functions-have-names@1.2.3: {} - geist@1.3.0(next@14.1.4): + geist@1.3.0(next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0)): dependencies: - next: 14.1.4(react-dom@18.2.0)(react@18.2.0) + next: 14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0) get-intrinsic@1.2.4: dependencies: @@ -3997,6 +4195,13 @@ snapshots: graphemer@1.4.0: {} + gray-matter@4.0.3: + dependencies: + js-yaml: 3.14.1 + kind-of: 6.0.3 + section-matter: 1.0.0 + strip-bom-string: 1.0.0 + has-bigints@1.0.2: {} has-flag@4.0.0: {} @@ -4017,6 +4222,47 @@ snapshots: dependencies: function-bind: 1.1.2 + hast-util-from-dom@5.0.1: + dependencies: + '@types/hast': 3.0.4 + hastscript: 9.0.1 + web-namespaces: 2.0.1 + + hast-util-from-html-isomorphic@2.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-from-dom: 5.0.1 + hast-util-from-html: 2.0.3 + unist-util-remove-position: 5.0.0 + + hast-util-from-html@2.0.3: + dependencies: + '@types/hast': 3.0.4 + devlop: 1.1.0 + hast-util-from-parse5: 8.0.3 + parse5: 7.2.1 + vfile: 6.0.1 + vfile-message: 4.0.2 + + hast-util-from-parse5@8.0.3: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.2 + devlop: 1.1.0 + hastscript: 9.0.1 + property-information: 7.0.0 + vfile: 6.0.1 + vfile-location: 5.0.3 + web-namespaces: 2.0.1 + + hast-util-is-element@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hast-util-parse-selector@4.0.0: + dependencies: + '@types/hast': 3.0.4 + hast-util-to-estree@3.1.0: dependencies: '@types/estree': 1.0.5 @@ -4058,10 +4304,25 @@ snapshots: transitivePeerDependencies: - supports-color + hast-util-to-text@4.0.2: + dependencies: + '@types/hast': 3.0.4 + '@types/unist': 3.0.2 + hast-util-is-element: 3.0.0 + unist-util-find-after: 5.0.0 + hast-util-whitespace@3.0.0: dependencies: '@types/hast': 3.0.4 + hastscript@9.0.1: + dependencies: + '@types/hast': 3.0.4 + comma-separated-tokens: 2.0.3 + hast-util-parse-selector: 4.0.0 + property-information: 7.0.0 + space-separated-tokens: 2.0.2 + ieee754@1.2.1: {} ignore@5.3.1: {} @@ -4139,6 +4400,8 @@ snapshots: is-decimal@2.0.1: {} + is-extendable@0.1.1: {} + is-extglob@2.1.1: {} is-finalizationregistry@1.0.2: @@ -4242,6 +4505,11 @@ snapshots: js-tokens@4.0.0: {} + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + js-yaml@4.1.0: dependencies: argparse: 2.0.1 @@ -4265,10 +4533,16 @@ snapshots: object.assign: 4.1.5 object.values: 1.2.0 + katex@0.16.21: + dependencies: + commander: 8.3.0 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 + kind-of@6.0.3: {} + language-subtag-registry@0.3.22: {} language-tags@1.0.9: @@ -4333,6 +4607,18 @@ snapshots: transitivePeerDependencies: - supports-color + mdast-util-math@3.0.0: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.3 + devlop: 1.1.0 + longest-streak: 3.1.0 + mdast-util-from-markdown: 2.0.0 + mdast-util-to-markdown: 2.1.0 + unist-util-remove-position: 5.0.0 + transitivePeerDependencies: + - supports-color + mdast-util-mdx-expression@2.0.0: dependencies: '@types/estree-jsx': 1.0.5 @@ -4440,6 +4726,16 @@ snapshots: micromark-util-symbol: 2.0.0 micromark-util-types: 2.0.0 + micromark-extension-math@3.1.0: + dependencies: + '@types/katex': 0.16.7 + devlop: 1.1.0 + katex: 0.16.21 + micromark-factory-space: 2.0.0 + micromark-util-character: 2.1.0 + micromark-util-symbol: 2.0.0 + micromark-util-types: 2.0.0 + micromark-extension-mdx-expression@3.0.0: dependencies: '@types/estree': 1.0.5 @@ -4670,12 +4966,25 @@ snapshots: neo-async@2.6.2: {} - next-themes@0.3.0(react-dom@18.2.0)(react@18.2.0): + next-mdx-remote@5.0.0(@types/react@18.2.73)(react@18.2.0): + dependencies: + '@babel/code-frame': 7.26.2 + '@mdx-js/mdx': 3.0.1 + '@mdx-js/react': 3.0.1(@types/react@18.2.73)(react@18.2.0) + react: 18.2.0 + unist-util-remove: 3.1.1 + vfile: 6.0.1 + vfile-matter: 5.0.0 + transitivePeerDependencies: + - '@types/react' + - supports-color + + next-themes@0.3.0(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - next@14.1.4(react-dom@18.2.0)(react@18.2.0): + next@14.1.4(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@next/env': 14.1.4 '@swc/helpers': 0.5.2 @@ -4788,6 +5097,10 @@ snapshots: is-decimal: 2.0.1 is-hexadecimal: 2.0.1 + parse5@7.2.1: + dependencies: + entities: 4.5.0 + path-exists@4.0.0: {} path-is-absolute@1.0.1: {} @@ -4834,8 +5147,9 @@ snapshots: postcss-load-config@4.0.2(postcss@8.4.38): dependencies: lilconfig: 3.1.1 - postcss: 8.4.38 yaml: 2.4.1 + optionalDependencies: + postcss: 8.4.38 postcss-nested@6.0.1(postcss@8.4.38): dependencies: @@ -4876,6 +5190,8 @@ snapshots: property-information@6.4.1: {} + property-information@7.0.0: {} + punycode@2.3.1: {} queue-microtask@1.2.3: {} @@ -4904,30 +5220,33 @@ snapshots: react-remove-scroll-bar@2.3.6(@types/react@18.2.73)(react@18.2.0): dependencies: - '@types/react': 18.2.73 react: 18.2.0 react-style-singleton: 2.2.1(@types/react@18.2.73)(react@18.2.0) tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.2.73 react-remove-scroll@2.5.5(@types/react@18.2.73)(react@18.2.0): dependencies: - '@types/react': 18.2.73 react: 18.2.0 react-remove-scroll-bar: 2.3.6(@types/react@18.2.73)(react@18.2.0) react-style-singleton: 2.2.1(@types/react@18.2.73)(react@18.2.0) tslib: 2.6.2 use-callback-ref: 1.3.2(@types/react@18.2.73)(react@18.2.0) use-sidecar: 1.1.2(@types/react@18.2.73)(react@18.2.0) + optionalDependencies: + '@types/react': 18.2.73 react-style-singleton@2.2.1(@types/react@18.2.73)(react@18.2.0): dependencies: - '@types/react': 18.2.73 get-nonce: 1.0.1 invariant: 2.2.4 react: 18.2.0 tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.2.73 - react-use-measure@2.1.1(react-dom@18.2.0)(react@18.2.0): + react-use-measure@2.1.1(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: debounce: 1.2.1 react: 18.2.0 @@ -4964,6 +5283,25 @@ snapshots: es-errors: 1.3.0 set-function-name: 2.0.2 + rehype-katex@7.0.1: + dependencies: + '@types/hast': 3.0.4 + '@types/katex': 0.16.7 + hast-util-from-html-isomorphic: 2.0.0 + hast-util-to-text: 4.0.2 + katex: 0.16.21 + unist-util-visit-parents: 6.0.1 + vfile: 6.0.1 + + remark-math@6.0.0: + dependencies: + '@types/mdast': 4.0.3 + mdast-util-math: 3.0.0 + micromark-extension-math: 3.1.0 + unified: 11.0.4 + transitivePeerDependencies: + - supports-color + remark-mdx@3.0.1: dependencies: mdast-util-mdx: 3.0.0 @@ -5043,6 +5381,11 @@ snapshots: ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) + section-matter@1.0.0: + dependencies: + extend-shallow: 2.0.1 + kind-of: 6.0.3 + semver@6.3.1: {} semver@7.6.0: @@ -5101,6 +5444,8 @@ snapshots: space-separated-tokens@2.0.2: {} + sprintf-js@1.0.3: {} + streamsearch@1.1.0: {} string-width@4.2.3: @@ -5162,6 +5507,8 @@ snapshots: dependencies: ansi-regex: 6.0.1 + strip-bom-string@1.0.0: {} + strip-bom@3.0.0: {} strip-json-comments@3.1.1: {} @@ -5350,6 +5697,15 @@ snapshots: trough: 2.2.0 vfile: 6.0.1 + unist-util-find-after@5.0.0: + dependencies: + '@types/unist': 3.0.2 + unist-util-is: 6.0.0 + + unist-util-is@5.2.1: + dependencies: + '@types/unist': 2.0.10 + unist-util-is@6.0.0: dependencies: '@types/unist': 3.0.2 @@ -5367,10 +5723,21 @@ snapshots: '@types/unist': 3.0.2 unist-util-visit: 5.0.0 + unist-util-remove@3.1.1: + dependencies: + '@types/unist': 2.0.10 + unist-util-is: 5.2.1 + unist-util-visit-parents: 5.1.3 + unist-util-stringify-position@4.0.0: dependencies: '@types/unist': 3.0.2 + unist-util-visit-parents@5.1.3: + dependencies: + '@types/unist': 2.0.10 + unist-util-is: 5.2.1 + unist-util-visit-parents@6.0.1: dependencies: '@types/unist': 3.0.2 @@ -5394,16 +5761,18 @@ snapshots: use-callback-ref@1.3.2(@types/react@18.2.73)(react@18.2.0): dependencies: - '@types/react': 18.2.73 react: 18.2.0 tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.2.73 use-sidecar@1.1.2(@types/react@18.2.73)(react@18.2.0): dependencies: - '@types/react': 18.2.73 detect-node-es: 1.1.0 react: 18.2.0 tslib: 2.6.2 + optionalDependencies: + '@types/react': 18.2.73 use-sync-external-store@1.2.0(react@18.2.0): dependencies: @@ -5411,6 +5780,16 @@ snapshots: util-deprecate@1.0.2: {} + vfile-location@5.0.3: + dependencies: + '@types/unist': 3.0.2 + vfile: 6.0.1 + + vfile-matter@5.0.0: + dependencies: + vfile: 6.0.1 + yaml: 2.4.1 + vfile-message@4.0.2: dependencies: '@types/unist': 3.0.2 @@ -5427,6 +5806,8 @@ snapshots: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 + web-namespaces@2.0.1: {} + webpack-sources@3.2.3: {} webpack@5.91.0: @@ -5523,13 +5904,14 @@ snapshots: yocto-queue@0.1.0: {} zustand@3.7.2(react@18.2.0): - dependencies: + optionalDependencies: react: 18.2.0 zustand@4.5.2(@types/react@18.2.73)(react@18.2.0): dependencies: + use-sync-external-store: 1.2.0(react@18.2.0) + optionalDependencies: '@types/react': 18.2.73 react: 18.2.0 - use-sync-external-store: 1.2.0(react@18.2.0) zwitch@2.0.4: {} diff --git a/src/app/[...dir]/page.tsx b/src/app/[...dir]/page.tsx index 838d103..35b94d5 100644 --- a/src/app/[...dir]/page.tsx +++ b/src/app/[...dir]/page.tsx @@ -1,20 +1,74 @@ import { notFound } from "next/navigation"; +import { MDXRemote } from 'next-mdx-remote/rsc'; +import fs from 'fs/promises'; +import path from 'path'; +import matter from 'gray-matter'; +import remarkMath from 'remark-math'; +import rehypeKatex from 'rehype-katex'; -type Log = { +// Update the type to match our MDX frontmatter +type Post = { title: string; - createdAt: Date; - updatedAt: Date; - content: React.ReactNode; + createdAt: string; + updatedAt: string; + content: string; }; -const Page = async () => { - const post = undefined; +async function getPost(slug: string[]): Promise { + // Handle only essays/[name] route + if (slug[0] !== 'essays' || slug.length !== 2) { + return null; + } + + const postName = slug[1]; + const postsDirectory = path.join(process.cwd(), 'content/essays'); + + try { + const fullPath = path.join(postsDirectory, `${postName}.mdx`); + const fileContents = await fs.readFile(fullPath, 'utf8'); + + const { data, content } = matter(fileContents); + + return { + title: data.title, + createdAt: data.createdAt, + updatedAt: data.updatedAt, + content: content, + }; + } catch (error) { + return null; + } +} + +const Page = async ({ params }: { params: { dir: string[] } }) => { + const post = await getPost(params.dir); if (!post) { return notFound(); } - return

WIP

; + return ( +
+

{post.title}

+
+ + {post.updatedAt && ( + + )} +
+ +
+ ); }; export default Page; diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 50eaf92..7e83361 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -2,6 +2,8 @@ import type { Metadata } from "next"; import "./globals.css"; +import 'katex/dist/katex.min.css'; + export const metadata: Metadata = { title: "\\wych.dev", description: "In the wych elm's shadow, veritas whispers brew.", @@ -54,6 +56,12 @@ export default function RootLayout({ }) { return ( + + + { + const postsDirectory = path.join(process.cwd(), 'content/essays'); + const files = await fs.readdir(postsDirectory); + + const posts = await Promise.all( + files + .filter(file => file.endsWith('.mdx')) + .map(async (file) => { + const fullPath = path.join(postsDirectory, file); + const fileContents = await fs.readFile(fullPath, 'utf8'); + const { data } = matter(fileContents); + + return { + title: data.title, + createdAt: data.createdAt, + slug: file.replace(/\.mdx$/, ''), + }; + }) + ); + + return posts.sort((a, b) => + new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime() + ); +} + +export default async function PostsPage() { + const posts = await getPosts(); + + return ( +
+

Essays

+
    + {posts.map((post) => ( +
  • + +

    {post.title}

    + + +
  • + ))} +
+
+ ); +} \ No newline at end of file