From eb972b8f1ae11010a1f5ec296a5c282ab16f922e Mon Sep 17 00:00:00 2001 From: Kuinox Date: Fri, 10 Nov 2023 21:24:07 +0100 Subject: [PATCH] Blog Engine and more. (#11) --- .prettierrc | 3 + .stylelintrc | 3 +- .vscode/launch.json | 28 + README.md | 1 + generateAssets.js | 30 +- next.config.js | 4 +- package-lock.json | 1312 +++++++++++++---- package.json | 11 +- public/blog/birthday/article.md | 721 +++++++++ public/clipboard.svg | 1 + public/index.html | 18 - public/link.svg | 1 + src/app/SuperDerpy.tsx | 1 - src/app/blog/[articleName]/CommentScript.tsx | 35 + src/app/blog/[articleName]/page.css | 84 ++ src/app/blog/[articleName]/page.tsx | 134 ++ src/app/blog/layout.tsx | 13 + src/app/blog/page.css | 37 +- src/app/blog/page.tsx | 33 +- src/app/community/page.css | 10 +- src/app/community/page.tsx | 4 +- src/app/docs/page.tsx | 2 +- src/app/layout.css | 49 +- src/app/layout.tsx | 31 +- src/app/not-found.tsx | 5 +- src/app/specs/[articleName]/page.tsx | 31 + src/app/specs/layout.css | 47 + src/app/specs/layout.tsx | 43 + src/app/specs/page.css | 6 - src/app/specs/page.tsx | 21 +- src/components/Article.css | 214 +++ src/components/Article.tsx | 180 +++ src/components/CodeViewer/CodeTab.css | 15 +- src/components/CodeViewer/CodeViewer.tsx | 1 - src/components/CodeViewer/Highlight.tsx | 1 + src/components/DracoButton.css | 5 + src/components/DracoButton.tsx | 2 +- src/components/TableOfContentScrollEffect.tsx | 130 ++ src/utils/ArticleNameParams.ts | 5 + src/utils/blog.ts | 63 + src/utils/github.ts | 41 + src/utils/metadata.ts | 44 + 42 files changed, 3046 insertions(+), 374 deletions(-) create mode 100644 .prettierrc create mode 100644 .vscode/launch.json create mode 100644 public/blog/birthday/article.md create mode 100644 public/clipboard.svg delete mode 100644 public/index.html create mode 100644 public/link.svg create mode 100644 src/app/blog/[articleName]/CommentScript.tsx create mode 100644 src/app/blog/[articleName]/page.css create mode 100644 src/app/blog/[articleName]/page.tsx create mode 100644 src/app/blog/layout.tsx create mode 100644 src/app/specs/[articleName]/page.tsx create mode 100644 src/app/specs/layout.css create mode 100644 src/app/specs/layout.tsx create mode 100644 src/components/Article.css create mode 100644 src/components/Article.tsx create mode 100644 src/components/TableOfContentScrollEffect.tsx create mode 100644 src/utils/ArticleNameParams.ts create mode 100644 src/utils/blog.ts create mode 100644 src/utils/github.ts create mode 100644 src/utils/metadata.ts diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..de753c5 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,3 @@ +{ + "printWidth": 100 +} diff --git a/.stylelintrc b/.stylelintrc index 1953c36..84073b7 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -1,6 +1,7 @@ { "extends": "stylelint-config-standard", "rules": { - "shorthand-property-no-redundant-values": null + "shorthand-property-no-redundant-values": null, + "color-function-notation": "legacy" } } diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..e330519 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Next.js: debug server-side", + "type": "node-terminal", + "request": "launch", + "command": "npm run dev" + }, + { + "name": "Next.js: debug client-side", + "type": "chrome", + "request": "launch", + "url": "http://localhost:3000" + }, + { + "name": "Next.js: debug full stack", + "type": "node-terminal", + "request": "launch", + "command": "npm run dev", + "serverReadyAction": { + "pattern": "- Local:.+(https?://.+)", + "uriFormat": "%s", + "action": "debugWithChrome" + } + } + ] + } \ No newline at end of file diff --git a/README.md b/README.md index cd2e39d..34de037 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ # draco-lang.github.io + Official website for the Draco programming language. diff --git a/generateAssets.js b/generateAssets.js index eefa9f2..ab4d541 100644 --- a/generateAssets.js +++ b/generateAssets.js @@ -1,6 +1,7 @@ const { Octokit } = require("@octokit/rest"); const fs = require("fs"); -const createActionAuth = require("@octokit/auth-action"); +const { createTokenAuth } = require("@octokit/auth-token"); +const sharp = require("sharp"); const fullLogo = { light: "https://raw.githubusercontent.com/Draco-lang/Language-suggestions/main/Resources/Logo-Long.svg", @@ -21,14 +22,15 @@ async function main() { fs.mkdirSync("public/generated", { recursive: true }); } - downloadThemedImage(fullLogo, "public/generated/Logo-Long.svg", true); - downloadThemedImage(shortLogo, "public/generated/Logo-Short.svg", true); - downloadThemedImage(githubLogo, "public/generated/github-logo.svg", false); - download("https://raw.githubusercontent.com/Draco-lang/Language-suggestions/main/Resources/Derpy-Outlined.svg", "public/generated/derpy.svg"); + await downloadThemedImage(fullLogo, "public/generated/Logo-Long.svg", true); + await downloadThemedImage(shortLogo, "public/generated/Logo-Short.svg", true); + await downloadThemedImage(githubLogo, "public/generated/github-logo.svg", false); + await downloadAndConvertSvgToPng("https://raw.githubusercontent.com/Draco-lang/Language-suggestions/main/Resources/Logo-Short-Inverted-Outline.svg", "public/generated/Logo-Short-Inverted-Outline.png"); + await download("https://raw.githubusercontent.com/Draco-lang/Language-suggestions/main/Resources/Derpy-Outlined.svg", "public/generated/derpy.svg"); emojis.push("derpy"); let octokit; if (process.env.GITHUB_TOKEN !== undefined && process.env.GITHUB_TOKEN.length > 0) { - const auth = createActionAuth(); + const auth = createTokenAuth(process.env.GITHUB_TOKEN); const authentication = await auth(); octokit = new Octokit({ auth: authentication.token @@ -43,15 +45,16 @@ async function main() { path: "Resources/Emojis" }); - for (let i = 0; i < response.data.length; i++) { - const element = response.data[i]; + const promises = response.data.map(async element => { console.log(`Downloading ${element.name}...`); const resp = await fetch(element.download_url); const emoji = await resp.text(); await fs.promises.writeFile(`public/generated/${element.name}`, emoji); - } + }); + await Promise.all(promises); + response.data - .map(s => `${s.name.replace(/\.[^/.]+$/, "")}`) + .map(s => s.name.replace(/\.[^/.]+$/, "")) .forEach(s => emojis.push(s)); await fs.promises.writeFile( "src/generated/emojiTypes.ts", @@ -130,4 +133,11 @@ ${logoLight} `; return logoSvg; +} + +async function downloadAndConvertSvgToPng(url, outputPath) { + const resp = await fetch(url); + const svgContent = await resp.text(); + await sharp(Buffer.from(svgContent)).png().toFile(outputPath); + console.log(`SVG converted and saved as ${outputPath}`); } \ No newline at end of file diff --git a/next.config.js b/next.config.js index ba03062..ff7a6ce 100644 --- a/next.config.js +++ b/next.config.js @@ -6,6 +6,6 @@ const nextConfig = { images: { unoptimized: true, } -} +}; -module.exports = nextConfig +module.exports = nextConfig; diff --git a/package-lock.json b/package-lock.json index ff0110a..7cc6bf0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,14 +8,17 @@ "name": "draco-website", "version": "0.1.0", "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/rest": "^20.0.1", + "front-matter": "^4.0.2", "highlight.js": "^11.8.0", - "next": "^13.5.3", + "marked": "^9.1.2", + "next": "^14.0.1", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "sharp": "^0.32.6" }, "devDependencies": { - "@octokit/auth-action": "^4.0.1", - "@octokit/rest": "^20.0.1", "@types/node": "^20.6.5", "@types/react": "^18.2.22", "@types/react-dom": "^18.2.7", @@ -298,9 +301,9 @@ "peer": true }, "node_modules/@next/env": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/env/-/env-13.5.3.tgz", - "integrity": "sha512-X4te86vsbjsB7iO4usY9jLPtZ827Mbx+WcwNBGUOIuswuTAKQtzsuoxc/6KLxCMvogKG795MhrR1LDhYgDvasg==" + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.0.1.tgz", + "integrity": "sha512-Ms8ZswqY65/YfcjrlcIwMPD7Rg/dVjdLapMcSHG26W6O67EJDF435ShW4H4LXi1xKO1oRc97tLXUpx8jpLe86A==" }, "node_modules/@next/eslint-plugin-next": { "version": "13.5.3", @@ -332,9 +335,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.5.3.tgz", - "integrity": "sha512-6hiYNJxJmyYvvKGrVThzo4nTcqvqUTA/JvKim7Auaj33NexDqSNwN5YrrQu+QhZJCIpv2tULSHt+lf+rUflLSw==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.0.1.tgz", + "integrity": "sha512-JyxnGCS4qT67hdOKQ0CkgFTp+PXub5W1wsGvIq98TNbF3YEIN7iDekYhYsZzc8Ov0pWEsghQt+tANdidITCLaw==", "cpu": [ "arm64" ], @@ -347,9 +350,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.3.tgz", - "integrity": "sha512-UpBKxu2ob9scbpJyEq/xPgpdrgBgN3aLYlxyGqlYX5/KnwpJpFuIHU2lx8upQQ7L+MEmz+fA1XSgesoK92ppwQ==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.0.1.tgz", + "integrity": "sha512-625Z7bb5AyIzswF9hvfZWa+HTwFZw+Jn3lOBNZB87lUS0iuCYDHqk3ujuHCkiyPtSC0xFBtYDLcrZ11mF/ap3w==", "cpu": [ "x64" ], @@ -362,9 +365,9 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.3.tgz", - "integrity": "sha512-5AzM7Yx1Ky+oLY6pHs7tjONTF22JirDPd5Jw/3/NazJ73uGB05NqhGhB4SbeCchg7SlVYVBeRMrMSZwJwq/xoA==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.0.1.tgz", + "integrity": "sha512-iVpn3KG3DprFXzVHM09kvb//4CNNXBQ9NB/pTm8LO+vnnnaObnzFdS5KM+w1okwa32xH0g8EvZIhoB3fI3mS1g==", "cpu": [ "arm64" ], @@ -377,9 +380,9 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.3.tgz", - "integrity": "sha512-A/C1shbyUhj7wRtokmn73eBksjTM7fFQoY2v/0rTM5wehpkjQRLOXI8WJsag2uLhnZ4ii5OzR1rFPwoD9cvOgA==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.0.1.tgz", + "integrity": "sha512-mVsGyMxTLWZXyD5sen6kGOTYVOO67lZjLApIj/JsTEEohDDt1im2nkspzfV5MvhfS7diDw6Rp/xvAQaWZTv1Ww==", "cpu": [ "arm64" ], @@ -392,9 +395,9 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.3.tgz", - "integrity": "sha512-FubPuw/Boz8tKkk+5eOuDHOpk36F80rbgxlx4+xty/U71e3wZZxVYHfZXmf0IRToBn1Crb8WvLM9OYj/Ur815g==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.0.1.tgz", + "integrity": "sha512-wMqf90uDWN001NqCM/auRl3+qVVeKfjJdT9XW+RMIOf+rhUzadmYJu++tp2y+hUbb6GTRhT+VjQzcgg/QTD9NQ==", "cpu": [ "x64" ], @@ -407,9 +410,9 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.3.tgz", - "integrity": "sha512-DPw8nFuM1uEpbX47tM3wiXIR0Qa+atSzs9Q3peY1urkhofx44o7E1svnq+a5Q0r8lAcssLrwiM+OyJJgV/oj7g==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.0.1.tgz", + "integrity": "sha512-ol1X1e24w4j4QwdeNjfX0f+Nza25n+ymY0T2frTyalVczUmzkVD7QGgPTZMHfR1aLrO69hBs0G3QBYaj22J5GQ==", "cpu": [ "x64" ], @@ -422,9 +425,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.3.tgz", - "integrity": "sha512-zBPSP8cHL51Gub/YV8UUePW7AVGukp2D8JU93IHbVDu2qmhFAn9LWXiOOLKplZQKxnIPUkJTQAJDCWBWU4UWUA==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.0.1.tgz", + "integrity": "sha512-WEmTEeWs6yRUEnUlahTgvZteh5RJc4sEjCQIodJlZZ5/VJwVP8p2L7l6VhzQhT4h7KvLx/Ed4UViBdne6zpIsw==", "cpu": [ "arm64" ], @@ -437,9 +440,9 @@ } }, "node_modules/@next/swc-win32-ia32-msvc": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.3.tgz", - "integrity": "sha512-ONcL/lYyGUj4W37D4I2I450SZtSenmFAvapkJQNIJhrPMhzDU/AdfLkW98NvH1D2+7FXwe7yclf3+B7v28uzBQ==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.0.1.tgz", + "integrity": "sha512-oFpHphN4ygAgZUKjzga7SoH2VGbEJXZa/KL8bHCAwCjDWle6R1SpiGOdUdA8EJ9YsG1TYWpzY6FTbUA+iAJeww==", "cpu": [ "ia32" ], @@ -452,9 +455,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.3.tgz", - "integrity": "sha512-2Vz2tYWaLqJvLcWbbTlJ5k9AN6JD7a5CN2pAeIzpbecK8ZF/yobA39cXtv6e+Z8c5UJuVOmaTldEAIxvsIux/Q==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.0.1.tgz", + "integrity": "sha512-FFp3nOJ/5qSpeWT0BZQ+YE1pSMk4IMpkME/1DwKBwhg4mJLB9L+6EXuJi4JEwaJdl5iN+UUlmUD3IsR1kx5fAg==", "cpu": [ "x64" ], @@ -501,24 +504,10 @@ "node": ">= 8" } }, - "node_modules/@octokit/auth-action": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-action/-/auth-action-4.0.1.tgz", - "integrity": "sha512-mJLOcFFafIivLZ7BEkGDCTFoHPJv7BeL5Zwy7j5qMDU0b/DKshhi6GCU9tw3vmKhOxTNquYfvwqsEfPpemaaxg==", - "dev": true, - "dependencies": { - "@octokit/auth-token": "^4.0.0", - "@octokit/types": "^12.0.0" - }, - "engines": { - "node": ">= 18" - } - }, "node_modules/@octokit/auth-token": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", - "dev": true, "engines": { "node": ">= 18" } @@ -527,7 +516,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.1.tgz", "integrity": "sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==", - "dev": true, "dependencies": { "@octokit/auth-token": "^4.0.0", "@octokit/graphql": "^7.0.0", @@ -545,7 +533,6 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.1.tgz", "integrity": "sha512-hRlOKAovtINHQPYHZlfyFwaM8OyetxeoC81lAkBy34uLb8exrZB50SQdeW3EROqiY9G9yxQTpp5OHTV54QD+vA==", - "dev": true, "dependencies": { "@octokit/types": "^12.0.0", "is-plain-object": "^5.0.0", @@ -559,7 +546,6 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", - "dev": true, "dependencies": { "@octokit/request": "^8.0.1", "@octokit/types": "^12.0.0", @@ -572,14 +558,12 @@ "node_modules/@octokit/openapi-types": { "version": "19.0.0", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz", - "integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw==", - "dev": true + "integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw==" }, "node_modules/@octokit/plugin-paginate-rest": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.0.0.tgz", "integrity": "sha512-oIJzCpttmBTlEhBmRvb+b9rlnGpmFgDtZ0bB6nq39qIod6A5DP+7RkVLMOixIgRCYSHDTeayWqmiJ2SZ6xgfdw==", - "dev": true, "dependencies": { "@octokit/types": "^12.0.0" }, @@ -594,7 +578,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz", "integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==", - "dev": true, "engines": { "node": ">= 18" }, @@ -606,7 +589,6 @@ "version": "10.0.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.0.0.tgz", "integrity": "sha512-16VkwE2v6rXU+/gBsYC62M8lKWOphY5Lg4wpjYnVE9Zbu0J6IwiT5kILoj1YOB53XLmcJR+Nqp8DmifOPY4H3g==", - "dev": true, "dependencies": { "@octokit/types": "^12.0.0" }, @@ -621,7 +603,6 @@ "version": "8.1.2", "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.2.tgz", "integrity": "sha512-A0RJJfzjlZQwb+39eDm5UM23dkxbp28WEG4p2ueH+Q2yY4p349aRK/vcUlEuIB//ggcrHJceoYYkBP/LYCoXEg==", - "dev": true, "dependencies": { "@octokit/endpoint": "^9.0.0", "@octokit/request-error": "^5.0.0", @@ -637,7 +618,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", - "dev": true, "dependencies": { "@octokit/types": "^12.0.0", "deprecation": "^2.0.0", @@ -651,7 +631,6 @@ "version": "20.0.2", "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", - "dev": true, "dependencies": { "@octokit/core": "^5.0.0", "@octokit/plugin-paginate-rest": "^9.0.0", @@ -666,7 +645,6 @@ "version": "12.0.0", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.0.0.tgz", "integrity": "sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==", - "dev": true, "dependencies": { "@octokit/openapi-types": "^19.0.0" } @@ -1007,6 +985,14 @@ "node": ">=4" } }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/aria-query": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", @@ -1210,17 +1196,50 @@ "dequal": "^2.0.3" } }, + "node_modules/b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/before-after-hook": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "dev": true + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -1244,6 +1263,29 @@ "node": ">=8" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -1357,11 +1399,28 @@ "node": ">=4" } }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, "node_modules/client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1375,9 +1434,32 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "peer": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/color/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/colord": { "version": "2.9.3", @@ -1509,6 +1591,28 @@ "node": ">=0.10.0" } }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -1535,8 +1639,7 @@ "node_modules/deprecation": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" }, "node_modules/dequal": { "version": "2.0.3", @@ -1547,6 +1650,14 @@ "node": ">=6" } }, + "node_modules/detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", + "engines": { + "node": ">=8" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -1578,6 +1689,14 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", @@ -2243,6 +2362,18 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -2287,6 +2418,14 @@ "node": ">=0.10.0" } }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "engines": { + "node": ">=6" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2294,6 +2433,11 @@ "dev": true, "peer": true }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "node_modules/fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -2428,6 +2572,19 @@ "is-callable": "^1.1.3" } }, + "node_modules/front-matter": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", + "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==", + "dependencies": { + "js-yaml": "^3.13.1" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -2510,6 +2667,11 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -2801,6 +2963,25 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -2883,15 +3064,12 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "peer": true + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "node_modules/internal-slot": { "version": "1.0.5", @@ -3127,7 +3305,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -3279,6 +3456,18 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -3439,6 +3628,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/marked": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.2.tgz", + "integrity": "sha512-qoKMJqK0w6vkLk8+KnKZAH6neUZSNaQqVZ/h2yZ9S7CbLuFHyS2viB0jnqcWF9UKjwsAbMrQtnQhdmdvOVOw9w==", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 16" + } + }, "node_modules/mathml-tag-names": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", @@ -3512,6 +3712,17 @@ "node": ">=8.6" } }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -3538,7 +3749,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -3568,6 +3778,11 @@ "node": ">=0.10.0" } }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -3591,6 +3806,11 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -3598,35 +3818,34 @@ "dev": true }, "node_modules/next": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/next/-/next-13.5.3.tgz", - "integrity": "sha512-4Nt4HRLYDW/yRpJ/QR2t1v63UOMS55A38dnWv3UDOWGezuY0ZyFO1ABNbD7mulVzs9qVhgy2+ppjdsANpKP1mg==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/next/-/next-14.0.1.tgz", + "integrity": "sha512-s4YaLpE4b0gmb3ggtmpmV+wt+lPRuGtANzojMQ2+gmBpgX9w5fTbjsy6dXByBuENsdCX5pukZH/GxdFgO62+pA==", "dependencies": { - "@next/env": "13.5.3", + "@next/env": "14.0.1", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", - "postcss": "8.4.14", + "postcss": "8.4.31", "styled-jsx": "5.1.1", - "watchpack": "2.4.0", - "zod": "3.21.4" + "watchpack": "2.4.0" }, "bin": { "next": "dist/bin/next" }, "engines": { - "node": ">=16.14.0" + "node": ">=18.17.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "13.5.3", - "@next/swc-darwin-x64": "13.5.3", - "@next/swc-linux-arm64-gnu": "13.5.3", - "@next/swc-linux-arm64-musl": "13.5.3", - "@next/swc-linux-x64-gnu": "13.5.3", - "@next/swc-linux-x64-musl": "13.5.3", - "@next/swc-win32-arm64-msvc": "13.5.3", - "@next/swc-win32-ia32-msvc": "13.5.3", - "@next/swc-win32-x64-msvc": "13.5.3" + "@next/swc-darwin-arm64": "14.0.1", + "@next/swc-darwin-x64": "14.0.1", + "@next/swc-linux-arm64-gnu": "14.0.1", + "@next/swc-linux-arm64-musl": "14.0.1", + "@next/swc-linux-x64-gnu": "14.0.1", + "@next/swc-linux-x64-musl": "14.0.1", + "@next/swc-win32-arm64-msvc": "14.0.1", + "@next/swc-win32-ia32-msvc": "14.0.1", + "@next/swc-win32-x64-msvc": "14.0.1" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -3643,29 +3862,22 @@ } } }, - "node_modules/next/node_modules/postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - } - ], + "node_modules/node-abi": { + "version": "3.51.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", + "integrity": "sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==", "dependencies": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "semver": "^7.3.5" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">=10" } }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" + }, "node_modules/normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -3814,7 +4026,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -3963,10 +4174,9 @@ } }, "node_modules/postcss": { - "version": "8.4.29", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", - "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", - "dev": true, + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "funding": [ { "type": "opencollective", @@ -3981,7 +4191,6 @@ "url": "https://github.com/sponsors/ai" } ], - "peer": true, "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -4036,6 +4245,57 @@ "dev": true, "peer": true }, + "node_modules/prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/prebuild-install/node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/prebuild-install/node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -4063,6 +4323,15 @@ "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -4093,6 +4362,11 @@ } ] }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "node_modules/quick-lru": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", @@ -4106,6 +4380,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/rc/node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -4192,6 +4488,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/redent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz", @@ -4365,6 +4674,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -4391,7 +4719,6 @@ "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -4406,7 +4733,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -4417,8 +4743,29 @@ "node_modules/semver/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/sharp": { + "version": "0.32.6", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", + "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "hasInstallScript": true, + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", + "prebuild-install": "^7.1.1", + "semver": "^7.5.4", + "simple-get": "^4.0.1", + "tar-fs": "^3.0.4", + "tunnel-agent": "^0.6.0" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } }, "node_modules/shebang-command": { "version": "2.0.0", @@ -4427,36 +4774,92 @@ "dev": true, "peer": true, "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "peer": true, - "engines": { - "node": ">=8" + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "peer": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" } }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "is-arrayish": "^0.3.1" } }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -4564,6 +4967,11 @@ "dev": true, "peer": true }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, "node_modules/streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", @@ -4572,6 +4980,23 @@ "node": ">=10.0.0" } }, + "node_modules/streamx": { + "version": "2.15.2", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.2.tgz", + "integrity": "sha512-b62pAV/aeMjUoRN2C/9F0n+G8AfcJjNC0zw/ZmOHeFsIe4m4GzjVW9m6VHXVjk536NbdU9JRwKMJRfkc+zUFTg==", + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -5059,6 +5484,26 @@ "node": ">=6" } }, + "node_modules/tar-fs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "dependencies": { + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "node_modules/tar-stream": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -5141,6 +5586,17 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -5250,8 +5706,7 @@ "node_modules/universal-user-agent": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", - "dev": true + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" }, "node_modules/uri-js": { "version": "4.4.1", @@ -5266,9 +5721,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "peer": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/validate-npm-package-license": { "version": "3.0.4", @@ -5388,8 +5841,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/yargs-parser": { "version": "20.2.9", @@ -5413,14 +5865,6 @@ "funding": { "url": "https://github.com/sponsors/sindresorhus" } - }, - "node_modules/zod": { - "version": "3.21.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", - "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } } }, "dependencies": { @@ -5596,9 +6040,9 @@ "peer": true }, "@next/env": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/env/-/env-13.5.3.tgz", - "integrity": "sha512-X4te86vsbjsB7iO4usY9jLPtZ827Mbx+WcwNBGUOIuswuTAKQtzsuoxc/6KLxCMvogKG795MhrR1LDhYgDvasg==" + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/env/-/env-14.0.1.tgz", + "integrity": "sha512-Ms8ZswqY65/YfcjrlcIwMPD7Rg/dVjdLapMcSHG26W6O67EJDF435ShW4H4LXi1xKO1oRc97tLXUpx8jpLe86A==" }, "@next/eslint-plugin-next": { "version": "13.5.3", @@ -5626,57 +6070,57 @@ } }, "@next/swc-darwin-arm64": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.5.3.tgz", - "integrity": "sha512-6hiYNJxJmyYvvKGrVThzo4nTcqvqUTA/JvKim7Auaj33NexDqSNwN5YrrQu+QhZJCIpv2tULSHt+lf+rUflLSw==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.0.1.tgz", + "integrity": "sha512-JyxnGCS4qT67hdOKQ0CkgFTp+PXub5W1wsGvIq98TNbF3YEIN7iDekYhYsZzc8Ov0pWEsghQt+tANdidITCLaw==", "optional": true }, "@next/swc-darwin-x64": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.5.3.tgz", - "integrity": "sha512-UpBKxu2ob9scbpJyEq/xPgpdrgBgN3aLYlxyGqlYX5/KnwpJpFuIHU2lx8upQQ7L+MEmz+fA1XSgesoK92ppwQ==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.0.1.tgz", + "integrity": "sha512-625Z7bb5AyIzswF9hvfZWa+HTwFZw+Jn3lOBNZB87lUS0iuCYDHqk3ujuHCkiyPtSC0xFBtYDLcrZ11mF/ap3w==", "optional": true }, "@next/swc-linux-arm64-gnu": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.5.3.tgz", - "integrity": "sha512-5AzM7Yx1Ky+oLY6pHs7tjONTF22JirDPd5Jw/3/NazJ73uGB05NqhGhB4SbeCchg7SlVYVBeRMrMSZwJwq/xoA==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.0.1.tgz", + "integrity": "sha512-iVpn3KG3DprFXzVHM09kvb//4CNNXBQ9NB/pTm8LO+vnnnaObnzFdS5KM+w1okwa32xH0g8EvZIhoB3fI3mS1g==", "optional": true }, "@next/swc-linux-arm64-musl": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.5.3.tgz", - "integrity": "sha512-A/C1shbyUhj7wRtokmn73eBksjTM7fFQoY2v/0rTM5wehpkjQRLOXI8WJsag2uLhnZ4ii5OzR1rFPwoD9cvOgA==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.0.1.tgz", + "integrity": "sha512-mVsGyMxTLWZXyD5sen6kGOTYVOO67lZjLApIj/JsTEEohDDt1im2nkspzfV5MvhfS7diDw6Rp/xvAQaWZTv1Ww==", "optional": true }, "@next/swc-linux-x64-gnu": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.5.3.tgz", - "integrity": "sha512-FubPuw/Boz8tKkk+5eOuDHOpk36F80rbgxlx4+xty/U71e3wZZxVYHfZXmf0IRToBn1Crb8WvLM9OYj/Ur815g==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.0.1.tgz", + "integrity": "sha512-wMqf90uDWN001NqCM/auRl3+qVVeKfjJdT9XW+RMIOf+rhUzadmYJu++tp2y+hUbb6GTRhT+VjQzcgg/QTD9NQ==", "optional": true }, "@next/swc-linux-x64-musl": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.5.3.tgz", - "integrity": "sha512-DPw8nFuM1uEpbX47tM3wiXIR0Qa+atSzs9Q3peY1urkhofx44o7E1svnq+a5Q0r8lAcssLrwiM+OyJJgV/oj7g==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.0.1.tgz", + "integrity": "sha512-ol1X1e24w4j4QwdeNjfX0f+Nza25n+ymY0T2frTyalVczUmzkVD7QGgPTZMHfR1aLrO69hBs0G3QBYaj22J5GQ==", "optional": true }, "@next/swc-win32-arm64-msvc": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.5.3.tgz", - "integrity": "sha512-zBPSP8cHL51Gub/YV8UUePW7AVGukp2D8JU93IHbVDu2qmhFAn9LWXiOOLKplZQKxnIPUkJTQAJDCWBWU4UWUA==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.0.1.tgz", + "integrity": "sha512-WEmTEeWs6yRUEnUlahTgvZteh5RJc4sEjCQIodJlZZ5/VJwVP8p2L7l6VhzQhT4h7KvLx/Ed4UViBdne6zpIsw==", "optional": true }, "@next/swc-win32-ia32-msvc": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.5.3.tgz", - "integrity": "sha512-ONcL/lYyGUj4W37D4I2I450SZtSenmFAvapkJQNIJhrPMhzDU/AdfLkW98NvH1D2+7FXwe7yclf3+B7v28uzBQ==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.0.1.tgz", + "integrity": "sha512-oFpHphN4ygAgZUKjzga7SoH2VGbEJXZa/KL8bHCAwCjDWle6R1SpiGOdUdA8EJ9YsG1TYWpzY6FTbUA+iAJeww==", "optional": true }, "@next/swc-win32-x64-msvc": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.5.3.tgz", - "integrity": "sha512-2Vz2tYWaLqJvLcWbbTlJ5k9AN6JD7a5CN2pAeIzpbecK8ZF/yobA39cXtv6e+Z8c5UJuVOmaTldEAIxvsIux/Q==", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.0.1.tgz", + "integrity": "sha512-FFp3nOJ/5qSpeWT0BZQ+YE1pSMk4IMpkME/1DwKBwhg4mJLB9L+6EXuJi4JEwaJdl5iN+UUlmUD3IsR1kx5fAg==", "optional": true }, "@nodelib/fs.scandir": { @@ -5705,27 +6149,15 @@ "fastq": "^1.6.0" } }, - "@octokit/auth-action": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@octokit/auth-action/-/auth-action-4.0.1.tgz", - "integrity": "sha512-mJLOcFFafIivLZ7BEkGDCTFoHPJv7BeL5Zwy7j5qMDU0b/DKshhi6GCU9tw3vmKhOxTNquYfvwqsEfPpemaaxg==", - "dev": true, - "requires": { - "@octokit/auth-token": "^4.0.0", - "@octokit/types": "^12.0.0" - } - }, "@octokit/auth-token": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz", - "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==", - "dev": true + "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==" }, "@octokit/core": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.0.1.tgz", "integrity": "sha512-lyeeeZyESFo+ffI801SaBKmCfsvarO+dgV8/0gD8u1d87clbEdWsP5yC+dSj3zLhb2eIf5SJrn6vDz9AheETHw==", - "dev": true, "requires": { "@octokit/auth-token": "^4.0.0", "@octokit/graphql": "^7.0.0", @@ -5740,7 +6172,6 @@ "version": "9.0.1", "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.1.tgz", "integrity": "sha512-hRlOKAovtINHQPYHZlfyFwaM8OyetxeoC81lAkBy34uLb8exrZB50SQdeW3EROqiY9G9yxQTpp5OHTV54QD+vA==", - "dev": true, "requires": { "@octokit/types": "^12.0.0", "is-plain-object": "^5.0.0", @@ -5751,7 +6182,6 @@ "version": "7.0.2", "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz", "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==", - "dev": true, "requires": { "@octokit/request": "^8.0.1", "@octokit/types": "^12.0.0", @@ -5761,14 +6191,12 @@ "@octokit/openapi-types": { "version": "19.0.0", "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.0.0.tgz", - "integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw==", - "dev": true + "integrity": "sha512-PclQ6JGMTE9iUStpzMkwLCISFn/wDeRjkZFIKALpvJQNBGwDoYYi2fFvuHwssoQ1rXI5mfh6jgTgWuddeUzfWw==" }, "@octokit/plugin-paginate-rest": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.0.0.tgz", "integrity": "sha512-oIJzCpttmBTlEhBmRvb+b9rlnGpmFgDtZ0bB6nq39qIod6A5DP+7RkVLMOixIgRCYSHDTeayWqmiJ2SZ6xgfdw==", - "dev": true, "requires": { "@octokit/types": "^12.0.0" } @@ -5777,14 +6205,12 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-4.0.0.tgz", "integrity": "sha512-2uJI1COtYCq8Z4yNSnM231TgH50bRkheQ9+aH8TnZanB6QilOnx8RMD2qsnamSOXtDj0ilxvevf5fGsBhBBzKA==", - "dev": true, "requires": {} }, "@octokit/plugin-rest-endpoint-methods": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.0.0.tgz", "integrity": "sha512-16VkwE2v6rXU+/gBsYC62M8lKWOphY5Lg4wpjYnVE9Zbu0J6IwiT5kILoj1YOB53XLmcJR+Nqp8DmifOPY4H3g==", - "dev": true, "requires": { "@octokit/types": "^12.0.0" } @@ -5793,7 +6219,6 @@ "version": "8.1.2", "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.2.tgz", "integrity": "sha512-A0RJJfzjlZQwb+39eDm5UM23dkxbp28WEG4p2ueH+Q2yY4p349aRK/vcUlEuIB//ggcrHJceoYYkBP/LYCoXEg==", - "dev": true, "requires": { "@octokit/endpoint": "^9.0.0", "@octokit/request-error": "^5.0.0", @@ -5806,7 +6231,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz", "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==", - "dev": true, "requires": { "@octokit/types": "^12.0.0", "deprecation": "^2.0.0", @@ -5817,7 +6241,6 @@ "version": "20.0.2", "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", - "dev": true, "requires": { "@octokit/core": "^5.0.0", "@octokit/plugin-paginate-rest": "^9.0.0", @@ -5829,7 +6252,6 @@ "version": "12.0.0", "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.0.0.tgz", "integrity": "sha512-EzD434aHTFifGudYAygnFlS1Tl6KhbTynEWELQXIbTY8Msvb5nEqTZIm7sbPEt4mQYLZwu3zPKVdeIrw0g7ovg==", - "dev": true, "requires": { "@octokit/openapi-types": "^19.0.0" } @@ -6063,6 +6485,14 @@ "color-convert": "^1.9.0" } }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, "aria-query": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", @@ -6215,17 +6645,36 @@ "dequal": "^2.0.3" } }, + "b4a": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", + "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, "before-after-hook": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "dev": true + "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } }, "brace-expansion": { "version": "1.1.11", @@ -6246,6 +6695,15 @@ "fill-range": "^7.0.1" } }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, "busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -6317,11 +6775,40 @@ "supports-color": "^5.3.0" } }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, "client-only": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "requires": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "dependencies": { + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + } + } + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -6335,9 +6822,16 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "peer": true + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } }, "colord": { "version": "2.9.3", @@ -6433,6 +6927,19 @@ } } }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "requires": { + "mimic-response": "^3.1.0" + } + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, "deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -6453,8 +6960,7 @@ "deprecation": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true + "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" }, "dequal": { "version": "2.0.3", @@ -6462,6 +6968,11 @@ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", "dev": true }, + "detect-libc": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", + "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==" + }, "dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -6487,6 +6998,14 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, "enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", @@ -7003,6 +7522,11 @@ "eslint-visitor-keys": "^3.4.1" } }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, "esquery": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", @@ -7035,6 +7559,11 @@ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "dev": true }, + "expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==" + }, "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -7042,6 +7571,11 @@ "dev": true, "peer": true }, + "fast-fifo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", + "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==" + }, "fast-glob": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", @@ -7154,6 +7688,19 @@ "is-callable": "^1.1.3" } }, + "front-matter": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", + "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==", + "requires": { + "js-yaml": "^3.13.1" + } + }, + "fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -7215,6 +7762,11 @@ "resolve-pkg-maps": "^1.0.0" } }, + "github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" + }, "glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -7429,6 +7981,11 @@ "dev": true, "peer": true }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "ignore": { "version": "5.2.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", @@ -7489,15 +8046,12 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "peer": true + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "internal-slot": { "version": "1.0.5", @@ -7657,8 +8211,7 @@ "is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==" }, "is-regex": { "version": "1.1.4", @@ -7768,6 +8321,15 @@ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", @@ -7904,6 +8466,11 @@ "dev": true, "peer": true }, + "marked": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.2.tgz", + "integrity": "sha512-qoKMJqK0w6vkLk8+KnKZAH6neUZSNaQqVZ/h2yZ9S7CbLuFHyS2viB0jnqcWF9UKjwsAbMrQtnQhdmdvOVOw9w==" + }, "mathml-tag-names": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", @@ -7957,6 +8524,11 @@ "picomatch": "^2.3.1" } }, + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==" + }, "min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -7976,8 +8548,7 @@ "minimist": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" }, "minimist-options": { "version": "4.1.0", @@ -8000,6 +8571,11 @@ } } }, + "mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==" + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -8011,6 +8587,11 @@ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==" }, + "napi-build-utils": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz", + "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==" + }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -8018,41 +8599,41 @@ "dev": true }, "next": { - "version": "13.5.3", - "resolved": "https://registry.npmjs.org/next/-/next-13.5.3.tgz", - "integrity": "sha512-4Nt4HRLYDW/yRpJ/QR2t1v63UOMS55A38dnWv3UDOWGezuY0ZyFO1ABNbD7mulVzs9qVhgy2+ppjdsANpKP1mg==", - "requires": { - "@next/env": "13.5.3", - "@next/swc-darwin-arm64": "13.5.3", - "@next/swc-darwin-x64": "13.5.3", - "@next/swc-linux-arm64-gnu": "13.5.3", - "@next/swc-linux-arm64-musl": "13.5.3", - "@next/swc-linux-x64-gnu": "13.5.3", - "@next/swc-linux-x64-musl": "13.5.3", - "@next/swc-win32-arm64-msvc": "13.5.3", - "@next/swc-win32-ia32-msvc": "13.5.3", - "@next/swc-win32-x64-msvc": "13.5.3", + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/next/-/next-14.0.1.tgz", + "integrity": "sha512-s4YaLpE4b0gmb3ggtmpmV+wt+lPRuGtANzojMQ2+gmBpgX9w5fTbjsy6dXByBuENsdCX5pukZH/GxdFgO62+pA==", + "requires": { + "@next/env": "14.0.1", + "@next/swc-darwin-arm64": "14.0.1", + "@next/swc-darwin-x64": "14.0.1", + "@next/swc-linux-arm64-gnu": "14.0.1", + "@next/swc-linux-arm64-musl": "14.0.1", + "@next/swc-linux-x64-gnu": "14.0.1", + "@next/swc-linux-x64-musl": "14.0.1", + "@next/swc-win32-arm64-msvc": "14.0.1", + "@next/swc-win32-ia32-msvc": "14.0.1", + "@next/swc-win32-x64-msvc": "14.0.1", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", - "postcss": "8.4.14", + "postcss": "8.4.31", "styled-jsx": "5.1.1", - "watchpack": "2.4.0", - "zod": "3.21.4" - }, - "dependencies": { - "postcss": { - "version": "8.4.14", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", - "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", - "requires": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - } + "watchpack": "2.4.0" + } + }, + "node-abi": { + "version": "3.51.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", + "integrity": "sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA==", + "requires": { + "semver": "^7.3.5" } }, + "node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==" + }, "normalize-package-data": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", @@ -8162,7 +8743,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "requires": { "wrappy": "1" } @@ -8269,11 +8849,9 @@ "dev": true }, "postcss": { - "version": "8.4.29", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", - "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", - "dev": true, - "peer": true, + "version": "8.4.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", + "integrity": "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==", "requires": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", @@ -8313,6 +8891,50 @@ "dev": true, "peer": true }, + "prebuild-install": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz", + "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==", + "requires": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^1.0.1", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "dependencies": { + "tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "requires": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "requires": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + } + } + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -8339,6 +8961,15 @@ } } }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "punycode": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", @@ -8352,6 +8983,11 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", "dev": true }, + "queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==" + }, "quick-lru": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", @@ -8359,6 +8995,24 @@ "dev": true, "peer": true }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" + } + } + }, "react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -8419,6 +9073,16 @@ } } }, + "readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, "redent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-4.0.0.tgz", @@ -8529,6 +9193,11 @@ "isarray": "^2.0.5" } }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, "safe-regex-test": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", @@ -8552,7 +9221,6 @@ "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, "requires": { "lru-cache": "^6.0.0" }, @@ -8561,7 +9229,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "requires": { "yallist": "^4.0.0" } @@ -8569,11 +9236,25 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, + "sharp": { + "version": "0.32.6", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.6.tgz", + "integrity": "sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==", + "requires": { + "color": "^4.2.3", + "detect-libc": "^2.0.2", + "node-addon-api": "^6.1.0", + "prebuild-install": "^7.1.1", + "semver": "^7.5.4", + "simple-get": "^4.0.1", + "tar-fs": "^3.0.4", + "tunnel-agent": "^0.6.0" + } + }, "shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8602,6 +9283,36 @@ "object-inspect": "^1.9.0" } }, + "simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==" + }, + "simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "requires": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" + } + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -8690,11 +9401,33 @@ "dev": true, "peer": true }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + }, "streamsearch": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" }, + "streamx": { + "version": "2.15.2", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.2.tgz", + "integrity": "sha512-b62pAV/aeMjUoRN2C/9F0n+G8AfcJjNC0zw/ZmOHeFsIe4m4GzjVW9m6VHXVjk536NbdU9JRwKMJRfkc+zUFTg==", + "requires": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", @@ -9048,6 +9781,26 @@ "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", "dev": true }, + "tar-fs": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", + "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", + "requires": { + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + } + }, + "tar-stream": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", + "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", + "requires": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -9112,6 +9865,14 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -9190,8 +9951,7 @@ "universal-user-agent": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==", - "dev": true + "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" }, "uri-js": { "version": "4.4.1", @@ -9206,9 +9966,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "peer": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "validate-npm-package-license": { "version": "3.0.4", @@ -9301,8 +10059,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "yargs-parser": { "version": "20.2.9", @@ -9317,11 +10074,6 @@ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", "dev": true, "peer": true - }, - "zod": { - "version": "3.21.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", - "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==" } } } diff --git a/package.json b/package.json index f06e4e3..29da049 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,15 @@ "version": "0.1.0", "private": true, "dependencies": { + "@octokit/auth-token": "^4.0.0", + "@octokit/rest": "^20.0.1", + "front-matter": "^4.0.2", "highlight.js": "^11.8.0", - "next": "^13.5.3", + "marked": "^9.1.2", + "next": "^14.0.1", "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "sharp": "^0.32.6" }, "scripts": { "prestart": "node generateAssets.js", @@ -35,8 +40,6 @@ ] }, "devDependencies": { - "@octokit/auth-action": "^4.0.1", - "@octokit/rest": "^20.0.1", "@types/node": "^20.6.5", "@types/react": "^18.2.22", "@types/react-dom": "^18.2.7", diff --git a/public/blog/birthday/article.md b/public/blog/birthday/article.md new file mode 100644 index 0000000..3e9bcdd --- /dev/null +++ b/public/blog/birthday/article.md @@ -0,0 +1,721 @@ +--- +title: "Happy first birthday Draco compiler!" +date: 2023-10-09 18:23:00 +0200 +teaser: "🎉 Celebrating Draco compiler's 1st birthday! Dive into a year of code, community, and incredible milestones. Let's rewind and relive the journey!" +image: "/generated/party.svg" +imageMargin: "20px" +imageHeight: "200px" +tags: meta +authors: ["LPeter1997"] +makeSocialEmbedBig: false +--- + +I'd like to go through the first year of Draco compiler development, highlighting major milestones. This first year was full of exciting, sudden contributions and some extremely active time periods. I'm hoping the project will grow throughout the years, and this won't be the only yearly history diary I'll be able to write. + +## In the beginning... + +Early on, we decided that we'd rely on as few external tools, as possible. It's easy to progress quickly with tools like ANTLR or high(er)-level code generation, like `System.Reflection.Emit`, but eventually it will be a blocker for some issues - like proper error recovery or tree format. At that point, we would be locked in, and would have to spend huge efforts into just tearing out the old solution and developing the replacement. That said, the DIY approach made the beginning very slow and humble. + +Please note, that we didn't have visualization tools in the beginning, and didn't target formats like Graphviz DOT until much later. To make this retrospective more authentic, I'll always use the output formats our compiler supported at the time. + +- 2022 9th of October: Initial commit, README updates +- 2022 13th of October: Initial Lexer + +At this point, the following code: + +```draco +// Simple hello world +from System.Console import { WriteLine }; + +func main() { + WriteLine("Hello, World!"); +} +``` + +Produced this sequence of tokens: + +``` +"from": KeywordFrom + leading trivia: ["// Simple hello world": LineComment, "\n": Newline] + trailing trivia: [" ": Whitespace] +"System": Identifier +".": Dot +"Console": Identifier + trailing trivia: [" ": Whitespace] +"import": KeywordImport + trailing trivia: [" ": Whitespace] +"{": CurlyOpen + trailing trivia: [" ": Whitespace] +"WriteLine": Identifier + trailing trivia: [" ": Whitespace] +"}": CurlyClose +";": Semicolon + trailing trivia: ["\n": Newline] +"func": KeywordFunc + leading trivia: ["\n": Newline] + trailing trivia: [" ": Whitespace] +"main": Identifier +"(": ParenOpen +")": ParenClose + trailing trivia: [" ": Whitespace] +"{": CurlyOpen + trailing trivia: ["\n": Newline] +"WriteLine": Identifier + leading trivia: [" ": Whitespace] +"(": ParenOpen +""": LineStringStart +"Hello, World!": StringContent +""": LineStringEnd +")": ParenClose +";": Semicolon + trailing trivia: ["\n": Newline] +"}": CurlyClose +"": EndOfInput +``` + +As you can see, our decision was to keep semantically insignificant details - like spacing and comments - attached to the tokens. This, as many other decisions were inspired by the wonderful [Roslyn project](https://github.com/dotnet/roslyn). + +- 2022 14th of October: Parse tree declarations, [EditorConfig](https://editorconfig.org/) setup +- 2022 15th of October: Lexer tests, CI setup +- 2022 16th Of October: Initial parser + +Another important milestone, we are finally structuring tokens into a tree. The following code: + +```draco +func main() { + var x: int32 = 0; + if (x > 0) { + WriteLine("x > 0"); + } +} +``` + +Gets structured into the following tree: + +``` +CompilationUnit { + Declarations: [ + Func { + FuncKeyword: 'func', + Identifier: 'main', + Params: Enclosed { + OpenToken: '(', + Value: [], + CloseToken: ')', + }, + ReturnType: null, + Body: BlockBody { + Block: Block { + Enclosed: Enclosed { + OpenToken: '{', + Value: ( + Item1: [ + Decl { + Declaration: Variable { + Keyword: 'var', + Identifier: 'x', + Type: TypeSpecifier { + ColonToken: ':', + Type: Name { + Identifier: 'int32', + }, + }, + Initializer: ( + Item1: '=', + Item2: Literal { + Value: '0', + }, + ), + Semicolon: ';', + }, + }, + ], + Item2: If { + IfKeyword: 'if', + Condition: Enclosed { + OpenToken: '(', + Value: Relational { + Left: Name { + Identifier: 'x', + }, + Comparisons: [ + ( + Item1: '>', + Item2: Literal { + Value: '0', + }, + ), + ], + }, + CloseToken: ')', + }, + Then: UnitStmt { + Statement: Expr { + Expression: Block { + Enclosed: Enclosed { + OpenToken: '{', + Value: ( + Item1: [ + Expr { + Expression: Call { + Called: Name { + Identifier: 'WriteLine', + }, + Args: Enclosed { + OpenToken: '(', + Value: [ + Punctuated { + Value: String { + OpenQuotes: '"', + Parts: [ + Content { + Token: 'x > 0', + }, + ], + CloseQuotes: '"', + }, + Punctuation: null, + }, + ], + CloseToken: ')', + }, + }, + Semicolon: ';', + }, + ], + Item2: null, + ), + CloseToken: '}', + }, + }, + Semicolon: null, + }, + }, + Else: null, + }, + ), + CloseToken: '}', + }, + }, + }, + }, + ], +} +``` + +- 2022 17th of October: Parser recovery improvements +- 2022 22nd of October: Completed lexer test suite, bugfixes +- 2022 23rd of October: Generating [red-green trees](https://blog.yaakov.online/red-green-trees/) and visitor for the parse tree +- 2022 24th of October: Initial public API and CLI +- 2022 25th of October: Parser tests and fixes + +## The wild west + +After having the lexer and parser more-or-less done, having them backed up with test cases, it was time to move on to the more interesting parts of the compiler. I'd like to call this portion the "wild west", as contributors started to experiment by branching out into different topics, even ones that are less fundamental to the core compiler. Of course these experiments made the whole project all more exciting. + +- 2022 26th of October: Basic C# code-generation + +After all, why not? We didn't have any semantic checks in place, but a syntax-based transpiler was a cheap way to motivate us by showing the running language. + +Example Draco program: + +```draco +func abs(n: int32): int32 = + if (n < 0) -n + else n; + +func fib(n: int32): int32 = + if (n < 2) 1 + else fib(n - 1) + fib(n - 2); + +func main() { + println("Hello, \{1} + \{2} is \{1 + 2}"); + println("|-12| = \{abs(-12)}"); + println("fib(5) = \{fib(5)}"); + println(""" + Hello, Multi line strings! + I hope this works! + """); + println('\u{1F47D}'); + println("Hello,\nNewlines!"); +} +``` + +And the absolutely atrocious C# it transpiled to (keep in mind, we didn't have type information yet!): + +```cs +using static Prelude; +internal static class Prelude +{ +    public record struct Unit; +    public record struct Char32(int Codepoint) +    { +        public override string ToString() => +            char.ConvertFromUtf32(this.Codepoint); +    } +    public static Unit print(dynamic value) +    { +        System.Console.Write(value); +        return default; +    } +    public static Unit println(dynamic value) +    { +        System.Console.WriteLine(value); +        return default; +    } +} +internal sealed class Program +{ +    internal static void Main(string[] args) => DracoProgram.main(); +} +internal sealed class DracoProgram +{ +    internal static dynamic abs(dynamic n) +    { +        dynamic reg_0 = default(Unit); +        dynamic reg_1 = false; +        if (n < 0) { +            reg_1 = true; +        } +        if (!reg_1) goto label_0; +        dynamic reg_2 = - n; +        reg_0 = n; +        goto label_1; +    label_0:; +        reg_0 = n; +    label_1:; +        return reg_0; +        return default(Unit); +    } +    internal static dynamic fib(dynamic n) +    { +        dynamic reg_3 = default(Unit); +        dynamic reg_4 = false; +        if (n < 2) { +            reg_4 = true; +        } +        if (!reg_4) goto label_2; +        reg_3 = 1; +        goto label_3; +    label_2:; +        dynamic reg_6 = n - 1; +        dynamic reg_7 = fib(reg_6); +        dynamic reg_8 = n - 2; +        dynamic reg_9 = fib(reg_8); +        dynamic reg_5 = reg_7 + reg_9; +        reg_3 = reg_5; +    label_3:; +        return reg_3; +        return default(Unit); +    } +    internal static dynamic main() +    { +        dynamic reg_10 = new System.Text.StringBuilder(); +        reg_10.Append(\"Hello, \"); +        reg_10.Append(1.ToString()); +        reg_10.Append(\" + \"); +        reg_10.Append(2.ToString()); +        reg_10.Append(\" is \"); +        dynamic reg_11 = 1 + 2; +        reg_10.Append(reg_11.ToString()); +        dynamic reg_12 = println(reg_10.ToString()); +        dynamic reg_13 = new System.Text.StringBuilder(); +        reg_13.Append(\"|-12| = \"); +        dynamic reg_14 = - 12; +        dynamic reg_15 = abs(12); +        reg_13.Append(reg_15.ToString()); +        dynamic reg_16 = println(reg_13.ToString()); +        dynamic reg_17 = new System.Text.StringBuilder(); +        reg_17.Append(\"fib(5) = \"); +        dynamic reg_18 = fib(5); +        reg_17.Append(reg_18.ToString()); +        dynamic reg_19 = println(reg_17.ToString()); +        dynamic reg_20 = new System.Text.StringBuilder(); +        reg_20.Append(\"Hello, Multi line strings!\"); +        reg_20.Append(\"\\n\"); +        reg_20.Append(\"I hope this works!\"); +        dynamic reg_21 = println(reg_20.ToString()); +        dynamic reg_22 = println(new Char32(128125)); +        dynamic reg_23 = new System.Text.StringBuilder(); +        reg_23.Append(\"Hello,\\nNewlines!\"); +        dynamic reg_24 = println(reg_23.ToString()); +        return default(Unit); +    } +} +``` + +Our compiler finally executed simple programs! Admittedly, we didn't have any type-safety yet and we did invoke Roslyn to compile down the emitted C# code, but this was a major milestone in our eyes. + +- 2022 27th of October: Web-compiler in Blazor, TextMate syntax highlighting + +I woke up to one of the contributors putting the entire compiler in Blazor, so we could host a playground in a website. This completely blew my mind! Our little compiler, already on web! + +![image](https://github.com/Draco-lang/Compiler/assets/7904867/a5027f56-2c27-4550-beb2-3f335397f79e) + +While looking simplistic, it already had features such as running, displaying the transpiled C#, or the compiler .NET IL. It also has the feature to share code snippets through the URL, just like [SharpLab](https://sharplab.io/) does. To this day, some contributors use these URLs to share programs/bugs between each other. + +This initiative is one of my favorites in the project. It shows, that there is so much more to a language than the compiler, and this makes the project all that more interesting. + +This same day started the development of our VS Code extension. All we had back then, was syntax highlighting with some basic TextMate definitions. + +- 2022 28th of October: Publish the web editor on our github.io site +- 2022 29th of October: Hotfixes around the web editor +- 2022 4th of November: Initial query system + +This is an interesting one! Inspired by projects like [Salsa](https://github.com/salsa-rs/salsa), we wanted a general approach to incremental compiler frontends. One of our contributors showed us, how we can hijack the async state machine of C# to make this more seamless. The gist of it was this: + +Computations we wanted to be incremental and their results memoized, we returned the `QueryValueTask` type for it, similarly how `Task` and `ValueTask` would be for regular async: + +```cs +QueryValueTask DoComputation(QueryDatabase db, T1 arg1, ...) +{ + ... +} +``` + +Whenever we called a function like the above, the call only happened, if the method wasn't called with these parameters yet, or one of the dependencies changed. If anyone is interested, details can be found in [this issue](https://github.com/Draco-lang/Compiler/issues/68). + +The solution was not long lived. While it sounded good in theory, we had more problems with it than it was worth, and ultimately went for a manual memoization solution, that was also replaced by the architecture we have today. Either way, it was a very interesting experiment, and showed how hackable C# was with its features. + +- 2022 5th of November: `Result` type implemented +- 2022 6th of November: a bunch of things + - Diagnostics wired out into public API + - Initial Language Server + - More extensive parser test suite + - Merge the compiler API and internals project into one + +The Language Server was born, which can be used in a bunch of editors to this day, but the main target was always the VS Code extension. We utilized the [OmniSharp-LSP implementation](https://github.com/OmniSharp/csharp-language-server-protocol), something we would regret later. All our Language Server did at this point was showed diagnostics at the appropriate location and did some basic semantic highlighting. + +![image](https://github.com/Draco-lang/Compiler/assets/7904867/fe24e659-402a-4cb9-9492-c7d72cf44908) + +- 2022 7th of November: Code cleanup, simplifications, bugfixes +- 2022 8th of November: Floating point literals +- 2022 11th of November: .NET 6 to .NET 7 update, reproducible builds +- 2022 12th of November: Mutation testing, CLI update, public API update, web editor rewrite +- 2022 13th of November: Red-green tree rewriting utility, web editor updates +- 2022 15th of November: Lexer and parser test suite extension +- 2022 18th of November: Web editor dependency updates, codegen fixes +- 2022 20th of November: Symbol resolution implemented, threw out the query system, misc. fixes + +This was the first major semantic check implemented. Now the user couldn't just reference a non-existing name, the variable or function had to be declared appropriately. Shadowing support was also added. This addition improved the codegen accuracy by a lot, especially because C# does not support local variable shadowing. + +- 2022 22nd of November: Basic AST structure implemented +- 2022 23rd of November: Stripped off state from the parser +- 2022 24th of November: Code formatting cleanup +- 2022 26th of November: CI tweaks, `Option` type, initial formatter + +This was another really interesting contribution, we could finally press Alt-Shift-F in VS Code, and got the code more-or-less formatted! We use this same formatter engine to this day. There are plans to improve it with [ideas from a very famous blog post](https://journal.stuffwithstuff.com/2015/09/08/the-hardest-program-ive-ever-written/), but it hasn't bothered us enough yet to tackle it. + +- 2022 27th of November: Codegen fixes +- 2022 7th of December: Web editor theming fixes +- 2022 8th of December: Separated the concept of Token and Trivia +- 2022 11th of December: Web editor uses a web-worker to run the compiler +- 2022 12th of December: Type-checker, type-inference + +Yet another major milestone for the compiler: we have type-safety, and some basic type-inference is in place as well! This means that the compiler does not just crash on type-unsafe code, but - for the most part - reports an appropriate error message. This meant, that we could finally turn our parse-tree into the well-typed AST, and update our codegen to utilize the type-information. + +The absolute-value and Fibonacci functions recompiled with this version of the compiler yields the following C# code: + +```cs +internal sealed class DracoProgram +{ + static DracoProgram() + { + } + internal static System.Int32 abs(System.Int32 sym_1) + { + System.Int32 reg_0; + System.Boolean reg_1 = sym_1 < 0; + if (!reg_1) goto label_0; + System.Int32 reg_2 = -sym_1; + reg_0 = reg_2; + goto label_1; + label_0:; + reg_0 = sym_1; + label_1:; + return reg_0; + } + internal static System.Int32 fib(System.Int32 sym_3) + { + System.Int32 reg_3; + System.Boolean reg_4 = sym_3 < 2; + if (!reg_4) goto label_2; + reg_3 = 1; + goto label_3; + label_2:; + System.Int32 reg_5 = sym_3 - 1; + System.Int32 reg_6 = fib(reg_5); + System.Int32 reg_7 = sym_3 - 2; + System.Int32 reg_8 = fib(reg_7); + System.Int32 reg_9 = reg_6 + reg_8; + reg_3 = reg_9; + label_3:; + return reg_3; + } +} +``` + +This looks way tidier, it finally resembles a register machine target language. More importantly, all the `dynamic` is gone. + +- 2022 14th of December: Syntax factory utility, start of e2e testing +- 2022 17th of December: Semantic test suite introduced +- 2022 18th of December: README update, typechecking fixes +- 2022 23rd of December: Rework around location info +- 2022 30th of December: Go-to definition for the Language Server +- 2022 31st of December: Our internal IR and CIL compilation + +Another milestone reached! We are now compiling to our custom, register-based IR, which is then translated to CIL, using the `System.Reflection.Metadata` APIs. The reason we are bothering with an IR, is because we want to do optimizations that the JIT does not do, like vectorization. In fact, our compiler already does 3 small optimization steps to make the output nicer: jump-threading, dead block elimination and - the only "real" optimization - tail-call optimization. + +Let's take a look at the IR and CIL of the `fib` function now. The Draco IR: + +``` +assembly 'Output'; +proc System.Int32 fib(System.Int32 n): +locals ( + System.Int32 +) +label bb_5: + System.Boolean reg_3 = less n, 2 + jmp_if reg_3, bb_6, bb_7 +label bb_6: + store , 1 + jmp bb_8 +label bb_7: + System.Int32 reg_4 = sub n, 1 + System.Int32 reg_5 = call fib, [reg_4] + System.Int32 reg_6 = sub n, 2 + System.Int32 reg_7 = call fib, [reg_6] + System.Int32 reg_8 = add reg_5, reg_7 + store , reg_8 + jmp bb_8 +label bb_8: + System.Int32 reg_9 = load + ret reg_9 +``` + +The CIL: + +```msil +.method public hidebysig static int32 fib (int32 n) cil managed +{ +    // Method begins at RVA 0x2088 +    // Header size: 12 +    // Code size: 68 (0x44) +    .maxstack 8 +    .locals ( +        [0] int32, +        [1] bool, +        [2] int32, +        [3] int32, +        [4] int32, +        [5] int32, +        [6] int32, +        [7] int32 +    ) +    IL_0000: ldarg.1 +    IL_0001: ldc.i4.2 +    IL_0002: clt +    IL_0004: stloc.1 +    IL_0005: ldloc.1 +    IL_0006: brtrue IL_0010 +    IL_000b: br IL_0017 +    IL_0010: ldc.i4.1 +    IL_0011: stloc.0 +    IL_0012: br IL_003e +    IL_0017: ldarg.1 +    IL_0018: ldc.i4.1 +    IL_0019: sub +    IL_001a: stloc.2 +    IL_001b: ldloc.2 +    IL_001c: call int32 FreeFunctions::fib(int32) +    IL_0021: stloc.3 +    IL_0022: ldarg.1 +    IL_0023: ldc.i4.2 +    IL_0024: sub +    IL_0025: stloc.s 4 +    IL_0027: ldloc.s 4 +    IL_0029: call int32 FreeFunctions::fib(int32) +    IL_002e: stloc.s 5 +    IL_0030: ldloc.3 +    IL_0031: ldloc.s 5 +    IL_0033: add +    IL_0034: stloc.s 6 +    IL_0036: ldloc.s 6 +    IL_0038: stloc.0 +    IL_0039: br IL_003e +    IL_003e: ldloc.0 +    IL_003f: stloc.s 7 +    IL_0041: ldloc.s 7 +    IL_0043: ret +} // end of method FreeFunctions::fib +``` + +As you can see, while the IR is quite compact, the CIL is very suboptimal (and incorrect, but let's ignore that one for now). This is because the IR uses a register-based, SSA form, while CIL is stack-based. The simplistic conversion we chose is that for each register, we simply allocate a local. This means that a lot of useless copies are made. We are planning to solve this with a process that [LLVM calls stackification](https://llvm.org/doxygen/WebAssemblyRegStackify_8cpp_source.html), which they do for WASM for this exact same situation. This is not implemented to this day, but a prototype is actively being worked on. + +## Race to release + +At this point, the compiler flow was (almost) complete, we had a basic test-suite, a web editor, a language server, ... All that was left, was to fill in the blanks, and implement features we were planning to ship with the first compiler release. The work was more laid-out for us, we saw the goal we wanted to achieve. + +- 2023 1st of January: README updates, find-all-references added for the Language Server +- 2023 2nd of January: Documentation comments, show documentation for symbols on hover in the Language Server + +At this point we were also making efforts to retarget the compiler to .NET Standard 2.0, something we would eventually revert and stick to the latest .NET. + +- 2023 7th of January: Tore out mutation testing, CIL codegen fixes +- 2023 11th of January: Out of process execution for the web editor, README updates, concept of error codes introduced +- 2023 13th of January: Icon theming for VS Code extension, web editor fixes, Language Server CLI introduction +- 2023 14th of January: Data flow analysis, crash fixes + +With this addition, the compiler flow is finally 100% complete. Any more crash or unreported error has to be a bug in the compiler. We detect methods that don't return on all paths, variable usages before initialization, ... + +At this stage, dataflow analysis is done on a dataflow graph that is constructed from the AST. This seemed as a great idea at the time, but due to multiple reasons, we will eventually replace it. + +- 2023 15th of January: Code style fixes, `break` and `continue` labels introduced +- 2023 16th of January: .NET SDK integration, bugfixes, test suite extension, project templates, first toolset deployment + +This is **HUGE**. We could finally have a project file with our source code and issue a `dotnet build` or `dotnet run`, just like with other languages. Users could install the project template from NuGet, then issue a `dotnet new console --language Draco` to create a Draco project. The SDK would be recognized and automatically downloaded by .NET. We finally felt like the compiler is a proper part of the ecosystem. + +## To be like Roslyn <3 + +The next section is completely about filling in the blanks, expanding on what we have, improving code quality, and most importantly of all: get the architecture closer to Roslyn. + +- 2023 19th of January: Language Server and VS Code extensions released, CI fixes +- 2023 20th of January: VS Code extension hotfix +- 2023 22nd of January: Floats added to codegen, codegen fixes, CI fixes +- 2023 29th of January: Web editor visual updates +- 2023 4th of February: Scientific notation for floats, formatter fixes +- 2023 5th of February: Rewrote Red-Green Tree generation to use XML, just like Roslyn, utility scripts added +- 2023 26th of February: Web editor UI overhaul +- 2023 27th of February: Web editor fixes +- 2023 19th of March: Getting started guide, source code reader API rework, ICE reporting +- 2023 25th of March: Complete internals rework + +To this day, this is [one of the largest PRs merged](https://github.com/Draco-lang/Compiler/pull/199) in the project. It is a huge step towards the long-running intent to bring the architecture closer to Roslyn. We eliminated the query system, introduced the concept of binding, generate the bound tree, its visitors and rewriters from XML, exposed the `SemanticModel` in the API, ... This rework resulted in the structure that we more-or-less stuck with since then. + +- 2023 29th of March: Syntax tree utilities +- 2023 30th of March: LSP reimplementation + +As foreshadowed, choosing OmniSharp for the Language Server came back to haunt us. The implementation was outdated, overengineered, and overall [just a pain to work with](https://github.com/Draco-lang/Compiler/pull/217#issuecomment-1500973656). We decided to bite the bullet, and do the hard work. We reimplemented LSP as a reusable, extensible package that generated the contracts right from the specification. It is easy to use, update and extend with features we need. The only thing we did not implement ourselves was the JSON-RPC communication, we used [StreamJsonRpc](https://github.com/microsoft/vs-streamjsonrpc) for that - something, that we would regret later. + +- 2023 2nd of April: Settings to turn inlay-hints on/off in the Language Server, `SemanticModel` fixes +- 2023 4th of April: Introduction of Fuzz testing +- 2023 5th of April: Refactoring in `SemanticModel` +- 2023 6th of April: Complete IR and CIL codegen rework, flow analysis rework, eliminating the need for dataflow graphs +- 2023 7th of April: Local functions support +- 2023 16th of April: Metadata imports + +An _extremely_ exciting addition: we finally interact with the ecosystem! No longer do we need intrinsics to be able to print something, we can just reference `System.Console`! A sample taken from this era, showcasing interaction with the BCL: + +```draco +import System.Console; +import System.Text; + +func main() { + var sb = StringBuilder(); + sb.Append("Hello, "); + sb.Append(123); + sb.Append(true); + sb.Append(" - and bye!"); + Write(sb.ToString()); +} +``` + +- 2023 18th of April: Web editor theming fixes +- 2023 20th of April: Semantic model rework, qualified type references, crash fixes + +## Tooling? We got tooling! + +At this point, the compiler architecture became stable - at least, there weren't major restructurings since then. We could finally focus on finishing the remaining language features, and more importantly, make the tooling nice to use. + +- 2023 24th of April: Code completions in the Language Server + +![image](https://github.com/Draco-lang/Compiler/assets/7904867/054dd820-da7a-4ad2-a8cf-9e6c565d0ebd) + +This was a beautiful sight to see. While the initial implementation wasn't perfect, it already felt great that we didn't have to remember/type out every single name in a namespace. + +- 2023 25th of April: Multiline string cutoff fix +- 2023 30th of April: Rework around overloading +- 2023 6th of May: Generate LSP messages from the metamodel instead of Markdown +- 2023 9th of May: Replace JSON-RPC with out own implementation under LSP, crash fix +- 2023 18th of May: Module system + +This took a surprisingly long time, but it's finally here. The source code isn't a single file anymore. It can be split into multiple files, the code can be organized into submodules, just like in most other programming languages. + +- 2023 21st of May: Basic generics implementation + +This took quite a long time. It introduced many-many edges in the type-inference algorithm, which resulted in reworking the constraint solver behind it many-many times. Eventually we got there, and the reward was that a huge chunk of the BCL unlocked before us. Most excitingly, collections: + +```draco +import System.Console; +import System.Collections.Generic; + +public func main() { + val s = Stack(); // Inferred to be Stack from use + s.Push(1); + s.Push(2); + Write(s.Pop()); + Write(s.Pop()); +} +``` + +- 2023 29th of May: .NET debugger developed, debugger TUI + +We wanted to start working on the debugger experience, but there were a few problems: the debugger shipped by Microsoft was closed-source, and the [one by Samsung](https://github.com/Samsung/netcoredbg) was written in mostly C++. This sadly didn't suit our wishes, as we would have wanted an open-source and truly cross-platform debugger, written in .NET instead of native code. After a lot of research, we have developed a general-purpose .NET debugging API, that we can later use to develop our debugger. To test the API, we have written a TUI for it using the wonderful [Terminal.Gui](https://github.com/gui-cs/Terminal.Gui) library. + +![image](https://github.com/Draco-lang/Compiler/assets/7904867/7cbd5a5d-c76b-4fde-b7b5-497818a6556a) + +- 2023 3rd of June: Debug Adapter Protocol implementation and our own Debug Adapter + +This time we didn't even bother with an existing protocol implementation. We used the same approach as for LSP, we generate messages right from the specification. The result was that we can finally debug from any editor that supports DAP. + +- 2023 9th of June: LSP fixes, Language Server fixes +- 2023 11th of June: Loading more metadata members (properties, indexers, fields), debug adapter refactor, VS Code debugger integration refactor, PDB emission + +## Threads, features, everything + +At this point, we had a pretty nice toolset. We could edit and debug Draco code with decent support. While the language was really basic, we could use a decent chunk of the BCL already. We could finally focus on things like making the compiler thread-safe, fixing minor bugs, and adding language features that we have been missing for a long time. While the work seems less exciting or groundbreaking than before, there has been lots of important work done in this phase. + +- 2023 15th of June: Initial thread-safety refactor +- 2023 18th of June: More threading fixes in the Language Server +- 2023 20th of June: More threading fixes in the core compiler +- 2023 22nd of June: Modules defined in-code +- 2023 24th of June: Arrays support +- 2023 27th of June: Variadic argument list support +- 2023 30th of June: Multidimensional arrays support +- 2023 16th of July: Codegen versioning tweaks +- 2023 17th of July: LSP touch-ups and fixes +- 2023 26th of July: First stage of the type-checker and solver rework, support for renaming in the Language Server +- 2023 29th of July: Intrinsic operations simplification +- 2023 2nd of August: Inheritance internals +- 2023 7th of August: Metadata work on nested structures +- 2023 8th of August: Primitive types merged with their metadata, double binding fix +- 2023 18th of August: Symbol lookup bugfix involving generics +- 2023 21st of August: A bunch of crashbug fixes + +These bugs were discovered during one of my trips. I was on a train for 3 hours with a weak laptop and had the latest Draco SDK installed. I've decided to write a console-based Tic-Tac-Toe and discovered quite a few bugs that crashed the compiler. + +- 2023 22nd of August: Crashbug fixes in the web editor +- 2023 26th of August: Foreach loops implemented + +This wasn't only a long-awaited language feature, but the first thing we ever streamed on the [Draco Twitch channel](https://www.twitch.tv/dracolang)! Since then we try to stream some things semi-regularly, then update the VODs onto our [YouTube channel](https://www.youtube.com/@Draco-lang). + +- 2023 29th of August: Constraint solver rework around location info +- 2023 2nd of September: Code cleanup, web editor cache invalidation +- 2023 5th of September: Load documentation comments from metadata +- 2023 15th of September: Misc. cleanup +- 2023 19th of September: Basic benchmarking +- 2023 28th of September: `TypeProvider` optimizations (significant compiler speedups), more benchmarks + +## What does the future bring? + +The first year of Draco compiler development was exciting! While the language itself is still fairly minimal, we achieved a lot in terms of compiler maturity and tooling. As of right now, we have a bunch of ongoing initiatives we need to wrap up: + +- Compiler optimizations, parallelization +- Match expressions, pattern matching +- Stackification for the IR +- LSP message scheduling rework +- Lots and lots of smaller things + +With that said, there are ongoing efforts to finally specify and agree on [user-defined types](https://github.com/Draco-lang/Language-suggestions/issues/126). Once the specification is done, we will have plenty on our plates for the compiler. + +I'm hoping that everyone who contributed or monitored the progress found the challenges we faced interesting. I'm hoping to see many of you in the future of Draco! Thank you so much everyone who contributed ideas, features or even kind words towards the project. diff --git a/public/clipboard.svg b/public/clipboard.svg new file mode 100644 index 0000000..4a18640 --- /dev/null +++ b/public/clipboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/index.html b/public/index.html deleted file mode 100644 index c9b6599..0000000 --- a/public/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - Draco Programming Language - - - -
- - diff --git a/public/link.svg b/public/link.svg new file mode 100644 index 0000000..ed0217c --- /dev/null +++ b/public/link.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/SuperDerpy.tsx b/src/app/SuperDerpy.tsx index b763cf0..aa7d38c 100644 --- a/src/app/SuperDerpy.tsx +++ b/src/app/SuperDerpy.tsx @@ -41,7 +41,6 @@ export default function SuperDerpy() { }); break; } - console.log(emojiState); setTimeout(() => { setEmoji({ name: "smile", title: "Derpy calmed down." }); }, 3000); diff --git a/src/app/blog/[articleName]/CommentScript.tsx b/src/app/blog/[articleName]/CommentScript.tsx new file mode 100644 index 0000000..cb4562c --- /dev/null +++ b/src/app/blog/[articleName]/CommentScript.tsx @@ -0,0 +1,35 @@ +"use client"; +import { useEffect, useRef } from "react"; + +export default function CommentScript() { + // this is an "hack" because react doesn't like custom attribute in script tag. + // So we gotta build the script tag manually. + const commentBox = useRef(null); + + useEffect(() => { + const scriptEl = document.createElement("script"); + scriptEl.src = "https://giscus.app/client.js"; + scriptEl.setAttribute("data-repo", "Draco-lang/draco-lang.github.io"); + scriptEl.setAttribute("data-repo-id", "R_kgDOKNtvDA"); + scriptEl.setAttribute("data-category", "Blog Comments"); + scriptEl.setAttribute("data-category-id", "DIC_kwDOKNtvDM4CarR0"); + scriptEl.setAttribute("data-mapping", "url"); + scriptEl.setAttribute("data-strict", "1"); + scriptEl.setAttribute("data-reactions-enabled", "1"); + scriptEl.setAttribute("data-emit-metadata", "0"); + scriptEl.setAttribute("data-input-position", "top"); + scriptEl.setAttribute("data-theme", "dark_dimmed"); + scriptEl.setAttribute("data-lang", "en"); + scriptEl.setAttribute("crossorigin", "anonymous"); + scriptEl.async = true; + + const current = commentBox.current!; + current.appendChild(scriptEl); + + return () => { + current.innerHTML = ""; + }; + }, []); + + return
; +} diff --git a/src/app/blog/[articleName]/page.css b/src/app/blog/[articleName]/page.css new file mode 100644 index 0000000..d5c2878 --- /dev/null +++ b/src/app/blog/[articleName]/page.css @@ -0,0 +1,84 @@ +.article-header { + max-width: 56rem; + margin-left: auto; + margin-right: auto; + padding-left: 3rem; + padding-right: 3rem; + display: flex; + flex-direction: column; +} + +.article-footer { + max-width: 56rem; + margin-left: auto; + margin-right: auto; + padding-left: 3rem; + padding-right: 3rem; + margin-top: 6rem; +} + +.footer-oldnew { + display: flex; + align-items: center; + justify-content: center; + padding-bottom: 2rem; + margin-bottom: 3rem; + border-bottom: 1px solid #e5e7eb28; +} + +.footer-oldnew > a { + background-color: #1c1f26; + outline: 1px solid #e5e7eb28; + margin-right: 1px; + display: flex; + flex-direction: row; + color: white; + text-decoration: none; + width: 50%; +} + +.footer-oldnew > a:first-child { + border-top-left-radius: 5px; + border-bottom-left-radius: 5px; +} + +.footer-oldnew > a:last-child { + border-top-right-radius: 5px; + border-bottom-right-radius: 5px; +} + +.footer-oldnew > a > div { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + padding: 0.375rem 0.75rem; + justify-content: center; +} + +.footer-oldnew > a > div > span { + text-transform: uppercase; + color: #b6b6b6; + font-size: 0.65rem; + margin-top: 0.5rem; +} + +.footer-oldnew > a > div > p { + font-size: 1.1rem; + line-height: 1.5rem; + margin-top: 0.3rem; + white-space: normal; + color: #00c8bd; + font-weight: 400; +} + +.muted-color { + color: #868686; +} + +.article-meta { + font-size: 13.6px; + font-weight: 400; + display: flex; + flex-direction: column; +} diff --git a/src/app/blog/[articleName]/page.tsx b/src/app/blog/[articleName]/page.tsx new file mode 100644 index 0000000..6185ed2 --- /dev/null +++ b/src/app/blog/[articleName]/page.tsx @@ -0,0 +1,134 @@ +import Article from "@/components/Article"; +import { getBlogArticles } from "@/utils/blog"; +import CommentScript from "./CommentScript"; +import "./page.css"; +import Link from "next/link"; +import metadata from "@/utils/metadata"; +import { Metadata } from "next"; +import sharp from "sharp"; +import { promises as fs } from "fs"; +import ArticleNameParams from "@/utils/ArticleNameParams"; + +export async function generateStaticParams() { + const articles = await getBlogArticles(); + return articles.map((article) => ({ + articleName: article.path, + })); +} + +export async function generateMetadata({ params }: ArticleNameParams): Promise { + let { articleName } = params; + + // https://github.com/vercel/next.js/issues/54730 + if (process.env.NODE_ENV === "production") { + articleName = decodeURIComponent(articleName); + } + + const articles = await getBlogArticles(); + const article = articles.find((article) => article.path === articleName)!; + if (article.image !== undefined) { + const filePath = `./public${article.image}`; + const svgBuffer = await fs.readFile(filePath); + const imageUrl = `generated/${articleName}-cover.png`; + await sharp(svgBuffer).png().toFile(`./public/${imageUrl}`); + + return metadata({ + title: `The Draco Blog - ${article.title}`, + description: article.teaser, + imagePng: `https://draco-lang.org/${imageUrl}`, + goBig: article.makeSocialEmbedBig, + }); + } + + return metadata({ + title: `The Draco Blog - ${article.title}`, + description: article.teaser, + imagePng: "https://draco-lang.org/generated/Logo-Short-Inverted-Outline.png", + goBig: false, + }); +} + +export default async function Page({ params }: ArticleNameParams) { + let { articleName } = params; + + // https://github.com/vercel/next.js/issues/54730 + if (process.env.NODE_ENV === "production") { + articleName = decodeURIComponent(articleName); + } + + const articles = await getBlogArticles(); + const article = articles.find((article) => article.path === articleName)!; + articles.sort((a, b) => (a.date > b.date ? -1 : 1)); + const articleIndex = articles.indexOf(article); + const previousArticle = articles[articleIndex + 1]; + const nextArticle = articles[articleIndex - 1]; + const date = new Date(article.date); + const formattedDate = date.toLocaleString("en-US", { + day: "numeric", + month: "long", + year: "numeric", + }); + + return ( +
+
+

{article.title}

+
+ + Posted + + + {article.tags.length === 0 ? ( + <> + ) : ( + + Tags + {article.tags} + + )} + + By + {article.authors?.join(", ")} + +
+ {article.image === undefined ? ( + <> + ) : ( + + )} +
+ +
+
+
+ {previousArticle === undefined ? ( + <> + ) : ( + +
+ older +

{previousArticle!.title}

+
+ + )} + {nextArticle === undefined ? ( + <> + ) : ( + +
+ newer +

{nextArticle!.title}

+
+ + )} +
+ +
+
+ ); +} diff --git a/src/app/blog/layout.tsx b/src/app/blog/layout.tsx new file mode 100644 index 0000000..b11d6a1 --- /dev/null +++ b/src/app/blog/layout.tsx @@ -0,0 +1,13 @@ +import generateMetadata from "@/utils/metadata"; +import { Metadata } from "next"; + +export const metadata: Metadata = generateMetadata({ + title: "The Draco Blog", + description: "Development diary of the language and compiler.", + imagePng: "https://draco-lang.org/generated/Logo-Short-Inverted-Outline.png", + goBig: true, +}); + +export default async function RootLayout({ children }: { children: React.ReactNode }) { + return
{children}
; +} diff --git a/src/app/blog/page.css b/src/app/blog/page.css index bf8a795..f920907 100644 --- a/src/app/blog/page.css +++ b/src/app/blog/page.css @@ -1,6 +1,37 @@ -.comming-soon { +.blog-entries { + max-width: 56rem; + margin-left: auto; + margin-right: auto; display: flex; flex-direction: column; - align-items: center; - justify-content: center; + gap: 1.25rem; +} + +.blog-entries > a { + background-color: #1c1f26; + border: 1px solid #e5e7eb28; + border-radius: 5px; + display: flex; + flex-direction: row; + height: 10.75rem; + color: white; + text-decoration: none; +} + +.blog-entries > a:hover { + background-color: #ffffff23; +} + +.blog-entries > a img { + width: 20rem; +} + +.blog-entries > a h1 { + margin-top: 0; + margin-bottom: 0.5rem; + font-size: 1.25rem; +} + +.article-preview-left-part { + padding: 1.75rem 1.75rem 1.25rem; } diff --git a/src/app/blog/page.tsx b/src/app/blog/page.tsx index d917821..1c14837 100644 --- a/src/app/blog/page.tsx +++ b/src/app/blog/page.tsx @@ -1,11 +1,34 @@ +import Link from "next/link"; import "./page.css"; -import Emoji from "@/components/Emoji"; +import { getBlogArticles } from "@/utils/blog"; -export default function Blog() { +export default async function Page() { + const articles = await getBlogArticles(); + // sort by date + articles.sort((a, b) => (a.date > b.date ? -1 : 1)); return ( -
-

Coming Soon 

{" "} - +
+ {articles.map((article, i) => ( + +
+

{article.title}

+
{article.teaser}
+
+ { + /* eslint-disable @next/next/no-img-element, jsx-a11y/alt-text */ + article.image != undefined ? ( + + ) : ( + <> + ) + } + + ))}
); } diff --git a/src/app/community/page.css b/src/app/community/page.css index dd3fd0e..601c7e6 100644 --- a/src/app/community/page.css +++ b/src/app/community/page.css @@ -42,19 +42,11 @@ margin-left: -5px; } -.community h1 { +.page-community h1 { text-align: center; font-size: 50px; } -.community iframe { - margin-top: 1em; - width: 100%; - height: 100%; - position: absolute; - top: 0; -} - .community-content .community-padding { margin-bottom: 1em; } diff --git a/src/app/community/page.tsx b/src/app/community/page.tsx index 87d334b..129982d 100644 --- a/src/app/community/page.tsx +++ b/src/app/community/page.tsx @@ -3,9 +3,9 @@ import BackgroundLogo from "@/components/BackgroundLogo"; import DiscordWidget from "@/components/DiscordWidget"; import Emoji from "@/components/Emoji"; -export default function Community() { +export default function Page() { return ( -
+

Community

diff --git a/src/app/docs/page.tsx b/src/app/docs/page.tsx index 62b36cf..af1e948 100644 --- a/src/app/docs/page.tsx +++ b/src/app/docs/page.tsx @@ -3,7 +3,7 @@ import Emoji from "@/components/Emoji"; export default function Page() { return ( -
+

Coming Soon 

{" "}
diff --git a/src/app/layout.css b/src/app/layout.css index 1f3d84e..8e00e06 100644 --- a/src/app/layout.css +++ b/src/app/layout.css @@ -42,7 +42,9 @@ code { justify-content: space-between; position: fixed; width: 100%; - background-color: #282c34; + background-color: rgba(40, 44, 52, 95%); + backdrop-filter: blur(16px) saturate(2); + border-bottom: 0 solid rgb(229 231 235); } .top-bar-logo { @@ -75,9 +77,52 @@ code { .app { height: 100vh; - width: 100vw; + width: 100%; } .body { padding-top: 6rem; + min-height: 100%; + box-sizing: border-box; +} + +body:has(.page-docs) .active-on-docs { + outline: 1px solid #00c8bd; +} + +body:has(.page-specs) .active-on-specs { + outline: 1px solid #00c8bd; +} + +body:has(.page-community) .active-on-community { + outline: 1px solid #00c8bd; +} + +body:has(.page-blog) .active-on-blog { + outline: 1px solid #00c8bd; +} + +body:has(.page-docs) .active-on-docs:hover { + background-color: #0000; +} + +body:has(.page-specs) .active-on-specs:hover { + background-color: #0000; +} + +body:has(.page-community) .active-on-community:hover { + background-color: #0000; +} + +body:has(.page-blog) .active-on-blog:hover { + background-color: #0000; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + scroll-margin-top: 64px; } diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 979e3e3..e2ce137 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -2,12 +2,21 @@ import DracoButton from "@/components/DracoButton"; import Link from "next/link"; import Image from "next/image"; import "./layout.css"; +import { Metadata } from "next"; +import generateMetadata from "@/utils/metadata"; -export default function RootLayout({ - children, -}: { +export const metadata: Metadata = generateMetadata({ + title: "Draco Programming Language", + description: "A new .NET programming language in the making.", + imagePng: "https://draco-lang.org/generated/Logo-Short-Inverted-Outline.png", + goBig: false, +}); + +export interface Params { children: React.ReactNode; -}) { +} + +export default function RootLayout({ children }: Params) { return ( @@ -15,7 +24,7 @@ export default function RootLayout({
logo
- + Documentation - {" "} + {/*redirect to getting started for now*/} - + Specification - + Community - + Blog GitHub Logo {currRandom > 0.5 ? ( - Confused Derpy + Confused Derpy ) : ( - Crying Derpy + Crying Derpy )}

Page Not Found

diff --git a/src/app/specs/[articleName]/page.tsx b/src/app/specs/[articleName]/page.tsx new file mode 100644 index 0000000..65558d6 --- /dev/null +++ b/src/app/specs/[articleName]/page.tsx @@ -0,0 +1,31 @@ +import Article from "@/components/Article"; +import ArticleNameParams from "@/utils/ArticleNameParams"; +import { getSpecsInfo } from "@/utils/github"; + +export async function generateStaticParams() { + const specs = await getSpecsInfo(); + return specs.map((post) => ({ + articleName: post.name, + })); +} + +export default async function Page({ params }: ArticleNameParams) { + const { articleName } = params; + const specs = await getSpecsInfo(); + const spec = specs.find((spec) => spec.name === articleName)!; + return ( +
+
+ +
+ ); +} diff --git a/src/app/specs/layout.css b/src/app/specs/layout.css new file mode 100644 index 0000000..eb8fb8e --- /dev/null +++ b/src/app/specs/layout.css @@ -0,0 +1,47 @@ +.page-specs { + display: flex; + flex-direction: row; + overflow: hidden; + width: 100%; + height: 100%; +} + +.sidebar { + position: fixed; + min-width: 200px; + overflow: auto; + display: flex; + flex-direction: column; + height: 100%; + padding-right: 5px; +} + +.sidebar > a { + border-bottom-left-radius: 0; + border-top-left-radius: 0; + padding-left: 1.5em; +} + +.spec-content { + width: 100%; +} + +/* The followings styles include the article name, so it doesn't follow exactly the convention. */ + +/* stylelint-disable-next-line selector-class-pattern */ +.article-active-on-Introduction { + margin-top: 1px; +} + +/* stylelint-disable-next-line selector-class-pattern */ +body:has(.article-Introduction) .article-active-on-Introduction { + background-color: #00c8bd50; +} + +.sidebar > a:hover { + background-color: #ffffff23; +} + +.sidebar > a:visited:hover { + background-color: #ffffff23; +} diff --git a/src/app/specs/layout.tsx b/src/app/specs/layout.tsx new file mode 100644 index 0000000..e12bae3 --- /dev/null +++ b/src/app/specs/layout.tsx @@ -0,0 +1,43 @@ +import "./layout.css"; +import { getSpecsInfo } from "@/utils/github"; +import DracoButton from "@/components/DracoButton"; + +interface Params { + children: React.ReactNode; +} + +export default async function RootLayout({ children }: Params) { + const specs = await getSpecsInfo(); + + return ( +
+
+ + Introduction + + {specs + .filter((s) => s.name !== "Introduction") + .map((s) => ( + + {camelToSpacedCamel(s.name)} + + ))} +
+
{children}
+
+ ); +} + +function camelToSpacedCamel(input: string): string { + const words = input.split(/(?=[A-Z])/); + return words.join(" "); +} diff --git a/src/app/specs/page.css b/src/app/specs/page.css index bf8a795..e69de29 100644 --- a/src/app/specs/page.css +++ b/src/app/specs/page.css @@ -1,6 +0,0 @@ -.comming-soon { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; -} diff --git a/src/app/specs/page.tsx b/src/app/specs/page.tsx index 946b905..9cef676 100644 --- a/src/app/specs/page.tsx +++ b/src/app/specs/page.tsx @@ -1,11 +1,20 @@ +import Article from "@/components/Article"; import "./page.css"; -import Emoji from "@/components/Emoji"; +import { getSpecsInfo } from "@/utils/github"; -export default function Specification() { +export default async function Page() { + const articles = await getSpecsInfo(); + const intro = articles.find((article) => article.name === "Introduction")!; return ( -
-

Coming Soon 

{" "} - -
+ <> +
+ + ); } diff --git a/src/components/Article.css b/src/components/Article.css new file mode 100644 index 0000000..de22f68 --- /dev/null +++ b/src/components/Article.css @@ -0,0 +1,214 @@ +.not-a-link { + color: white; + text-decoration: none; +} + +.not-a-link:visited { + color: white; +} + +.article { + display: flex; + flex-direction: row; + justify-content: space-between; + width: 100%; +} + +.article-content { + max-width: 56rem; + margin-left: auto; + margin-right: auto; + padding-left: 3rem; + padding-right: 3rem; + color: rgb(228, 228, 228); + font-weight: 400; +} + +.article-content h1, +.article-content h2, +.article-content h3, +.article-content h4, +.article-content h5, +.article-content h6 { + color: #ccc; + font-weight: 400; +} + +.article-content h2::after, +.article-content h3::after, +.article-content h4::after, +.article-content h5::after, +.article-content h6::after { + content: ""; + background-color: gray; + mask: url("/link.svg"); + height: 15px; + width: 18px; + margin-top: 5px; + margin-left: 5px; + display: inline-block; +} + +.article-content .not-a-link:hover { + text-decoration: underline; +} + +.article-content table { + display: block; + overflow-x: auto; + border-collapse: collapse; + min-width: 70%; + max-width: fit-content; + border-spacing: 0; +} + +.article-content table th, +.article-content table td { + padding: 0.4rem 1rem; + font-size: 95%; + white-space: nowrap; +} + +.article-content table thead { + border-bottom: solid 2px rgba(210, 215, 217, 75%); +} + +.article-content table tbody tr { + border-bottom: 1px solid rgba(42, 47, 53, 52%); + background-color: #333740; +} + +.article-content table tbody tr:nth-child(2n) { + background-color: #1c1f26; +} + +.code-box { + border: 1px solid #e5e7eb28; + text-align: left; + border-radius: 5px 5px 5px 5px; + background-color: #1c1f26; +} + +.code-box > pre { + padding: 0 1em 2em 2em; + overflow-x: auto; + margin: 0; +} + +.code-title-bar { + display: flex; + flex-direction: row; + justify-content: space-between; + align-items: center; + padding: 0.5em; + margin-right: 0.5em; +} + +.code-title-bar::before { + content: ""; +} + +.code-title-bar > div { + display: flex; + flex-direction: row; + align-items: center; +} + +.code-icon { + font-weight: bold; + font-family: monospace; + align-items: center; + padding-right: 0.5em; + padding-top: 3px; /* make the icon vertically aligned with the title */ + color: gray; +} + +.clipboard-icon { + height: 1em; + width: 0.8em; + background-color: white; + background-repeat: no-repeat; + mask-image: url("/clipboard.svg"); + cursor: pointer; +} + +.copy-ok { + background-color: transparent; + mask-image: none; +} + +.copy-ok::before { + /* checkmark */ + content: "✔"; + color: green; + height: 1em; + width: 1em; + display: inline-block; + size: 3em; +} + +.table-of-content { + margin-right: 2em; + position: fixed; + right: 0; + top: 8em; + font-weight: 400; +} + +.toc-bar { + border-left: #464951 1px solid; + left: 0; + position: absolute; + height: 22px; + max-height: inherit; +} + +.table-of-content ul { + padding-left: 20px; +} + +.table-of-content a { + max-height: inherit; +} + +.table-of-content a:hover { + transition: none; + color: #00c8bd; +} + +.table-of-content li, +.table-of-content ul { + overflow: hidden; + transition: all 300ms ease-in-out; +} + +/* When the heading is active, it is displayed. */ +.active-poc-heading { + max-height: 1000px; +} + +.active-poc-heading > a > span { + color: #00c8bd; + border-color: #00c8bd; + font-weight: 600; +} + +/* Parent heading are also displayed. */ +li:has(.active-poc-heading) { + max-height: 1000px; +} + +/* All parent child are also displayed */ +ul:has(.active-poc-heading) > li { + max-height: 1000px; +} + +/* Childs of current heading is always displayed. */ +.active-poc-heading > ul > li { + max-height: 1000px; +} + +/* Root headings are also displayed */ +.table-of-content > ul > ul > li { + max-height: 1000px; +} diff --git a/src/components/Article.tsx b/src/components/Article.tsx new file mode 100644 index 0000000..6627119 --- /dev/null +++ b/src/components/Article.tsx @@ -0,0 +1,180 @@ +import { Lexer, marked } from "marked"; +import hljs from "highlight.js"; +import "./Article.css"; +import { HTMLProps } from "react"; +import TableOfContentScrollEffect from "./TableOfContentScrollEffect"; +import "highlight.js/styles/atom-one-dark.css"; + +export default async function Article( + params: HTMLProps & { markdown: string } +) { + const { markdown, className, ...restProps } = params; + const headingsMapPoc = {}; + const headingsMapArticle = {}; + const html = marked(markdown, { + gfm: true, + async: false, + renderer: myRenderer(), + }); + const tokens = Lexer.lex(markdown, { + gfm: true, + }); + const headings = tokens.filter((t) => t.type === "heading" && t.depth > 1); + + function renderHeading(nodes: Node[]) { + return ( + + ); + } + + function myRenderer() { + const renderer = new marked.Renderer(); + renderer.code = (code, language) => { + let highlighted = code; + if (language !== undefined && language.length > 0) { + try { + highlighted = hljs.highlight(code, { language: language }).value; + } catch (e) { + console.warn(e); + highlighted = hljs.highlightAuto(code).value; + } + } + + const base64Code = stringToBase64(code); + return ` +
+
+
+ </> + ${language} +
+ +
+
${highlighted}
+
+ `; + }; + renderer.heading = (text, level) => { + if (level === 1) return `

${text}

`; + + const hashName = getHeading(text, headingsMapArticle); + const str = ` ${text} `; + return str; + }; + return renderer; + } + + function getHeading(text: string, map: { [key: string]: number }): string { + const hash = createHashLink(text); + if (map[hash] === undefined) { + map[hash] = 0; + } else { + map[hash]++; + } + + const i = map[hash]; + return `${hash}${i === 0 ? "" : `-${i}`}`; + } + + function createHashLink(title: string) { + return title + .toLowerCase() + .replace(/[^a-z0-9\s]/g, "") + .replace(/\s+/g, "-"); + } + + return ( +
+
+
+

Contents

+ {renderHeading(headingsToTree(headings.map((h) => h.raw)))} +
+ +
+ ); +} + +type Node = { + children: Node[]; + title: string; + parent?: Node; +}; + +function headingsToTree(headings: string[]): Node[] { + const root: Node = { + children: [], + title: "", + }; + + let current = root; + let currentDepth = 1; + + for (const heading of headings) { + const depth = headingDepth(heading); + if (depth > currentDepth) { + const last = current.children.at(-1)!; + const newChild = { + children: [], + title: heading, + parent: last, + }; + last.children.push(newChild); + current = last; + currentDepth = currentDepth + 1; // we don't use depth because it might skip levels + } else if (depth < currentDepth) { + for (let i = 0; i < currentDepth - depth; i++) { + current = current.parent!; + } + currentDepth = depth; + current.children.push({ + title: heading, + children: [], + parent: current, + }); + } else { + current.children.push({ + title: heading, + children: [], + parent: current, + }); + } + } + + return root.children; +} + +function headingDepth(heading: string): number { + const match = heading.match(/^#+/); + if (!match) { + throw new Error(`Invalid heading: ${heading}`); + } + + return match[0].length - 1; +} + +function stringToBase64(input: string) { + return btoa(unescape(encodeURIComponent(input))); +} diff --git a/src/components/CodeViewer/CodeTab.css b/src/components/CodeViewer/CodeTab.css index be8e698..c0a87cd 100644 --- a/src/components/CodeViewer/CodeTab.css +++ b/src/components/CodeViewer/CodeTab.css @@ -7,6 +7,11 @@ border: 0; /* borders produces doubles borders in tabs */ margin-left: 1px; float: left; + cursor: pointer; +} + +.tab-buttons:hover { + background-color: #00c8bd50; } .tab-buttons.first-tab { @@ -19,12 +24,6 @@ input[type="radio"]:checked + div.tab-content > label { outline-color: #00c8bd; -} - -.tab-buttons :not(:checked):hover { - background-color: #00c8bd50; -} - -.tab-buttons :not(:checked) { - cursor: pointer; + background-color: #0000; + cursor: default; } diff --git a/src/components/CodeViewer/CodeViewer.tsx b/src/components/CodeViewer/CodeViewer.tsx index 352ea7a..5d1f820 100644 --- a/src/components/CodeViewer/CodeViewer.tsx +++ b/src/components/CodeViewer/CodeViewer.tsx @@ -1,6 +1,5 @@ import React, { ReactNode, HTMLProps } from "react"; import "./CodeViewer.css"; -import "highlight.js/styles/atom-one-dark.css"; import Highlight from "./Highlight"; export default function CodeViewer( diff --git a/src/components/CodeViewer/Highlight.tsx b/src/components/CodeViewer/Highlight.tsx index a9d5c57..6b29043 100644 --- a/src/components/CodeViewer/Highlight.tsx +++ b/src/components/CodeViewer/Highlight.tsx @@ -1,6 +1,7 @@ import hljs from "highlight.js"; import { HTMLProps } from "react"; import "./Highlight.css"; +import "highlight.js/styles/atom-one-dark.css"; export default function Highlight( prop: HTMLProps & { language: string; children: string } diff --git a/src/components/DracoButton.css b/src/components/DracoButton.css index a587df7..0b90c1f 100644 --- a/src/components/DracoButton.css +++ b/src/components/DracoButton.css @@ -4,6 +4,11 @@ border-radius: 9999px; } +.draco-button-small { + font-size: 1em; + padding: 0.5em 1em; +} + .draco-button-medium { font-size: 1.2em; padding: 0.5em 1em; diff --git a/src/components/DracoButton.tsx b/src/components/DracoButton.tsx index 3667898..82d9adf 100644 --- a/src/components/DracoButton.tsx +++ b/src/components/DracoButton.tsx @@ -2,7 +2,7 @@ import { ReactNode } from "react"; import Link from "next/link"; import "./DracoButton.css"; -type ButtonSize = "medium" | "large"; +export type ButtonSize = "small" | "medium" | "large"; export default function DracoButton(props: { buttonSize: ButtonSize; diff --git a/src/components/TableOfContentScrollEffect.tsx b/src/components/TableOfContentScrollEffect.tsx new file mode 100644 index 0000000..28aa6af --- /dev/null +++ b/src/components/TableOfContentScrollEffect.tsx @@ -0,0 +1,130 @@ +"use client"; + +import { useLayoutEffect } from "react"; + +export default function TableOfContentScrollEffect() { + useLayoutEffect(() => { + let lastClickTime = 0; + function onLinkClick(event: Event) { + const link = event.target as HTMLAnchorElement; + const li = link.parentElement!.parentElement as HTMLLIElement; + clearActiveTag(); + li.classList.add("active-poc-heading"); + lastClickTime = Date.now(); + } + const tocLinks = Array.from(document.getElementsByClassName("poc-heading")); + tocLinks.forEach((e) => { + e.addEventListener("click", onLinkClick); + }); + + const style = document.createElement("style"); + // We set this in js so noscript users can still see the table of content. + style.innerHTML = ` + .poc-heading { + max-height: 0; + } + `; + document.head.appendChild(style); + + const headings = Array.from( + document.getElementsByClassName("article-heading") + ); + const headingsInScreen: { + element: HTMLHeadingElement; + isOnScreen: boolean; + }[] = []; + function callback(entries: IntersectionObserverEntry[]) { + entries.forEach((entry) => { + let curr = headingsInScreen.find((h) => h.element === entry.target); + if (curr === undefined) { + curr = { + element: entry.target as HTMLHeadingElement, + isOnScreen: false, + }; + headingsInScreen.push(curr); + } + + curr.isOnScreen = entry.isIntersecting; + }); + + // Prevent scroll event after clicking on heading to change the active heading. + // anything between ~20-300 should be ok + // there are events triggered from the click, and I don't know how to tell the apart from the scroll event. + // So we have a little debounce here. + const delay = 50; + if (lastClickTime + delay > Date.now()) { + return; + } + + clearActiveTag(); + let activeHeading: HTMLHeadingElement; + const hasHeadingOnScreen = + headingsInScreen.findIndex((s) => s.isOnScreen) !== -1; + if (!hasHeadingOnScreen) { + // we want to know if the headings was scrolled out of the screen from the top or from the bottom. + // if it's at the top, the coordinate won't be 0 because it may have a padding, so we need to get this padding. + const padding = entries[0].rootBounds!.y; + const positionRelativeToObserver = + entries[0].boundingClientRect.top - padding; + // if the position is negative it means the heading is above the screen, so we are scrolling down. + const isScrollingBackward = positionRelativeToObserver > 0; + + if (!isScrollingBackward) { + // we are scrolling down, so the current heading is the one that just exited the screen. + activeHeading = entries[0].target as HTMLHeadingElement; + } else { + // we are scrolling up, so the current heading is the previous of the one that exited the screen. + const index = headingsInScreen.findIndex( + (s) => s.element === entries[0].target + ); + if (index === 0) { + // if somehow the first heading is far in the text, we will keep selecting it. + activeHeading = headingsInScreen[0].element; + } else { + activeHeading = headingsInScreen[index - 1].element; + } + } + } else { + let previous = headingsInScreen[0]; + for (let i = 0; i < headingsInScreen.length; i++) { + const element = headingsInScreen[i]; + if (element.isOnScreen) break; + + previous = element; + } + activeHeading = previous.element; + } + + const headingId = Array.from(activeHeading.classList) + .find((c) => c.startsWith("heading-")) + ?.replace("heading-", ""); + const pocHeading = document.getElementsByClassName( + `poc-heading-${headingId}` + )[0]; + if (pocHeading === undefined) { + throw new Error(`poc-heading-${headingId} not found`); + } + + pocHeading.classList.add("active-poc-heading"); + } + const observer = new IntersectionObserver(callback, { + root: document, + rootMargin: "-150px 0px 0px 0px", + threshold: 0, + }); + headings.forEach((h) => observer.observe(h)); + return () => { + observer.disconnect(); + tocLinks.forEach((e) => { + e.removeEventListener("click", onLinkClick); + }); + }; + }); + + return <>; +} +function clearActiveTag() { + Array.from(document.getElementsByClassName("poc-heading")).forEach((e) => + e.classList.remove("active-poc-heading") + ); +} diff --git a/src/utils/ArticleNameParams.ts b/src/utils/ArticleNameParams.ts new file mode 100644 index 0000000..7c63ee7 --- /dev/null +++ b/src/utils/ArticleNameParams.ts @@ -0,0 +1,5 @@ +interface ArticleNameParams { + params: { articleName: string }; +} + +export default ArticleNameParams; \ No newline at end of file diff --git a/src/utils/blog.ts b/src/utils/blog.ts new file mode 100644 index 0000000..ce29e5b --- /dev/null +++ b/src/utils/blog.ts @@ -0,0 +1,63 @@ +import path from "path"; +import fs from "fs"; +import fm from "front-matter"; + +export interface BlogArticle { + title: string; // The title. + date: string; // The date in the following format: YYYY-MM-DD hh:mm:ss YOUR_UTC_OFFSET. + tags: string[]; // The tags. Not really used for now. + markdown: string; + authors: string[] | undefined; // Authors list. + image: string | undefined; // This image will be put below the title, and next to the article in the articles list, and in the social embeds. + imageMargin: string | undefined; // The margin of the image in the article list. + imageHeight: string | undefined; // The height of the image in the article. + teaser: string | undefined; // This text is used in the article list, and social embeds. + path: string; // The directory name. + makeSocialEmbedBig: boolean; // To make the image of the social embeds bigger. +} + +export async function getBlogArticles(): Promise { + // list directories in /blog + // for each directory, read the markdown file article.md + const dir = await fs.promises.opendir(path.join(process.cwd(), "public/blog")); + const articles: BlogArticle[] = []; + for await (const dirEntry of dir) { + if (dirEntry.isDirectory()) { + const articlePath = path.join(dir.path, dirEntry.name, "article.md"); + if (!fs.existsSync(articlePath)) continue; + + const article = await fs.promises.readFile(articlePath, "utf-8"); + + const result = fm(article); + const attributes = result.attributes as { + title: string | undefined; + date: string; + tags: string[] | undefined; + teaser: string | undefined; + authors: string[] | undefined; + image: string | undefined; + imageMargin: string | undefined; + imageHeight: string | undefined; + makeSocialEmbedBig: boolean | undefined; + }; + if (attributes.date === undefined) { + throw new Error(`Article ${dirEntry.name} does not have a date`); + } + + articles.push({ + title: attributes.title ?? "Untitled", + date: attributes.date, + tags: attributes["tags"] as string[] || [], + markdown: result.body, + teaser: attributes.teaser, + authors: attributes.authors, + image: attributes.image, + imageMargin: attributes.imageMargin, + imageHeight: attributes.imageHeight, + path: encodeURIComponent(dirEntry.name), + makeSocialEmbedBig: attributes.makeSocialEmbedBig ?? false, + }); + } + } + return articles; +} \ No newline at end of file diff --git a/src/utils/github.ts b/src/utils/github.ts new file mode 100644 index 0000000..08fa4f9 --- /dev/null +++ b/src/utils/github.ts @@ -0,0 +1,41 @@ +import { createTokenAuth } from "@octokit/auth-token"; +import { Octokit } from "@octokit/rest"; +import { components } from "@octokit/openapi-types"; + +let instance: Octokit; + +export async function getOctokit() { + if (instance !== undefined) return instance; + + if (process.env.GITHUB_TOKEN !== undefined && process.env.GITHUB_TOKEN.length > 0) { + const auth = createTokenAuth(process.env.GITHUB_TOKEN); + const authentication = await auth(); + instance = new Octokit({ + auth: authentication.token + }); + } else { + instance = new Octokit(); + } + + return instance; +} + +export async function getSpecsInfo(): Promise<{ name: string, markdown: string }[]> { + const octokit = await getOctokit(); + + const response = await octokit.repos.getContent({ + owner: "Draco-lang", + repo: "Language-suggestions", + path: "Specification" + }); + const data = response.data as components["schemas"]["content-directory"]; + return Promise.all( + data.filter(entry => entry.name.endsWith(".md")) + .map(async file => { + return { + name: file.name.replace(".md", ""), + markdown: await fetch(file.download_url!).then(r => r.text()) + }; + }) + ); +} \ No newline at end of file diff --git a/src/utils/metadata.ts b/src/utils/metadata.ts new file mode 100644 index 0000000..72b52ea --- /dev/null +++ b/src/utils/metadata.ts @@ -0,0 +1,44 @@ +import { Metadata } from "next"; + +export interface MetadataInput { + title: string; + description: string | undefined; + imagePng: string; + goBig: boolean; +} + +export default function generateMetadata( metadata: MetadataInput): Metadata { + const { title, description, imagePng, goBig } = metadata; + const urlBase = "https://draco-lang.org/"; + return { + metadataBase: new URL(urlBase), + title: title, + description: description, + icons: ["https://draco-lang.org/generated/Logo-Short.svg"], + openGraph: { + type: "website", + title: title, + description: description, + images: [ + { + url: imagePng, + alt: "Draco Logo", + type: "image/png", + }, + ], + url: urlBase, + siteName: "draco-lang.org", + }, + twitter: { + title: title, + description: description, + images: { + url: imagePng, + alt: "Draco Logo", + type: "image/png", + }, + site: "@Draco_lang", + card: goBig ? "summary_large_image" : "summary", + }, + }; +} \ No newline at end of file