diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..f7ceca8d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,12 @@ +{ + "name": "Thoth-Tech Website Dev", + "dockerComposeFile": "./docker-compose.yml", + "service": "thoth-astro-dev", + "workspaceFolder": "/site", + "workspaceMount": "source=${localWorkspaceFolder},target=/site,type=bind", + "forwardPorts": [4321], + "postStartCommand": "npm run dev", + "features": { + "ghcr.io/devcontainers/features/github-cli:1": {} + } +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 00000000..6106451a --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,15 @@ +services: + thoth-astro-dev: + build: + context: ../ + dockerfile: Dockerfile + ports: + - "4321:4321" + volumes: + - ..:/site + - thoth-astro-node_modules:/site/node_modules + tty: true + stdin_open: true + command: sleep infinity +volumes: + thoth-astro-node_modules: diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..809ba837 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,24 @@ +**/.classpath +**/.dockerignore +**/.env +**/.git +**/.gitignore +**/.project +**/.settings +**/.toolstarget +**/.vs +**/.vscode +**/*.*proj.user +**/*.dbmdl +**/*.jfm +**/charts +**/docker-compose* +**/compose* +**/Dockerfile* +**/node_modules +**/npm-debug.log +**/obj +**/secrets.dev.yaml +**/values.dev.yaml +LICENSE +README.md diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..6313b56c --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index d805dd6b..05b559d2 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -22,9 +22,12 @@ reproduce. Please also list any relevant details for your test configuration_ ## Testing Checklist -- [ ] Tested in latest Chrome -- [ ] Tested in latest Safari -- [ ] Tested in latest Firefox +- [ ] Have run `npm run format` +- [ ] Have run `npm run build` +- [ ] Have run `npm run dev` and/or `npm run preview`, using: + - [ ] Chrome + - [ ] Safari + - [ ] Firefox ## Checklist diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4129545f..9bf0d9b9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,7 +3,9 @@ name: CI on: pull_request: push: - branches: [main] + branches: + - main + - development jobs: build: @@ -23,7 +25,9 @@ jobs: run: npm run format:check - name: Vale run: | - sudo apt update - sudo apt install snapd - sudo snap install vale --edge + curl -L -o vale.tar.gz "https://github.com/errata-ai/vale/releases/download/v3.13.0/vale_3.13.0_Linux_64-bit.tar.gz" + tar -xzf vale.tar.gz + sudo mv vale /usr/local/bin/vale + rm vale.tar.gz + vale --version npm run prose:check diff --git a/.linelint.yml b/.linelint.yml new file mode 100644 index 00000000..fe85e07c --- /dev/null +++ b/.linelint.yml @@ -0,0 +1,19 @@ +# 'true' will fix files +autofix: false + +# list of paths to ignore, uses gitignore syntaxes (executes before any rule) +ignore: + - src/styles/*.css + - .lintlint.yml + +rules: + # checks if file ends in a newline character + end-of-file: + # set to true to enable this rule + enable: true + + # set to true to disable autofix (if enabled globally) + disable-autofix: true + + # if true also checks if file ends in a single newline character + single-new-line: true diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 00000000..00fb5069 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,9 @@ +{ + "MD033": false, + "MD024": false, + "MD013": { + "line_length": 100, + "code_blocks": false, + "tables": false + } +} diff --git a/.netlify/state.json b/.netlify/state.json index e995df1c..d5bbba05 100644 --- a/.netlify/state.json +++ b/.netlify/state.json @@ -1,3 +1,3 @@ { - "siteId": "5273a592-7468-452e-a000-9f3e699ecc05" + "siteId": "b5458139-7fea-4422-a3fe-cd2fc7d3b7bb" } diff --git a/.vale/thothtech/MeaningfulLinkWords.yml b/.vale/thothtech/MeaningfulLinkWords.yml index 74aa60a9..209e6885 100644 --- a/.vale/thothtech/MeaningfulLinkWords.yml +++ b/.vale/thothtech/MeaningfulLinkWords.yml @@ -7,7 +7,7 @@ extends: existence message: 'Improve SEO and accessibility by rewriting "%s" in the link text.' level: warning -scope: link +scope: raw ignorecase: true link: TBA tokens: diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..0216455f --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,11 @@ +{ + "configurations": [ + { + "name": "Docker Node.js Launch", + "type": "docker", + "request": "launch", + "preLaunchTask": "docker-run: debug", + "platform": "node" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..52941c10 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "*.mdx": "markdown" + }, + "json.format.keepLines": true +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9464ffbe..5ab3aea3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -94,7 +94,7 @@ syllables per word. For more information, see [official instructions to install nvm](https://github.com/nvm-sh/nvm#installing-and-updating), a Node version manager. Then, run the following to install and use the repository's Node version: - ```sh + ```shell nvm install nvm use ``` @@ -103,7 +103,8 @@ syllables per word. For more information, see confirmed by running `nvm which`. 1. Install all dependencies - ```sh + + ```shell npm install ``` @@ -123,7 +124,7 @@ syllables per word. For more information, see 1. Install curl - ```sh + ```shell sudo apt-get install curl ``` @@ -131,7 +132,7 @@ syllables per word. For more information, see [official instructions to install nvm](https://github.com/nvm-sh/nvm#installing-and-updating), a Node version manager. Then, run the following to install and use the repository's Node version: - ```sh + ```shell nvm install nvm use ``` @@ -140,7 +141,8 @@ syllables per word. For more information, see confirmed by running `nvm which`. 1. Install all dependencies - ```sh + + ```shell npm install ``` @@ -153,7 +155,6 @@ syllables per word. For more information, see ``` 1. Install [`vale`](https://github.com/errata-ai/vale/releases). To install for: - - macOS using `brew`, run: `brew install vale`. - Linux, use your distribution's package manager or a [released binary](https://github.com/errata-ai/vale/releases). diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..576bbd1b --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +FROM node:iron-trixie-slim + +WORKDIR /site + +COPY package*.json /site/ + +RUN apt-get update && apt-get upgrade -y +RUN apt-get install git curl -y + +RUN npm install + +# Install Vale +RUN curl -L -o vale.tar.gz "https://github.com/errata-ai/vale/releases/download/v3.13.0/vale_3.13.0_Linux_64-bit.tar.gz" \ + && tar -xzf vale.tar.gz \ + && mv vale /usr/local/bin/vale \ + && rm vale.tar.gz \ + && vale --version + +ENV HOST=0.0.0.0 +ENV PORT=4321 + +# Expose the dev server port +EXPOSE 4321 diff --git a/README.md b/README.md index a459f502..eb2bef86 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,110 @@ -# Starlight Starter Kit: Basics +# ThothTech Documentation Website -``` -npm create astro@latest -- --template starlight -``` +

+ Thoth Tech Logo +

-[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics) -[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics) +[![GitHub contributors](https://img.shields.io/github/contributors/thoth-tech/ThothTech-Documentation-Website?label=Contributors&color=F5A623)](https://github.com/thoth-tech/ThothTech-Documentation-Website/graphs/contributors) +[![GitHub issues](https://img.shields.io/github/issues/thoth-tech/ThothTech-Documentation-Website?label=Issues&color=F5A623)](https://github.com/thoth-tech/ThothTech-Documentation-Website/issues) +[![GitHub pull requests](https://img.shields.io/github/issues-pr/thoth-tech/ThothTech-Documentation-Website?label=Pull%20Requests&color=F5A623)](https://github.com/thoth-tech/ThothTech-Documentation-Website/pulls) +[![Forks](https://img.shields.io/github/forks/thoth-tech/ThothTech-Documentation-Website?label=Forks&color=F5A623)](https://github.com/thoth-tech/ThothTech-Documentation-Website/network/members) +[![Stars](https://img.shields.io/github/stars/thoth-tech/ThothTech-Documentation-Website?label=Stars&color=F5A623)](https://github.com/thoth-tech/ThothTech-Documentation-Website/stargazers) -> πŸ§‘β€πŸš€ **Seasoned astronaut?** Delete this file. Have fun! +Welcome to the **ThothTech Documentation Website** repository! This project serves as the central +hub for all Thoth Tech resources, designed to provide a structured and accessible platform for +documentation, product information, and team resources. This contains out long term documentation, +such as the documentation for onboarding information, general information and company deliverables. -## πŸš€ Project Structure +Short term documentation such as spike reports and sprint reports are stored in the +[Documentation](https://github.com/thoth-tech/documentation) repository. -Inside of your Astro + Starlight project, you'll see the following folders and files: +Built with Astro and Starlight, this website offers an organized space where users can explore Thoth +Tech's mission, values, and goals, along with in-depth information on each of the company's products +and services. Each product has its own dedicated section, featuring a brief overview, its purpose, +and comprehensive documentation to support both users and development teams. -``` +The site also includes team documentation for each semester, highlighting the efforts of the +individuals contributing to Thoth Tech's ongoing projects. Whether you're a developer, a team +member, or a user, this website provides all the information needed to understand and contribute to +Thoth Tech's vision and initiatives. + +## Format Checks to Run + +To maintain code quality, please ensure you run the following commands before submitting a pull +request: + +1. **Format the Files**: + + ```shell + npm run format + ``` + +2. **Run the Lint Checker**: + + ```shell + npm run lint + ``` + +3. **Build the website (and check links are valid)**: + + ```shell + npm run build + ``` + +## Project Structure + +This website is built with Astro and uses the **Starlight Starter Kit** as a foundation. Below is a +breakdown of the project structure: + +```plaintext . -β”œβ”€β”€ public/ +β”œβ”€β”€ public/ # Static assets like favicons, images β”œβ”€β”€ src/ -β”‚ β”œβ”€β”€ assets/ -β”‚ β”œβ”€β”€ content/ -β”‚ β”‚ β”œβ”€β”€ docs/ -β”‚ β”‚ └── config.ts -β”‚ └── env.d.ts -β”œβ”€β”€ astro.config.mjs -β”œβ”€β”€ package.json -└── tsconfig.json +β”‚ β”œβ”€β”€ content/ # Markdown files for documentation content +β”‚ β”‚ β”œβ”€β”€ docs/ # Documentation pages +β”‚ β”‚ └── config.ts # Configuration for Starlight content +β”‚ β”œβ”€β”€ styles/ # Custom CSS for styling +β”‚ └── env.d.ts # TypeScript environment definitions +β”œβ”€β”€ astro.config.mjs # Astro configuration +β”œβ”€β”€ package.json # Node.js dependencies and scripts +└── tsconfig.json # TypeScript configuration ``` -Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed -as a route based on its file name. +- **Documentation Content**: `.md` or `.mdx` files placed in `src/content/docs/` are exposed as + routes based on their filenames. +- **Static Assets**: Place images and other static files in `public/` for easy access. + +## Commands -Images can be added to `src/assets/` and embedded in Markdown with a relative link. +All commands should be run from the root of the project in the terminal: -Static assets, like favicons, can be placed in the `public/` directory. +| Command | Action | +| :------------------------ | :------------------------------------------------------ | +| `npm install` | Installs all dependencies | +| `npm run dev` | Starts the local development server at `localhost:4321` | +| `npm run build` | Builds the production-ready site in `./dist/` | +| `npm run preview` | Previews your build locally before deployment | +| `npm run astro ...` | Runs Astro CLI commands like `astro add`, `astro check` | +| `npm run astro -- --help` | Displays help for Astro CLI commands | -## 🧞 Commands +--- + +## Getting Started + +To initialize the project, use the following Astro command to set up with the Starlight Starter Kit: + +```shell +npm create astro@latest -- --template starlight +``` -All commands are run from the root of the project, from a terminal: +For more information, check out the [CONTRIBUTING.md](CONTRIBUTING.md) file. -| Command | Action | -| :------------------------ | :----------------------------------------------- | -| `npm install` | Installs dependencies | -| `npm run dev` | Starts local dev server at `localhost:3000` | -| `npm run build` | Build your production site to `./dist/` | -| `npm run preview` | Preview your build locally, before deploying | -| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | -| `npm run astro -- --help` | Get help using the Astro CLI | +## Learn More -## πŸ‘€ Want to learn more? +For additional resources, check out the following: -Check out [Starlight’s docs](https://starlight.astro.build/), read -[the Astro documentation](https://docs.astro.build), or jump into the -[Astro Discord server](https://astro.build/chat). +- **[Starlight Documentation](https://starlight.astro.build/)**: Learn more about the Starlight + Starter Kit. +- **[Astro Documentation](https://docs.astro.build)**: Understand the Astro framework. +- **[Astro Discord Server](https://astro.build/chat)**: Connect with the Astro community. diff --git a/astro.config.mjs b/astro.config.mjs index 008d3cc0..4986be85 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -1,263 +1,163 @@ import { defineConfig } from "astro/config"; import starlight from "@astrojs/starlight"; +import starlightLinksValidator from 'starlight-links-validator'; +import partytown from '@astrojs/partytown'; // https://astro.build/config export default defineConfig({ - integrations: [ + + server: { + host: true + }, + vite: { + server: { + watch: { + usePolling: true, + interval: 60 + } + } + }, + + integrations: [ + partytown({ + config: { + forward: ["dataLayer.push", "gtag"], // Forward both for compatibility + }, + }), starlight({ title: "Thoth Tech", - customCss: ["./src/styles/custom.css"], - social: { - github: "https://github.com/thoth-tech", - }, - sidebar: [ + favicon: "/favicon.svg", + head: [ + // Google Analytics script tag { - label: "Processes", - items: [ - { label: "Introduction", link: "/processes/introduction" }, - { - label: "Cyber Security Guidelines", - autogenerate: { - directory: "processes/cyber-security-guidelines", - }, - }, - { - label: "Documentation", - autogenerate: { directory: "processes/Documentation" }, - }, - { - label: "Quality Assurance", - items: [ - { - label: "Git Contributions Guide", - link: "/processes/quality-assurance/git-contributions-guide", - }, - { - label: "Quality Assurance Overview", - link: "/processes/quality-assurance/quality-assurance-overview", - }, - { - label: "Testing and Development", - link: "/processes/quality-assurance/testing-and-dev", - }, - { - label: "Templates", - autogenerate: { - directory: "processes/quality-assurance/templates", - }, - }, - ], - }, - ], + tag: "script", + attrs: { + type: "text/partytown", + src: 'https://www.googletagmanager.com/gtag/js?id=G-D62C4YT9KZ', + async: true, + }, }, + // Google Analytics inline configuration { - label: "Teams and Leadership", - autogenerate: { - directory: "teams-and-leadership", - }, + tag: 'script', + type: 'text/partytown', + innerHTML: ` + window.dataLayer = window.dataLayer || []; + function gtag() { dataLayer.push(arguments); } + gtag('js', new Date()); + gtag('consent', 'default', { + ad_storage: 'denied', + ad_user_data: 'denied', + ad_personalization: 'denied', + analytics_storage: 'denied', + }); + gtag('config', 'G-D62C4YT9KZ'); + `, }, + // CookieConsent stylesheet { - label: "Reference", - autogenerate: { - directory: "reference", + tag: 'link', + attrs: { + rel: 'stylesheet', + href: 'https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@3.0.1/dist/cookieconsent.css', }, }, + // CookieConsent configuration script { - label: "Policies", - autogenerate: { - directory: "policies", + tag: 'script', + attrs: { + type: 'module', + src: '/cookieconsent-config.js', // Ensure this script exists in the `public/` folder }, }, + ], + plugins: [ + starlightLinksValidator({ + errorOnRelativeLinks: true, + }), + + ], + customCss: ["./src/styles/custom.css"], + social: { + github: "https://github.com/thoth-tech", + }, + logo: { + src: "./public/favicon.svg", + }, + components: { + // MarkdownContent: "starlight-blog/overrides/MarkdownContent.astro", + // Sidebar: "starlight-blog/overrides/Sidebar.astro", + // ThemeSelect: "starlight-blog/overrides/ThemeSelect.astro", + }, + sidebar: [ { - label: "Products", + label: "Resources", + collapsed: false, items: [ { - label: "Products", - link: "/products/products", + label: "Introduction", + link: "/resources/introduction" }, { - label: "Art Gallery", - items: [ - { - label: "Get to Know Us", - link: "/products/art-gallery/example", - }, - { - label: "Projects", - autogenerate: { - directory: "products/art-gallery/projects", - }, - }, - { - label: "Documentation", - autogenerate: { - directory: "products/art-gallery/documentation", - }, - }, - { - label: "Issues and Resolutions", - autogenerate: { - directory: "products/art-gallery/issues-and-resolution", - }, - }, - ], + label: "Thoth Tech Technology Stack", + link: "/resources/thoth-tech-technology-stack" }, { - label: "Company Operations", - items: [ - { - label: "Get to Know Us", - link: "/products/company-operations/example", - }, - { - label: "Projects", - autogenerate: { - directory: "products/company-operations/projects", - }, - items: [ - { - label: "Docusaurus Documentation", - autogenerate: { - directory: "products/company-operations/projects/docusaurus-documentation", - }, - }, - { - label: "Thoth Tech Website", - autogenerate: { - directory: "products/company-operations/projects/Thoth-Tech-Website", - }, - }, - ], - }, - { - label: "Documentation", - autogenerate: { - directory: "products/company-operations/documentation", - }, - }, - { - label: "Issues and Resolutions", - autogenerate: { - directory: "products/company-operations/issues-and-resolution", - }, - }, - ], + label: "Remote Working Guide", + link: "/resources/remote-working-guide" }, { - label: "CourseFlow", - items: [ - { - label: "Get to Know Us", - link: "/products/courseflow/example", - }, - { - label: "Projects", - autogenerate: { - directory: "products/courseflow/projects", - }, - }, - { - label: "Documentation", - autogenerate: { - directory: "products/courseflow/documentation", - }, - }, - { - label: "Issues and Resolutions", - autogenerate: { - directory: "products/courseflow/issues-and-resolution", - }, - }, - ], + label: "Onboarding Hub", + collapsed: true, + autogenerate: { directory: "Resources/Onboarding Hub" }, }, { - label: "OnTrack", - items: [ - { - label: "Get to Know Us", - link: "/products/ontrack/example", - }, - { - label: "Projects", - autogenerate: { - directory: "products/ontrack/projects", - }, - }, - { - label: "Documentation", - autogenerate: { - directory: "products/ontrack/documentation", - }, - items: [ - { - label: "Front End Migration", - autogenerate: { - directory: "products/ontrack/documentation/front-end-migration", - }, - }, - { - label: "Numbas", - autogenerate: { - directory: "products/ontrack/documentation/numbas", - }, - }, - { - label: "Deployment", - autogenerate: { - directory: "products/ontrack/documentation/deployment", - }, - }, - ], - }, - { - label: "Issues and Resolutions", - autogenerate: { - directory: "products/ontrack/issues-and-resolution", - }, - }, - ], + label: "Quality Assurance", + collapsed: true, + autogenerate: { directory: "Resources/Quality Assurance" }, }, + { + label: "Frequently Asked Questions (FAQ)", + link: "/resources/faq" + }, + ], + }, + { + label: "Products", + collapsed: false, + items: [ + { label: "Products", link: "/products" }, { label: "SplashKit", - items: [ - { - label: "Get to Know Us", - link: "/products/splashkit/example", - }, - { - label: "Projects", - autogenerate: { - directory: "products/splashkit/projects", - }, - }, - { - label: "Documentation", - autogenerate: { - directory: "products/splashkit/documentation", - }, - items: [ - { - label: "Applications", - autogenerate: { - directory: "products/splashkit/documentation/applications", - }, - }, - ], - }, - { - label: "Issues and Resolutions", - autogenerate: { - directory: "products/splashkit/issues-and-resolution", - }, - }, - ], + collapsed: true, + autogenerate: { directory: "Products/SplashKit" }, + }, + { + label: "OnTrack", + collapsed: true, + autogenerate: { directory: "Products/OnTrack" }, }, ], }, + { + label: "Teams and Contributions", + collapsed: true, + autogenerate: { directory: "Teams and Contributions" }, + }, + { + label: "Feedback", + collapsed: true, + items: [ + { + label: "Feedback Form", + link: "/feedback/feedback-form" + } + ], + }, ], }), ], - // Process images with sharp: https://docs.astro.build/en/guides/assets/#using-sharp + // Image processing image: { service: { entrypoint: "astro/assets/services/sharp", diff --git a/package-lock.json b/package-lock.json index f18a38d6..300cc9bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,7 +1,7 @@ { "name": "starlight-documentation-website", "version": "0.0.1", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { @@ -9,211 +9,234 @@ "version": "0.0.1", "dependencies": { "@astrojs/netlify": "^3.0.0", - "@astrojs/starlight": "^0.9.0", - "astro": "^3.0.7", - "prettier": "^3.1.0", - "sharp": "^0.32.3" + "@astrojs/partytown": "^2.1.2", + "@astrojs/starlight": "^0.28.6", + "astro": "^4.16.18", + "sharp": "^0.32.3", + "starlight": "^0.3.9", + "starlight-blog": "^0.4.0", + "starlight-links-validator": "^0.12.3", + "vanilla-cookieconsent": "^3.0.1" }, "devDependencies": { - "markdownlint": "^0.31.0" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" + "markdownlint": "^0.31.1", + "prettier": "^3.2.5" } }, "node_modules/@astrojs/compiler": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.0.1.tgz", - "integrity": "sha512-DfBR7Cf+tOgQ4n7TIgTtU5x5SEA/08DNshpEPcT+91A0KbBlmUOYMBM/O6qAaHkmVo1KIoXQYhAmfdTT1zx9PQ==" + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.0.tgz", + "integrity": "sha512-mqVORhUJViA28fwHYaWmsXSzLO9osbdZ5ImUfxBarqsYdMlPbqAqGJCxsNzvppp1BEzc1mJNjOVvQqeDN8Vspw==", + "license": "MIT" }, "node_modules/@astrojs/internal-helpers": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.2.0.tgz", - "integrity": "sha512-NQ4ppp1CM0HNkKbJNM4saVSfmUYzGlRalF6wx7F6T/MYHYSWGuojY89/oFTy4t8VlOGUCUijlsVNNeziWaUo5g==" + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.4.1.tgz", + "integrity": "sha512-bMf9jFihO8YP940uD70SI/RDzIhUHJAolWVcO1v5PUivxGKvfLZTLTVVxEYzGYyPsA3ivdLNqMnL5VgmQySa+g==", + "license": "MIT" }, "node_modules/@astrojs/markdown-remark": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-3.0.0.tgz", - "integrity": "sha512-s8I49Je4++ImgYAgwL32HgN8m6we2qz3RtBpN4AjObMODPwDylmzUHZksD8Toy31q/P59ED3MuwphqOGm9l03w==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-5.3.0.tgz", + "integrity": "sha512-r0Ikqr0e6ozPb5bvhup1qdWnSPUvQu6tub4ZLYaKyG50BXZ0ej6FhGz3GpChKpH7kglRFPObJd/bDyf2VM9pkg==", + "license": "MIT", "dependencies": { - "@astrojs/prism": "^3.0.0", + "@astrojs/prism": "3.1.0", "github-slugger": "^2.0.0", - "import-meta-resolve": "^3.0.0", - "rehype-raw": "^6.1.1", - "rehype-stringify": "^9.0.4", - "remark-gfm": "^3.0.1", - "remark-parse": "^10.0.2", - "remark-rehype": "^10.1.0", - "remark-smartypants": "^2.0.0", - "shiki": "^0.14.3", - "unified": "^10.1.2", - "unist-util-visit": "^4.1.2", - "vfile": "^5.3.7" - }, - "peerDependencies": { - "astro": "^3.0.0" + "hast-util-from-html": "^2.0.3", + "hast-util-to-text": "^4.0.2", + "import-meta-resolve": "^4.1.0", + "mdast-util-definitions": "^6.0.0", + "rehype-raw": "^7.0.0", + "rehype-stringify": "^10.0.1", + "remark-gfm": "^4.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.1.1", + "remark-smartypants": "^3.0.2", + "shiki": "^1.22.0", + "unified": "^11.0.5", + "unist-util-remove-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.1", + "vfile": "^6.0.3" } }, "node_modules/@astrojs/mdx": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-1.0.0.tgz", - "integrity": "sha512-Gmeleci8o4X7dST9E85c1+k273zcKW8cSFgZLTwU5K4dC0qHfY/EaDKHWrtzOB2wjZlT1JDRzTJ68LJYGrF2OA==", - "dependencies": { - "@astrojs/markdown-remark": "3.0.0", - "@astrojs/prism": "3.0.0", - "@mdx-js/mdx": "^2.3.0", - "acorn": "^8.10.0", - "es-module-lexer": "^1.3.0", - "estree-util-visit": "^1.2.1", - "github-slugger": "^2.0.0", + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-3.1.9.tgz", + "integrity": "sha512-3jPD4Bff6lIA20RQoonnZkRtZ9T3i0HFm6fcDF7BMsKIZ+xBP2KXzQWiuGu62lrVCmU612N+SQVGl5e0fI+zWg==", + "license": "MIT", + "dependencies": { + "@astrojs/markdown-remark": "5.3.0", + "@mdx-js/mdx": "^3.1.0", + "acorn": "^8.14.0", + "es-module-lexer": "^1.5.4", + "estree-util-visit": "^2.0.0", "gray-matter": "^4.0.3", - "hast-util-to-html": "^8.0.4", - "kleur": "^4.1.4", - "rehype-raw": "^6.1.1", - "remark-frontmatter": "^4.0.1", - "remark-gfm": "^3.0.1", - "remark-smartypants": "^2.0.0", - "shiki": "^0.14.3", + "hast-util-to-html": "^9.0.3", + "kleur": "^4.1.5", + "rehype-raw": "^7.0.0", + "remark-gfm": "^4.0.0", + "remark-smartypants": "^3.0.2", "source-map": "^0.7.4", - "unist-util-visit": "^4.1.2", - "vfile": "^5.3.7" + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.3" }, "engines": { - "node": ">=18.14.1" + "node": "^18.17.1 || ^20.3.0 || >=21.0.0" }, "peerDependencies": { - "astro": "^3.0.0" + "astro": "^4.8.0" } }, "node_modules/@astrojs/netlify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/netlify/-/netlify-3.0.0.tgz", - "integrity": "sha512-v76HpoaEAK9uZHRJCCA8LV51e344ZhChfSMTlvNRvYa+ExJvPZCusBW3EaiyUFKpVozjs9AkIf3xmZ6cc+hFgQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@astrojs/netlify/-/netlify-3.1.1.tgz", + "integrity": "sha512-zXApWH3uaW0/sxu75S4XfVO7xe8pmPtlGzBDFWyeceIi9u2oWgnFdVdNEnZ/bb5//+54b4y/LeL4yzL5kDjX6Q==", + "license": "MIT", "dependencies": { - "@astrojs/underscore-redirects": "0.3.0", + "@astrojs/underscore-redirects": "^0.3.3", "@netlify/functions": "^2.0.1", - "esbuild": "^0.19.2" + "esbuild": "^0.19.5" }, "peerDependencies": { - "astro": "^3.0.0" + "astro": "^3.0.0 || ^4.0.0" + } + }, + "node_modules/@astrojs/partytown": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@astrojs/partytown/-/partytown-2.1.4.tgz", + "integrity": "sha512-loUrAu0cGYFDC6dHVRiomdsBJ41VjDYXPA+B3Br51V5hENFgDSOLju86OIj1TvBACcsB22UQV7BlppODDG5gig==", + "license": "MIT", + "dependencies": { + "@qwik.dev/partytown": "^0.11.0", + "mrmime": "^2.0.1" } }, "node_modules/@astrojs/prism": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.0.0.tgz", - "integrity": "sha512-g61lZupWq1bYbcBnYZqdjndShr/J3l/oFobBKPA3+qMat146zce3nz2kdO4giGbhYDt4gYdhmoBz0vZJ4sIurQ==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.1.0.tgz", + "integrity": "sha512-Z9IYjuXSArkAUx3N6xj6+Bnvx8OdUSHA8YoOgyepp3+zJmtVYJIl/I18GozdJVW1p5u/CNpl3Km7/gwTJK85cw==", + "license": "MIT", "dependencies": { "prismjs": "^1.29.0" }, "engines": { - "node": ">=18.14.1" + "node": "^18.17.1 || ^20.3.0 || >=21.0.0" } }, "node_modules/@astrojs/sitemap": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.0.0.tgz", - "integrity": "sha512-qm7npHuUW4q3OOmulqhJ1g69jEQu0Sdc6P8NbOzqIoosj/L+3v4i8dtKBnp6n1UQ4Sx8H8Vdi3Z/On7i9/ZJhw==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.0.tgz", + "integrity": "sha512-+qxjUrz6Jcgh+D5VE1gKUJTA3pSthuPHe6Ao5JCxok794Lewx8hBFaWHtOnN0ntb2lfOf7gvOi9TefUswQ/ZVA==", + "license": "MIT", "dependencies": { - "sitemap": "^7.1.1", - "zod": "3.21.1" + "sitemap": "^8.0.2", + "stream-replace-string": "^2.0.0", + "zod": "^3.25.76" } }, "node_modules/@astrojs/starlight": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@astrojs/starlight/-/starlight-0.9.0.tgz", - "integrity": "sha512-RK1QGfcU7bCxiOaGhVwJiA2NojswFq39v675IqS1/P97S0uHHQEtPHyiOd3vS2N/fAhwE78Vru9ykeB29BQlxw==", - "dependencies": { - "@astrojs/mdx": "^1.0.0", - "@astrojs/sitemap": "^3.0.0", - "@pagefind/default-ui": "^1.0.0-alpha.5", - "@types/mdast": "^3.0.11", + "version": "0.28.6", + "resolved": "https://registry.npmjs.org/@astrojs/starlight/-/starlight-0.28.6.tgz", + "integrity": "sha512-lY+rbRMIVxDGiXhS4lBuVrU2jTUezEt4QeTxUTHxfj2tuKBwquG7Jg+alON6l+uaV+anbOkFb001MMXZF8X85w==", + "license": "MIT", + "dependencies": { + "@astrojs/mdx": "^3.1.3", + "@astrojs/sitemap": "^3.1.6", + "@pagefind/default-ui": "^1.0.3", + "@types/hast": "^3.0.4", + "@types/mdast": "^4.0.4", + "astro-expressive-code": "^0.35.6", "bcp-47": "^2.1.0", - "execa": "^7.1.1", - "hast-util-select": "^5.0.5", - "hastscript": "^7.2.0", - "pagefind": "^1.0.0-alpha.5", - "rehype": "^12.0.1", - "remark-directive": "^2.0.1", - "unified": "^10.1.2", - "unist-util-remove": "^3.1.1", - "unist-util-visit": "^4.1.2", - "vfile": "^5.3.7" + "hast-util-from-html": "^2.0.1", + "hast-util-select": "^6.0.2", + "hast-util-to-string": "^3.0.0", + "hastscript": "^9.0.0", + "i18next": "^23.11.5", + "js-yaml": "^4.1.0", + "mdast-util-directive": "^3.0.0", + "mdast-util-to-markdown": "^2.1.0", + "mdast-util-to-string": "^4.0.0", + "pagefind": "^1.0.3", + "rehype": "^13.0.1", + "rehype-format": "^5.0.0", + "remark-directive": "^3.0.0", + "unified": "^11.0.5", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.2" }, "peerDependencies": { - "astro": "^3.0.0" + "astro": "^4.14.0" } }, "node_modules/@astrojs/telemetry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.0.1.tgz", - "integrity": "sha512-7zJMuikRDQ0LLLivteu0+y4pqdgznrChFiRrY3qmKlOEkLWD1T3u1a5M970lvpErP7Vgh4P298JBPjv8LTj+sw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.1.0.tgz", + "integrity": "sha512-/ca/+D8MIKEC8/A9cSaPUqQNZm+Es/ZinRv0ZAzvu2ios7POQSsVD+VOj7/hypWNsNM3T7RpfgNq7H2TU1KEHA==", + "license": "MIT", "dependencies": { - "ci-info": "^3.8.0", + "ci-info": "^4.0.0", "debug": "^4.3.4", "dlv": "^1.1.3", - "dset": "^3.1.2", + "dset": "^3.1.3", "is-docker": "^3.0.0", "is-wsl": "^3.0.0", - "undici": "^5.23.0", "which-pm-runs": "^1.1.0" }, "engines": { - "node": ">=18.14.1" + "node": "^18.17.1 || ^20.3.0 || >=21.0.0" } }, "node_modules/@astrojs/underscore-redirects": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@astrojs/underscore-redirects/-/underscore-redirects-0.3.0.tgz", - "integrity": "sha512-dWBOH6hlGeaERmbdi+jFV2rnTcjOJrNOFYTnTTf8G2x0Gs3Radsh1ObSNEL5Z+xUhXNZLymhLbnN9yQSmh+PQw==" + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@astrojs/underscore-redirects/-/underscore-redirects-0.3.4.tgz", + "integrity": "sha512-vYuYtIrTwxFlDRIhuekscorsHdLL8Hr3mgOczfM1tRWVPn54dDNcKG0DmfL4DlC5YJRoqVaVdUs508Hw643NTw==", + "license": "MIT" }, "node_modules/@babel/code-frame": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", - "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", + "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.22.10", - "chalk": "^2.4.2" + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz", + "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz", - "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-compilation-targets": "^7.22.10", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.10", - "@babel/parser": "^7.22.10", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10", - "convert-source-map": "^1.7.0", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.6.tgz", + "integrity": "sha512-H3mcG6ZDLTlYfaSNi0iOKkigqMFvkTKlGUYlD8GW7nNOYRrevuA46iTypPyv+06V3fEmvvazfntkBU34L0azAw==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/generator": "^7.28.6", + "@babel/helper-compilation-targets": "^7.28.6", + "@babel/helper-module-transforms": "^7.28.6", + "@babel/helpers": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/template": "^7.28.6", + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", + "json5": "^2.2.3", "semver": "^6.3.1" }, "engines": { @@ -228,43 +251,48 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, "node_modules/@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz", + "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.10", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/types": "^7.27.3" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", - "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", - "dependencies": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", - "browserslist": "^4.21.9", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" }, @@ -276,62 +304,42 @@ "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", - "dependencies": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "dependencies": { - "@babel/types": "^7.22.5" - }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", + "license": "MIT", "dependencies": { - "@babel/types": "^7.22.5" + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -341,89 +349,62 @@ } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "dependencies": { - "@babel/types": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "dependencies": { - "@babel/types": "^7.22.5" - }, + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.28.6.tgz", + "integrity": "sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==", + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helpers": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz", - "integrity": "sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", + "license": "MIT", "dependencies": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10" + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/highlight": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", - "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", + "node_modules/@babel/parser": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", + "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" + "@babel/types": "^7.28.6" }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/parser": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", - "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==", "bin": { "parser": "bin/babel-parser.js" }, @@ -432,11 +413,12 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", - "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.28.6.tgz", + "integrity": "sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.22.5" + "@babel/helper-plugin-utils": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -446,15 +428,16 @@ } }, "node_modules/@babel/plugin-transform-react-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz", - "integrity": "sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.28.6.tgz", + "integrity": "sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==", + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-plugin-utils": "^7.28.6", + "@babel/plugin-syntax-jsx": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" @@ -463,59 +446,103 @@ "@babel/core": "^7.0.0-0" } }, + "node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", - "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", - "dependencies": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.10", - "@babel/types": "^7.22.10", - "debug": "^4.1.0", - "globals": "^11.1.0" + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz", + "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/generator": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.6", + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6", + "debug": "^4.3.1" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/types": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", + "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", - "to-fast-properties": "^2.0.0" + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@ctrl/tinycolor": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-4.2.0.tgz", + "integrity": "sha512-kzyuwOAQnXJNLS9PSyrk0CWk35nWJW/zl/6KvnTBMFK65gm7U1/Z5BqjxeapjZCIhQcM/DsrEmcbRwDyXyXK4A==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz", + "integrity": "sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, "node_modules/@esbuild/android-arm": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.2.tgz", - "integrity": "sha512-tM8yLeYVe7pRyAu9VMi/Q7aunpLwD139EY1S99xbQkT4/q2qa6eA4ige/WJQYdJ8GBL1K33pPFhPfPdJ/WzT8Q==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.12.tgz", + "integrity": "sha512-qg/Lj1mu3CdQlDEEiWrlC4eaPZ1KztwGJ9B6J+/6G+/4ewxJg7gqj8eVYWvao1bXrqGiW2rsBZFSX3q2lcW05w==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "android" @@ -525,12 +552,13 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.2.tgz", - "integrity": "sha512-lsB65vAbe90I/Qe10OjkmrdxSX4UJDjosDgb8sZUKcg3oefEuW2OT2Vozz8ef7wrJbMcmhvCC+hciF8jY/uAkw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.12.tgz", + "integrity": "sha512-P0UVNGIienjZv3f5zq0DP3Nt2IE/3plFzuaS96vihvD0Hd6H/q4WXUGpCxD/E8YrSXfNyRPbpTq+T8ZQioSuPA==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "android" @@ -540,12 +568,13 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.2.tgz", - "integrity": "sha512-qK/TpmHt2M/Hg82WXHRc/W/2SGo/l1thtDHZWqFq7oi24AjZ4O/CpPSu6ZuYKFkEgmZlFoa7CooAyYmuvnaG8w==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.12.tgz", + "integrity": "sha512-3k7ZoUW6Q6YqhdhIaq/WZ7HwBpnFBlW905Fa4s4qWJyiNOgT1dOqDiVAQFwBH7gBRZr17gLrlFCRzF6jFh7Kew==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "android" @@ -555,12 +584,13 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.2.tgz", - "integrity": "sha512-Ora8JokrvrzEPEpZO18ZYXkH4asCdc1DLdcVy8TGf5eWtPO1Ie4WroEJzwI52ZGtpODy3+m0a2yEX9l+KUn0tA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.12.tgz", + "integrity": "sha512-B6IeSgZgtEzGC42jsI+YYu9Z3HKRxp8ZT3cqhvliEHovq8HSX2YX8lNocDn79gCKJXOSaEot9MVYky7AKjCs8g==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -570,12 +600,13 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.2.tgz", - "integrity": "sha512-tP+B5UuIbbFMj2hQaUr6EALlHOIOmlLM2FK7jeFBobPy2ERdohI4Ka6ZFjZ1ZYsrHE/hZimGuU90jusRE0pwDw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.12.tgz", + "integrity": "sha512-hKoVkKzFiToTgn+41qGhsUJXFlIjxI/jSYeZf3ugemDYZldIXIxhvwN6erJGlX4t5h417iFuheZ7l+YVn05N3A==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "darwin" @@ -585,12 +616,13 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.2.tgz", - "integrity": "sha512-YbPY2kc0acfzL1VPVK6EnAlig4f+l8xmq36OZkU0jzBVHcOTyQDhnKQaLzZudNJQyymd9OqQezeaBgkTGdTGeQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.12.tgz", + "integrity": "sha512-4aRvFIXmwAcDBw9AueDQ2YnGmz5L6obe5kmPT8Vd+/+x/JMVKCgdcRwH6APrbpNXsPz+K653Qg8HB/oXvXVukA==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -600,12 +632,13 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.2.tgz", - "integrity": "sha512-nSO5uZT2clM6hosjWHAsS15hLrwCvIWx+b2e3lZ3MwbYSaXwvfO528OF+dLjas1g3bZonciivI8qKR/Hm7IWGw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.12.tgz", + "integrity": "sha512-EYoXZ4d8xtBoVN7CEwWY2IN4ho76xjYXqSXMNccFSx2lgqOG/1TBPW0yPx1bJZk94qu3tX0fycJeeQsKovA8gg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -615,12 +648,13 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.2.tgz", - "integrity": "sha512-Odalh8hICg7SOD7XCj0YLpYCEc+6mkoq63UnExDCiRA2wXEmGlK5JVrW50vZR9Qz4qkvqnHcpH+OFEggO3PgTg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.12.tgz", + "integrity": "sha512-J5jPms//KhSNv+LO1S1TX1UWp1ucM6N6XuL6ITdKWElCu8wXP72l9MM0zDTzzeikVyqFE6U8YAV9/tFyj0ti+w==", "cpu": [ "arm" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -630,12 +664,13 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.2.tgz", - "integrity": "sha512-ig2P7GeG//zWlU0AggA3pV1h5gdix0MA3wgB+NsnBXViwiGgY77fuN9Wr5uoCrs2YzaYfogXgsWZbm+HGr09xg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.12.tgz", + "integrity": "sha512-EoTjyYyLuVPfdPLsGVVVC8a0p1BFFvtpQDB/YLEhaXyf/5bczaGeN15QkR+O4S5LeJ92Tqotve7i1jn35qwvdA==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -645,12 +680,13 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.2.tgz", - "integrity": "sha512-mLfp0ziRPOLSTek0Gd9T5B8AtzKAkoZE70fneiiyPlSnUKKI4lp+mGEnQXcQEHLJAcIYDPSyBvsUbKUG2ri/XQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.12.tgz", + "integrity": "sha512-Thsa42rrP1+UIGaWz47uydHSBOgTUnwBwNq59khgIwktK6x60Hivfbux9iNR0eHCHzOLjLMLfUMLCypBkZXMHA==", "cpu": [ "ia32" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -660,12 +696,13 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.2.tgz", - "integrity": "sha512-hn28+JNDTxxCpnYjdDYVMNTR3SKavyLlCHHkufHV91fkewpIyQchS1d8wSbmXhs1fiYDpNww8KTFlJ1dHsxeSw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.12.tgz", + "integrity": "sha512-LiXdXA0s3IqRRjm6rV6XaWATScKAXjI4R4LoDlvO7+yQqFdlr1Bax62sRwkVvRIrwXxvtYEHHI4dm50jAXkuAA==", "cpu": [ "loong64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -675,12 +712,13 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.2.tgz", - "integrity": "sha512-KbXaC0Sejt7vD2fEgPoIKb6nxkfYW9OmFUK9XQE4//PvGIxNIfPk1NmlHmMg6f25x57rpmEFrn1OotASYIAaTg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.12.tgz", + "integrity": "sha512-fEnAuj5VGTanfJ07ff0gOA6IPsvrVHLVb6Lyd1g2/ed67oU1eFzL0r9WL7ZzscD+/N6i3dWumGE1Un4f7Amf+w==", "cpu": [ "mips64el" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -690,12 +728,13 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.2.tgz", - "integrity": "sha512-dJ0kE8KTqbiHtA3Fc/zn7lCd7pqVr4JcT0JqOnbj4LLzYnp+7h8Qi4yjfq42ZlHfhOCM42rBh0EwHYLL6LEzcw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.12.tgz", + "integrity": "sha512-nYJA2/QPimDQOh1rKWedNOe3Gfc8PabU7HT3iXWtNUbRzXS9+vgB0Fjaqr//XNbd82mCxHzik2qotuI89cfixg==", "cpu": [ "ppc64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -705,12 +744,13 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.2.tgz", - "integrity": "sha512-7Z/jKNFufZ/bbu4INqqCN6DDlrmOTmdw6D0gH+6Y7auok2r02Ur661qPuXidPOJ+FSgbEeQnnAGgsVynfLuOEw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.12.tgz", + "integrity": "sha512-2MueBrlPQCw5dVJJpQdUYgeqIzDQgw3QtiAHUC4RBz9FXPrskyyU3VI1hw7C0BSKB9OduwSJ79FTCqtGMWqJHg==", "cpu": [ "riscv64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -720,12 +760,13 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.2.tgz", - "integrity": "sha512-U+RinR6aXXABFCcAY4gSlv4CL1oOVvSSCdseQmGO66H+XyuQGZIUdhG56SZaDJQcLmrSfRmx5XZOWyCJPRqS7g==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.12.tgz", + "integrity": "sha512-+Pil1Nv3Umes4m3AZKqA2anfhJiVmNCYkPchwFJNEJN5QxmTs1uzyy4TvmDrCRNT2ApwSari7ZIgrPeUx4UZDg==", "cpu": [ "s390x" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -735,12 +776,13 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.2.tgz", - "integrity": "sha512-oxzHTEv6VPm3XXNaHPyUTTte+3wGv7qVQtqaZCrgstI16gCuhNOtBXLEBkBREP57YTd68P0VgDgG73jSD8bwXQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.12.tgz", + "integrity": "sha512-B71g1QpxfwBvNrfyJdVDexenDIt1CiDN1TIXLbhOw0KhJzE78KIFGX6OJ9MrtC0oOqMWf+0xop4qEU8JrJTwCg==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "linux" @@ -750,12 +792,13 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.2.tgz", - "integrity": "sha512-WNa5zZk1XpTTwMDompZmvQLHszDDDN7lYjEHCUmAGB83Bgs20EMs7ICD+oKeT6xt4phV4NDdSi/8OfjPbSbZfQ==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.12.tgz", + "integrity": "sha512-3ltjQ7n1owJgFbuC61Oj++XhtzmymoCihNFgT84UAmJnxJfm4sYCiSLTXZtE00VWYpPMYc+ZQmB6xbSdVh0JWA==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "netbsd" @@ -765,12 +808,13 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.2.tgz", - "integrity": "sha512-S6kI1aT3S++Dedb7vxIuUOb3oAxqxk2Rh5rOXOTYnzN8JzW1VzBd+IqPiSpgitu45042SYD3HCoEyhLKQcDFDw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.12.tgz", + "integrity": "sha512-RbrfTB9SWsr0kWmb9srfF+L933uMDdu9BIzdA7os2t0TXhCRjrQyCeOt6wVxr79CKD4c+p+YhCj31HBkYcXebw==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -780,12 +824,13 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.2.tgz", - "integrity": "sha512-VXSSMsmb+Z8LbsQGcBMiM+fYObDNRm8p7tkUDMPG/g4fhFX5DEFmjxIEa3N8Zr96SjsJ1woAhF0DUnS3MF3ARw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.12.tgz", + "integrity": "sha512-HKjJwRrW8uWtCQnQOz9qcU3mUZhTUQvi56Q8DPTLLB+DawoiQdjsYq+j+D3s9I8VFtDr+F9CjgXKKC4ss89IeA==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "sunos" @@ -795,12 +840,13 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.2.tgz", - "integrity": "sha512-5NayUlSAyb5PQYFAU9x3bHdsqB88RC3aM9lKDAz4X1mo/EchMIT1Q+pSeBXNgkfNmRecLXA0O8xP+x8V+g/LKg==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.12.tgz", + "integrity": "sha512-URgtR1dJnmGvX864pn1B2YUYNzjmXkuJOIqG2HdU62MVS4EHpU2946OZoTMnRUHklGtJdJZ33QfzdjGACXhn1A==", "cpu": [ "arm64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -810,12 +856,13 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.2.tgz", - "integrity": "sha512-47gL/ek1v36iN0wL9L4Q2MFdujR0poLZMJwhO2/N3gA89jgHp4MR8DKCmwYtGNksbfJb9JoTtbkoe6sDhg2QTA==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.12.tgz", + "integrity": "sha512-+ZOE6pUkMOJfmxmBZElNOx72NKpIa/HFOMGzu8fqzQJ5kgf6aTGrcJaFsNiVMH4JKpMipyK+7k0n2UXN7a8YKQ==", "cpu": [ "ia32" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -825,12 +872,13 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.2.tgz", - "integrity": "sha512-tcuhV7ncXBqbt/Ybf0IyrMcwVOAPDckMK9rXNHtF17UTK18OKLpg08glminN06pt2WCoALhXdLfSPbVvK/6fxw==", + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.12.tgz", + "integrity": "sha512-T1QyPSDCyMXaO3pzBkF96E8xMkiRYbUEZADd29SyPGabqxMViNoii+NcK7eWJAEoU6RZyEm5lVSIjTmcdoB9HA==", "cpu": [ "x64" ], + "license": "MIT", "optional": true, "os": [ "win32" @@ -839,4019 +887,2044 @@ "node": ">=12" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "node_modules/@expressive-code/core": { + "version": "0.35.6", + "resolved": "https://registry.npmjs.org/@expressive-code/core/-/core-0.35.6.tgz", + "integrity": "sha512-xGqCkmfkgT7lr/rvmfnYdDSeTdCSp1otAHgoFS6wNEeO7wGDPpxdosVqYiIcQ8CfWUABh/pGqWG90q+MV3824A==", + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "engines": { - "node": ">=6.0.0" + "@ctrl/tinycolor": "^4.0.4", + "hast-util-select": "^6.0.2", + "hast-util-to-html": "^9.0.1", + "hast-util-to-text": "^4.0.1", + "hastscript": "^9.0.0", + "postcss": "^8.4.38", + "postcss-nested": "^6.0.1", + "unist-util-visit": "^5.0.0", + "unist-util-visit-parents": "^6.0.1" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", + "node_modules/@expressive-code/plugin-frames": { + "version": "0.35.6", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-frames/-/plugin-frames-0.35.6.tgz", + "integrity": "sha512-CqjSWjDJ3wabMJZfL9ZAzH5UAGKg7KWsf1TBzr4xvUbZvWoBtLA/TboBML0U1Ls8h/4TRCIvR4VEb8dv5+QG3w==", + "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "@expressive-code/core": "^0.35.6" } }, - "node_modules/@mdx-js/mdx": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-2.3.0.tgz", - "integrity": "sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==", + "node_modules/@expressive-code/plugin-shiki": { + "version": "0.35.6", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-shiki/-/plugin-shiki-0.35.6.tgz", + "integrity": "sha512-xm+hzi9BsmhkDUGuyAWIydOAWer7Cs9cj8FM0t4HXaQ+qCubprT6wJZSKUxuvFJIUsIOqk1xXFaJzGJGnWtKMg==", + "license": "MIT", "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/mdx": "^2.0.0", - "estree-util-build-jsx": "^2.0.0", - "estree-util-is-identifier-name": "^2.0.0", - "estree-util-to-js": "^1.1.0", - "estree-walker": "^3.0.0", - "hast-util-to-estree": "^2.0.0", - "markdown-extensions": "^1.0.0", - "periscopic": "^3.0.0", - "remark-mdx": "^2.0.0", - "remark-parse": "^10.0.0", - "remark-rehype": "^10.0.0", - "unified": "^10.0.0", - "unist-util-position-from-estree": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "unist-util-visit": "^4.0.0", - "vfile": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "@expressive-code/core": "^0.35.6", + "shiki": "^1.1.7" } }, - "node_modules/@netlify/functions": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-2.0.2.tgz", - "integrity": "sha512-goWRtaIPUK/q47qLYtfGGj7HgJIRaT0snw7zZ0yeoNTfQfCRwQwvRrMAsXkCsCtq2N2Oo81L26SpkMxEQMk9hg==", + "node_modules/@expressive-code/plugin-text-markers": { + "version": "0.35.6", + "resolved": "https://registry.npmjs.org/@expressive-code/plugin-text-markers/-/plugin-text-markers-0.35.6.tgz", + "integrity": "sha512-/k9eWVZSCs+uEKHR++22Uu6eIbHWEciVHbIuD8frT8DlqTtHYaaiwHPncO6KFWnGDz5i/gL7oyl6XmOi/E6GVg==", + "license": "MIT", "dependencies": { - "@netlify/serverless-functions-api": "1.7.3", - "is-promise": "^4.0.0" - }, - "engines": { - "node": ">=14.0.0" + "@expressive-code/core": "^0.35.6" } }, - "node_modules/@netlify/node-cookies": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@netlify/node-cookies/-/node-cookies-0.1.0.tgz", - "integrity": "sha512-OAs1xG+FfLX0LoRASpqzVntVV/RpYkgpI0VrUnw2u0Q1qiZUzcPffxRK8HF3gc4GjuhG5ahOEMJ9bswBiZPq0g==", + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": "^14.16.0 || >=16.0.0" - } - }, - "node_modules/@netlify/serverless-functions-api": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@netlify/serverless-functions-api/-/serverless-functions-api-1.7.3.tgz", - "integrity": "sha512-n6/7cJlSWvvbBlUOEAbkGyEld80S6KbG/ldQI9OhLfe1lTatgKmrTNIgqVNpaWpUdTgP2OHWFjmFBzkxxBWs5w==", - "dependencies": { - "@netlify/node-cookies": "^0.1.0", - "urlpattern-polyfill": "8.0.2" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "funding": { + "url": "https://opencollective.com/libvips" }, - "engines": { - "node": ">= 8" + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, - "engines": { - "node": ">= 8" + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" } }, - "node_modules/@pagefind/darwin-arm64": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.0.0-alpha.10.tgz", - "integrity": "sha512-npjow0ZhicK47KqPcS4qtlWft2kV0jClyEh0iuumdzJstt4PTacapuyxUAIm5NRR0GH2XoLyaH+TZzaaOmMuJw==", + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", "cpu": [ "arm64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "darwin" - ] + ], + "funding": { + "url": "https://opencollective.com/libvips" + } }, - "node_modules/@pagefind/darwin-x64": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.0.0-alpha.10.tgz", - "integrity": "sha512-WYik242Lz0Qv+eTD0brqkE6kndHMDoG7kD8WvdJPKzCSA3MHXVCYm9OyG8EWAWLYxSaDCI+Dx5+NZ1crcQ3Hbw==", + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", "cpu": [ "x64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "darwin" - ] + ], + "funding": { + "url": "https://opencollective.com/libvips" + } }, - "node_modules/@pagefind/default-ui": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/@pagefind/default-ui/-/default-ui-1.0.0-alpha.10.tgz", - "integrity": "sha512-BHuRcd3ycJw2oEXxO8SARbWwLp7UP2f3Cv/PhvFh9opLvs0Cf+b/rqo8M7Rm3ldFTPxQuASvY4tt4leIX4DWDg==" + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } }, - "node_modules/@pagefind/linux-arm64": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.0.0-alpha.10.tgz", - "integrity": "sha512-puc21zq/AsQAqAKKqaBsS7lWy16XYjNt2qssTIfhWXmzVQ1jl3wbUK5jm1rvjco5CQAq5cH+y0QdOwrFeuGo3w==", + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", "cpu": [ "arm64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" - ] + ], + "funding": { + "url": "https://opencollective.com/libvips" + } }, - "node_modules/@pagefind/linux-x64": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.0.0-alpha.10.tgz", - "integrity": "sha512-SfTd1ABl4otyEiu8rXqLY+tF78yUcfhNW7h4TsgJW8smIKgLJu0CO3YGBze+ddmHGU3dLDCJ5Z+AgHc//VUGfg==", + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", "cpu": [ - "x64" + "s390x" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ "linux" - ] + ], + "funding": { + "url": "https://opencollective.com/libvips" + } }, - "node_modules/@pagefind/windows-x64": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.0.0-alpha.10.tgz", - "integrity": "sha512-GevBJZ+O0V/2VcNNaBrdWa1NFf6hg2mREhaj3o35WBYCOMSoZmofKuKdLI/w5X0v2AiMbM7CRhOlLwqqW4gKuQ==", + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", "cpu": [ "x64" ], + "license": "LGPL-3.0-or-later", "optional": true, "os": [ - "win32" - ] - }, - "node_modules/@types/acorn": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", - "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/@types/babel__core": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", - "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dependencies": { - "@babel/types": "^7.0.0" + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@types/babel__traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", - "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", - "dependencies": { - "@babel/types": "^7.20.7" + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" } }, - "node_modules/@types/debug": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", - "integrity": "sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==", - "dependencies": { - "@types/ms": "*" + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" } }, - "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" - }, - "node_modules/@types/estree-jsx": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.0.tgz", - "integrity": "sha512-3qvGd0z8F2ENTGr/GG1yViqfiKmRfrXVx5sJyHGFu3z7m5g5utCQtGp/g29JnjflhtQJBv1WDQukHiT58xPcYQ==", - "dependencies": { - "@types/estree": "*" + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" } }, - "node_modules/@types/hast": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.5.tgz", - "integrity": "sha512-SvQi0L/lNpThgPoleH53cdjB3y9zpLlVjRbqB3rH8hx1jiRSBGAhyjV3H+URFjNVRqt2EdYNrbZE5IsGlNfpRg==", - "dependencies": { - "@types/unist": "^2" + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" } }, - "node_modules/@types/json5": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.30.tgz", - "integrity": "sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==" - }, - "node_modules/@types/mdast": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.12.tgz", - "integrity": "sha512-DT+iNIRNX884cx0/Q1ja7NyUPpZuv0KPyL5rGNxm1WC1OtHstl7n4Jb7nk+xacNShQMbczJjt8uFzznpp6kYBg==", - "dependencies": { - "@types/unist": "^2" + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" } }, - "node_modules/@types/mdx": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.7.tgz", - "integrity": "sha512-BG4tyr+4amr3WsSEmHn/fXPqaCba/AYZ7dsaQTiavihQunHSIxk+uAtqsjvicNpyHN6cm+B9RVrUOtW9VzIKHw==" - }, - "node_modules/@types/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" - }, - "node_modules/@types/nlcst": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-1.0.1.tgz", - "integrity": "sha512-aVIyXt6pZiiMOtVByE4Y0gf+BLm1Cxc4ZLSK8VRHn1CgkO+kXbQwN/EBhQmhPdBMjFJCMBKtmNW2zWQuFywz8Q==", - "dependencies": { - "@types/unist": "^2" + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" } }, - "node_modules/@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" - }, - "node_modules/@types/parse5": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", - "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" - }, - "node_modules/@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==" - }, - "node_modules/@types/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==", + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, "dependencies": { - "@types/node": "*" + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/@types/unist": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.7.tgz", - "integrity": "sha512-cputDpIbFgLUaGQn6Vqg3/YsJwxUwHLO13v3i5ouxT4lat0khip9AEWxtERujXV9wxIB1EyF97BSJFt6vpdI8g==" - }, - "node_modules/acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", - "bin": { - "acorn": "bin/acorn" + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=0.4.0" + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "license": "MIT", "dependencies": { - "string-width": "^4.1.0" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/ansi-align/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=6.0.0" } }, - "node_modules/ansi-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "license": "MIT" }, - "node_modules/ansi-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@mdx-js/mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-3.1.1.tgz", + "integrity": "sha512-f6ZO2ifpwAQIpzGWaBQT2TXxPv6z3RBzQKpVftEWN78Vl/YweF1uwussDx8ECAXVtr3Rs89fKyG9YlzUs9DyGQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdx": "^2.0.0", + "acorn": "^8.0.0", + "collapse-white-space": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-util-scope": "^1.0.0", + "estree-walker": "^3.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "markdown-extensions": "^2.0.0", + "recma-build-jsx": "^1.0.0", + "recma-jsx": "^1.0.0", + "recma-stringify": "^1.0.0", + "rehype-recma": "^1.0.0", + "remark-mdx": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "source-map": "^0.7.0", + "unified": "^11.0.0", + "unist-util-position-from-estree": "^2.0.0", + "unist-util-stringify-position": "^4.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" }, - "engines": { - "node": ">=8" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/ansi-align/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/@netlify/functions": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-2.8.2.tgz", + "integrity": "sha512-DeoAQh8LuNPvBE4qsKlezjKj0PyXDryOFJfJKo3Z1qZLKzQ21sT314KQKPVjfvw6knqijj+IO+0kHXy/TJiqNA==", + "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "@netlify/serverless-functions-api": "1.26.1" }, "engines": { - "node": ">=8" + "node": ">=14.0.0" } }, - "node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "node_modules/@netlify/node-cookies": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@netlify/node-cookies/-/node-cookies-0.1.0.tgz", + "integrity": "sha512-OAs1xG+FfLX0LoRASpqzVntVV/RpYkgpI0VrUnw2u0Q1qiZUzcPffxRK8HF3gc4GjuhG5ahOEMJ9bswBiZPq0g==", + "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" + "node": "^14.16.0 || >=16.0.0" } }, - "node_modules/ansi-sequence-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", - "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==" - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/@netlify/serverless-functions-api": { + "version": "1.26.1", + "resolved": "https://registry.npmjs.org/@netlify/serverless-functions-api/-/serverless-functions-api-1.26.1.tgz", + "integrity": "sha512-q3L9i3HoNfz0SGpTIS4zTcKBbRkxzCRpd169eyiTuk3IwcPC3/85mzLHranlKo2b+HYT0gu37YxGB45aD8A3Tw==", + "license": "MIT", "dependencies": { - "color-convert": "^1.9.0" + "@netlify/node-cookies": "^0.1.0", + "urlpattern-polyfill": "8.0.2" }, "engines": { - "node": ">=4" + "node": ">=18.0.0" } }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" }, "engines": { "node": ">= 8" } }, - "node_modules/arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/array-iterate": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", - "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/astring": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", - "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==", - "bin": { - "astring": "bin/astring" - } - }, - "node_modules/astro": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/astro/-/astro-3.0.7.tgz", - "integrity": "sha512-slUnDBXfxMzq5abE4svcKbaeYC/tHZsJYOrzwDNU9lLye3/4cqYP7OuHMTXiRlx7LSpHQlUhwbMe2HqCv2GKag==", - "dependencies": { - "@astrojs/compiler": "^2.0.1", - "@astrojs/internal-helpers": "0.2.0", - "@astrojs/markdown-remark": "3.0.0", - "@astrojs/telemetry": "3.0.1", - "@babel/core": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/parser": "^7.22.10", - "@babel/plugin-transform-react-jsx": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10", - "@types/babel__core": "^7.20.1", - "acorn": "^8.10.0", - "boxen": "^7.1.1", - "chokidar": "^3.5.3", - "ci-info": "^3.8.0", - "clsx": "^2.0.0", - "common-ancestor-path": "^1.0.1", - "cookie": "^0.5.0", - "debug": "^4.3.4", - "devalue": "^4.3.2", - "diff": "^5.1.0", - "es-module-lexer": "^1.3.0", - "esbuild": "^0.19.2", - "estree-walker": "^3.0.3", - "execa": "^8.0.1", - "fast-glob": "^3.3.1", - "github-slugger": "^2.0.0", - "gray-matter": "^4.0.3", - "html-escaper": "^3.0.3", - "http-cache-semantics": "^4.1.1", - "js-yaml": "^4.1.0", - "kleur": "^4.1.4", - "magic-string": "^0.30.3", - "mime": "^3.0.0", - "ora": "^7.0.1", - "p-limit": "^4.0.0", - "path-to-regexp": "^6.2.1", - "preferred-pm": "^3.0.3", - "prompts": "^2.4.2", - "rehype": "^12.0.1", - "resolve": "^1.22.4", - "semver": "^7.5.4", - "server-destroy": "^1.0.1", - "sharp": "^0.32.5", - "shiki": "^0.14.3", - "string-width": "^6.1.0", - "strip-ansi": "^7.1.0", - "tsconfig-resolver": "^3.0.1", - "undici": "^5.23.0", - "unist-util-visit": "^4.1.2", - "vfile": "^5.3.7", - "vite": "^4.4.9", - "vitefu": "^0.2.4", - "which-pm": "^2.0.0", - "yargs-parser": "^21.1.1", - "zod": "3.21.1" - }, - "bin": { - "astro": "astro.js" - }, - "engines": { - "node": ">=18.14.1", - "npm": ">=6.14.0" - } - }, - "node_modules/astro/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/astro/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", - "engines": { - "node": ">=16" + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/astro/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", - "engines": { - "node": ">=16.17.0" - } - }, - "node_modules/astro/node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "node": ">= 8" } }, - "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/@oslojs/encoding": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@oslojs/encoding/-/encoding-1.1.0.tgz", + "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", + "license": "MIT" }, - "node_modules/bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "node_modules/@pagefind/darwin-arm64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.4.0.tgz", + "integrity": "sha512-2vMqkbv3lbx1Awea90gTaBsvpzgRs7MuSgKDxW0m9oV1GPZCZbZBJg/qL83GIUEN2BFlY46dtUZi54pwH+/pTQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "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/@pagefind/darwin-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.4.0.tgz", + "integrity": "sha512-e7JPIS6L9/cJfow+/IAqknsGqEPjJnVXGjpGm25bnq+NPdoD3c/7fAwr1OXkG4Ocjx6ZGSCijXEV4ryMcH2E3A==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" ] }, - "node_modules/bcp-47": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", - "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "node_modules/@pagefind/default-ui": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/default-ui/-/default-ui-1.4.0.tgz", + "integrity": "sha512-wie82VWn3cnGEdIjh4YwNESyS1G6vRHwL6cNjy9CFgNnWW/PGRjsLq300xjVH5sfPFK3iK36UxvIBymtQIEiSQ==", + "license": "MIT" }, - "node_modules/bcp-47-match": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", - "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } + "node_modules/@pagefind/freebsd-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/freebsd-x64/-/freebsd-x64-1.4.0.tgz", + "integrity": "sha512-WcJVypXSZ+9HpiqZjFXMUobfFfZZ6NzIYtkhQ9eOhZrQpeY5uQFqNWLCk7w9RkMUwBv1HAMDW3YJQl/8OqsV0Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "engines": { - "node": ">=8" - } + "node_modules/@pagefind/linux-arm64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.4.0.tgz", + "integrity": "sha512-PIt8dkqt4W06KGmQjONw7EZbhDF+uXI7i0XtRLN1vjCUxM9vGPdtJc2mUyVPevjomrGz5M86M8bqTr6cgDp1Uw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/bl": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", - "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", - "dependencies": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } + "node_modules/@pagefind/linux-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.4.0.tgz", + "integrity": "sha512-z4oddcWwQ0UHrTHR8psLnVlz6USGJ/eOlDPTDYZ4cI8TK8PgwRUPQZp9D2iJPNIPcS6Qx/E4TebjuGJOyK8Mmg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + "node_modules/@pagefind/windows-x64": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.4.0.tgz", + "integrity": "sha512-NkT+YAdgS2FPCn8mIA9bQhiBs+xmniMGq1LFPDhcFn0+2yIUEiIG06t7bsZlhdjknEQRTSdT7YitP6fC5qwP0g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", + "node_modules/@qwik.dev/partytown": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/@qwik.dev/partytown/-/partytown-0.11.2.tgz", + "integrity": "sha512-795y49CqBiKiwKAD+QBZlzlqEK275hVcazZ7wBPSfgC23L+vWuA7PJmMpgxojOucZHzYi5rAAQ+IP1I3BKVZxw==", + "license": "MIT", "dependencies": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" + "dotenv": "^16.4.7" }, - "engines": { - "node": ">=14.16" + "bin": { + "partytown": "bin/partytown.cjs" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/boxen/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=18.0.0" } }, - "node_modules/boxen/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/boxen/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "license": "MIT", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" }, "engines": { - "node": ">=12" + "node": ">=14.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" }, - "engines": { - "node": ">=8" + "peerDependenciesMeta": { + "rollup": { + "optional": true + } } }, - "node_modules/browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } + "node_modules/@rollup/pluginutils/node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.56.0.tgz", + "integrity": "sha512-LNKIPA5k8PF1+jAFomGe3qN3bbIgJe/IlpDBwuVjrDKrJhVWywgnJvflMt/zkbVNLFtF1+94SljYQS6e99klnw==", + "cpu": [ + "arm" ], - "dependencies": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } + "license": "MIT", + "optional": true, + "os": [ + "android" + ] }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "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/@rollup/rollup-android-arm64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.56.0.tgz", + "integrity": "sha512-lfbVUbelYqXlYiU/HApNMJzT1E87UPGvzveGg2h0ktUNlOCxKlWuJ9jtfvs1sKHdwU4fzY7Pl8sAl49/XaEk6Q==", + "cpu": [ + "arm64" ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, - "node_modules/camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001519", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz", - "integrity": "sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } + "license": "MIT", + "optional": true, + "os": [ + "android" ] }, - "node_modules/ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.56.0.tgz", + "integrity": "sha512-EgxD1ocWfhoD6xSOeEEwyE7tDvwTgZc8Bss7wCWe+uc7wO8G34HHCUH+Q6cHqJubxIAnQzAsyUsClt0yFLu06w==", + "cpu": [ + "arm64" ], - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.56.0.tgz", + "integrity": "sha512-1vXe1vcMOssb/hOF8iv52A7feWW2xnu+c8BV4t1F//m9QVLTfNVpEdja5ia762j/UEJe2Z1jAmEqZAK42tVW3g==", + "cpu": [ + "x64" ], - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", - "dependencies": { - "restore-cursor": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-spinners": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", - "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clsx": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", - "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==", - "engines": { - "node": ">=6" - } - }, - "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", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "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==" - }, - "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/comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/common-ancestor-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", - "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.56.0.tgz", + "integrity": "sha512-bof7fbIlvqsyv/DtaXSck4VYQ9lPtoWNFCB/JY4snlFuJREXfZnm+Ej6yaCHfQvofJDXLDMTVxWscVSuQvVWUQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "engines": { - "node": ">= 0.6" - } + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.56.0.tgz", + "integrity": "sha512-KNa6lYHloW+7lTEkYGa37fpvPq+NKG/EHKM8+G/g9WDU7ls4sMqbVRV78J6LdNuVaeeK5WB9/9VAFbKxcbXKYg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.56.0.tgz", + "integrity": "sha512-E8jKK87uOvLrrLN28jnAAAChNq5LeCd2mGgZF+fGF5D507WlG/Noct3lP/QzQ6MrqJ5BCKNwI9ipADB6jyiq2A==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/css-selector-parser": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz", - "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==" - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-named-character-reference": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", - "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", - "dependencies": { - "character-entities": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "engines": { - "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/devalue": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.2.tgz", - "integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==" - }, - "node_modules/diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/direction": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz", - "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==", - "bin": { - "direction": "cli.js" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" - }, - "node_modules/dset": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.2.tgz", - "integrity": "sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==", - "engines": { - "node": ">=4" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "node_modules/electron-to-chromium": { - "version": "1.4.490", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.490.tgz", - "integrity": "sha512-6s7NVJz+sATdYnIwhdshx/N/9O6rvMxmhVoDSDFdj6iA45gHR8EQje70+RYsF4GeB+k0IeNSBnP7yG9ZXJFr7A==" - }, - "node_modules/emoji-regex": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.2.1.tgz", - "integrity": "sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA==" - }, - "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/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/es-module-lexer": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", - "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==" - }, - "node_modules/esbuild": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.2.tgz", - "integrity": "sha512-G6hPax8UbFakEj3hWO0Vs52LQ8k3lnBhxZWomUJDxfz3rZTLqF5k/FCzuNdLx2RbpBiQQF9H9onlDDH1lZsnjg==", - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/android-arm": "0.19.2", - "@esbuild/android-arm64": "0.19.2", - "@esbuild/android-x64": "0.19.2", - "@esbuild/darwin-arm64": "0.19.2", - "@esbuild/darwin-x64": "0.19.2", - "@esbuild/freebsd-arm64": "0.19.2", - "@esbuild/freebsd-x64": "0.19.2", - "@esbuild/linux-arm": "0.19.2", - "@esbuild/linux-arm64": "0.19.2", - "@esbuild/linux-ia32": "0.19.2", - "@esbuild/linux-loong64": "0.19.2", - "@esbuild/linux-mips64el": "0.19.2", - "@esbuild/linux-ppc64": "0.19.2", - "@esbuild/linux-riscv64": "0.19.2", - "@esbuild/linux-s390x": "0.19.2", - "@esbuild/linux-x64": "0.19.2", - "@esbuild/netbsd-x64": "0.19.2", - "@esbuild/openbsd-x64": "0.19.2", - "@esbuild/sunos-x64": "0.19.2", - "@esbuild/win32-arm64": "0.19.2", - "@esbuild/win32-ia32": "0.19.2", - "@esbuild/win32-x64": "0.19.2" - } - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "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/estree-util-attach-comments": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-2.1.1.tgz", - "integrity": "sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w==", - "dependencies": { - "@types/estree": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-build-jsx": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-2.2.2.tgz", - "integrity": "sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "estree-util-is-identifier-name": "^2.0.0", - "estree-walker": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-is-identifier-name": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.1.0.tgz", - "integrity": "sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-to-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-1.2.0.tgz", - "integrity": "sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "astring": "^1.8.0", - "source-map": "^0.7.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-util-visit": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-1.2.1.tgz", - "integrity": "sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "dependencies": { - "@types/estree": "^1.0.0" - } - }, - "node_modules/execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - }, - "engines": { - "node": "^14.18.0 || ^16.14.0 || >=18.0.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "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/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fast-fifo": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.0.tgz", - "integrity": "sha512-IgfweLvEpwyA4WgiQe9Nx6VV2QkML2NkvZnk1oKnIzXgXdWxuhF7zw4DvLTPZJn6PIUneiAXPF24QmoEqHTjyw==" - }, - "node_modules/fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fault": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", - "dependencies": { - "format": "^0.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/find-yarn-workspace-root2": { - "version": "1.2.16", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz", - "integrity": "sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==", - "dependencies": { - "micromatch": "^4.0.2", - "pkg-dir": "^4.2.0" - } - }, - "node_modules/format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", - "engines": { - "node": ">=0.4.x" - } - }, - "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/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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/github-slugger": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==" - }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/gray-matter": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", - "dependencies": { - "js-yaml": "^3.13.1", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/gray-matter/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/gray-matter/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/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/hast-util-from-parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", - "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "hastscript": "^7.0.0", - "property-information": "^6.0.0", - "vfile": "^5.0.0", - "vfile-location": "^4.0.0", - "web-namespaces": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-has-property": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-2.0.1.tgz", - "integrity": "sha512-X2+RwZIMTMKpXUzlotatPzWj8bspCymtXH3cfG3iQKV+wPF53Vgaqxi/eLqGck0wKq1kS9nvoB1wchbCPEL8sg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-parse-selector": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", - "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", - "dependencies": { - "@types/hast": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-raw": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", - "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/parse5": "^6.0.0", - "hast-util-from-parse5": "^7.0.0", - "hast-util-to-parse5": "^7.0.0", - "html-void-elements": "^2.0.0", - "parse5": "^6.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0", - "vfile": "^5.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-select": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-5.0.5.tgz", - "integrity": "sha512-QQhWMhgTFRhCaQdgTKzZ5g31GLQ9qRb1hZtDPMqQaOhpLBziWcshUS0uCR5IJ0U1jrK/mxg35fmcq+Dp/Cy2Aw==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "bcp-47-match": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "css-selector-parser": "^1.0.0", - "direction": "^2.0.0", - "hast-util-has-property": "^2.0.0", - "hast-util-to-string": "^2.0.0", - "hast-util-whitespace": "^2.0.0", - "not": "^0.1.0", - "nth-check": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "unist-util-visit": "^4.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-estree": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-2.3.3.tgz", - "integrity": "sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ==", - "dependencies": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "estree-util-attach-comments": "^2.0.0", - "estree-util-is-identifier-name": "^2.0.0", - "hast-util-whitespace": "^2.0.0", - "mdast-util-mdx-expression": "^1.0.0", - "mdast-util-mdxjs-esm": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.1", - "unist-util-position": "^4.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-html": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.4.tgz", - "integrity": "sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-raw": "^7.0.0", - "hast-util-whitespace": "^2.0.0", - "html-void-elements": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-parse5": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", - "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-to-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-2.0.0.tgz", - "integrity": "sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==", - "dependencies": { - "@types/hast": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hast-util-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", - "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/hastscript": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", - "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", - "dependencies": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^3.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/html-escaper": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", - "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==" - }, - "node_modules/html-void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", - "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, - "node_modules/human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==", - "engines": { - "node": ">=14.18.0" - } - }, - "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/import-meta-resolve": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-3.0.0.tgz", - "integrity": "sha512-4IwhLhNNA8yy445rPjD/lWh++7hMDOml2eHtd58eG7h+qK3EryMuuRbsHGPikCoAgIkkDnckKfWSk2iDla/ejg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "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==" - }, - "node_modules/inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" - }, - "node_modules/is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumerical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "dependencies": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, - "node_modules/is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" - }, - "node_modules/is-reference": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.1.tgz", - "integrity": "sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w==", - "dependencies": { - "@types/estree": "*" - } - }, - "node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-wsl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.0.0.tgz", - "integrity": "sha512-TQ7xXW/fTBaz/HhGSV779AC99ocpvb9qJPuPwyIea+F+Z+htcQ1wouAA0xEQaa4saVqyP8mwkoYp5efeM/4Gbg==", - "dependencies": { - "is-docker": "^3.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/linkify-it": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", - "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", - "dev": true, - "dependencies": { - "uc.micro": "^1.0.1" - } - }, - "node_modules/load-yaml-file": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz", - "integrity": "sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==", - "dependencies": { - "graceful-fs": "^4.1.5", - "js-yaml": "^3.13.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/load-yaml-file/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/load-yaml-file/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/load-yaml-file/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", - "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", - "dependencies": { - "chalk": "^5.0.0", - "is-unicode-supported": "^1.1.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-symbols/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/markdown-extensions": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", - "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/markdown-it": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", - "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - }, - "bin": { - "markdown-it": "bin/markdown-it.js" - } - }, - "node_modules/markdown-table": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", - "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/markdownlint": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.31.1.tgz", - "integrity": "sha512-CKMR2hgcIBrYlIUccDCOvi966PZ0kJExDrUi1R+oF9PvqQmCrTqjOsgIvf2403OmJ+CWomuzDoylr6KbuMyvHA==", - "dev": true, - "dependencies": { - "markdown-it": "13.0.1", - "markdownlint-micromark": "0.1.7" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/markdownlint-micromark": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.7.tgz", - "integrity": "sha512-BbRPTC72fl5vlSKv37v/xIENSRDYL/7X/XoFzZ740FGEbs9vZerLrIkFRY0rv7slQKxDczToYuMmqQFN61fi4Q==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/mdast-util-definitions": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", - "integrity": "sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "unist-util-visit": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-directive": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-2.2.4.tgz", - "integrity": "sha512-sK3ojFP+jpj1n7Zo5ZKvoxP1MvLyzVG63+gm40Z/qI00avzdPCYxt7RBMgofwAva9gBjbDBWVRB/i+UD+fUCzQ==", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "mdast-util-from-markdown": "^1.3.0", - "mdast-util-to-markdown": "^1.5.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^5.1.3" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz", - "integrity": "sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==", - "dependencies": { - "@types/mdast": "^3.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "mdast-util-to-string": "^3.1.0", - "micromark": "^3.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-decode-string": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-frontmatter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-1.0.1.tgz", - "integrity": "sha512-JjA2OjxRqAa8wEG8hloD0uTU0kdn8kbtOWpPP94NBkfAlbxn4S8gCGf/9DwFtEeGPXrDcNXdiDjVaRdUFqYokw==", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0", - "micromark-extension-frontmatter": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz", - "integrity": "sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==", - "dependencies": { - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-gfm-autolink-literal": "^1.0.0", - "mdast-util-gfm-footnote": "^1.0.0", - "mdast-util-gfm-strikethrough": "^1.0.0", - "mdast-util-gfm-table": "^1.0.0", - "mdast-util-gfm-task-list-item": "^1.0.0", - "mdast-util-to-markdown": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-autolink-literal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz", - "integrity": "sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==", - "dependencies": { - "@types/mdast": "^3.0.0", - "ccount": "^2.0.0", - "mdast-util-find-and-replace": "^2.0.0", - "micromark-util-character": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-footnote": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz", - "integrity": "sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0", - "micromark-util-normalize-identifier": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-strikethrough": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz", - "integrity": "sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-table": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz", - "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==", - "dependencies": { - "@types/mdast": "^3.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-to-markdown": "^1.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-gfm-task-list-item": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz", - "integrity": "sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-2.0.1.tgz", - "integrity": "sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw==", - "dependencies": { - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-mdx-expression": "^1.0.0", - "mdast-util-mdx-jsx": "^2.0.0", - "mdast-util-mdxjs-esm": "^1.0.0", - "mdast-util-to-markdown": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-expression": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.3.2.tgz", - "integrity": "sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-to-markdown": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdx-jsx": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-2.1.4.tgz", - "integrity": "sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "ccount": "^2.0.0", - "mdast-util-from-markdown": "^1.1.0", - "mdast-util-to-markdown": "^1.3.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-remove-position": "^4.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-mdxjs-esm": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-1.3.1.tgz", - "integrity": "sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w==", - "dependencies": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-to-markdown": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-phrasing": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz", - "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", - "dependencies": { - "@types/mdast": "^3.0.0", - "unist-util-is": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-hast": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz", - "integrity": "sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-definitions": "^5.0.0", - "micromark-util-sanitize-uri": "^1.1.0", - "trim-lines": "^3.0.0", - "unist-util-generated": "^2.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-markdown": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", - "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", - "dependencies": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^3.0.0", - "mdast-util-to-string": "^3.0.0", - "micromark-util-decode-string": "^1.0.0", - "unist-util-visit": "^4.0.0", - "zwitch": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "dependencies": { - "@types/mdast": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromark": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", - "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], - "dependencies": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "micromark-core-commonmark": "^1.0.1", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "node_modules/micromark-core-commonmark": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", - "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.56.0.tgz", + "integrity": "sha512-jQosa5FMYF5Z6prEpTCCmzCXz6eKr/tCBssSmQGEeozA9tkRUty/5Vx06ibaOP9RCrW1Pvb8yp3gvZhHwTDsJw==", + "cpu": [ + "arm" ], - "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-factory-destination": "^1.0.0", - "micromark-factory-label": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-factory-title": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-html-tag-name": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "node_modules/micromark-extension-directive": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-2.2.1.tgz", - "integrity": "sha512-ZFKZkNaEqAP86IghX1X7sE8NNnx6kFNq9mSBRvEHjArutTCJZ3LYg6VH151lXVb1JHpmIcW/7rX25oMoIHuSug==", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "parse-entities": "^4.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-frontmatter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-1.1.1.tgz", - "integrity": "sha512-m2UH9a7n3W8VAH9JO9y01APpPKmNNNs71P0RbknEmYSaZU5Ghogv38BYO94AI5Xw6OYfxZRdHZZ2nYjs/Z+SZQ==", - "dependencies": { - "fault": "^2.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz", - "integrity": "sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==", - "dependencies": { - "micromark-extension-gfm-autolink-literal": "^1.0.0", - "micromark-extension-gfm-footnote": "^1.0.0", - "micromark-extension-gfm-strikethrough": "^1.0.0", - "micromark-extension-gfm-table": "^1.0.0", - "micromark-extension-gfm-tagfilter": "^1.0.0", - "micromark-extension-gfm-task-list-item": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-types": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-autolink-literal": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz", - "integrity": "sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==", - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-footnote": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz", - "integrity": "sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==", - "dependencies": { - "micromark-core-commonmark": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-strikethrough": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz", - "integrity": "sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==", - "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/micromark-extension-gfm-table": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz", - "integrity": "sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/micromark-extension-gfm-tagfilter": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz", - "integrity": "sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==", - "dependencies": { - "micromark-util-types": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.56.0.tgz", + "integrity": "sha512-uQVoKkrC1KGEV6udrdVahASIsaF8h7iLG0U0W+Xn14ucFwi6uS539PsAr24IEF9/FoDtzMeeJXJIBo5RkbNWvQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/micromark-extension-gfm-task-list-item": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz", - "integrity": "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==", - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.56.0.tgz", + "integrity": "sha512-vLZ1yJKLxhQLFKTs42RwTwa6zkGln+bnXc8ueFGMYmBTLfNu58sl5/eXyxRa2RarTkJbXl8TKPgfS6V5ijNqEA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/micromark-extension-mdx-expression": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.8.tgz", - "integrity": "sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.56.0.tgz", + "integrity": "sha512-FWfHOCub564kSE3xJQLLIC/hbKqHSVxy8vY75/YHHzWvbJL7aYJkdgwD/xGfUlL5UV2SB7otapLrcCj2xnF1dg==", + "cpu": [ + "loong64" ], - "dependencies": { - "@types/estree": "^1.0.0", - "micromark-factory-mdx-expression": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-events-to-acorn": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/micromark-extension-mdx-jsx": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-1.0.5.tgz", - "integrity": "sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA==", - "dependencies": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "estree-util-is-identifier-name": "^2.0.0", - "micromark-factory-mdx-expression": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0", - "vfile-message": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.56.0.tgz", + "integrity": "sha512-z1EkujxIh7nbrKL1lmIpqFTc/sr0u8Uk0zK/qIEFldbt6EDKWFk/pxFq3gYj4Bjn3aa9eEhYRlL3H8ZbPT1xvA==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/micromark-extension-mdx-md": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-1.0.1.tgz", - "integrity": "sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA==", - "dependencies": { - "micromark-util-types": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.56.0.tgz", + "integrity": "sha512-iNFTluqgdoQC7AIE8Q34R3AuPrJGJirj5wMUErxj22deOcY7XwZRaqYmB6ZKFHoVGqRcRd0mqO+845jAibKCkw==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/micromark-extension-mdxjs": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-1.0.1.tgz", - "integrity": "sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q==", - "dependencies": { - "acorn": "^8.0.0", - "acorn-jsx": "^5.0.0", - "micromark-extension-mdx-expression": "^1.0.0", - "micromark-extension-mdx-jsx": "^1.0.0", - "micromark-extension-mdx-md": "^1.0.0", - "micromark-extension-mdxjs-esm": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-types": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.56.0.tgz", + "integrity": "sha512-MtMeFVlD2LIKjp2sE2xM2slq3Zxf9zwVuw0jemsxvh1QOpHSsSzfNOTH9uYW9i1MXFxUSMmLpeVeUzoNOKBaWg==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/micromark-extension-mdxjs-esm": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-1.0.5.tgz", - "integrity": "sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w==", - "dependencies": { - "@types/estree": "^1.0.0", - "micromark-core-commonmark": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-events-to-acorn": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-position-from-estree": "^1.1.0", - "uvu": "^0.5.0", - "vfile-message": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.56.0.tgz", + "integrity": "sha512-in+v6wiHdzzVhYKXIk5U74dEZHdKN9KH0Q4ANHOTvyXPG41bajYRsy7a8TPKbYPl34hU7PP7hMVHRvv/5aCSew==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/micromark-factory-destination": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", - "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.56.0.tgz", + "integrity": "sha512-yni2raKHB8m9NQpI9fPVwN754mn6dHQSbDTwxdr9SE0ks38DTjLMMBjrwvB5+mXrX+C0npX0CVeCUcvvvD8CNQ==", + "cpu": [ + "riscv64" ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/micromark-factory-label": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", - "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.56.0.tgz", + "integrity": "sha512-zhLLJx9nQPu7wezbxt2ut+CI4YlXi68ndEve16tPc/iwoylWS9B3FxpLS2PkmfYgDQtosah07Mj9E0khc3Y+vQ==", + "cpu": [ + "s390x" ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/micromark-factory-mdx-expression": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.9.tgz", - "integrity": "sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.56.0.tgz", + "integrity": "sha512-MVC6UDp16ZSH7x4rtuJPAEoE1RwS8N4oK9DLHy3FTEdFoUTCFVzMfJl/BVJ330C+hx8FfprA5Wqx4FhZXkj2Kw==", + "cpu": [ + "x64" ], - "dependencies": { - "@types/estree": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-events-to-acorn": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-position-from-estree": "^1.0.0", - "uvu": "^0.5.0", - "vfile-message": "^3.0.0" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.56.0.tgz", + "integrity": "sha512-ZhGH1eA4Qv0lxaV00azCIS1ChedK0V32952Md3FtnxSqZTBTd6tgil4nZT5cU8B+SIw3PFYkvyR4FKo2oyZIHA==", + "cpu": [ + "x64" ], - "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/micromark-factory-title": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.56.0.tgz", + "integrity": "sha512-O16XcmyDeFI9879pEcmtWvD/2nyxR9mF7Gs44lf1vGGx8Vg2DRNx11aVXBEqOQhWb92WN4z7fW/q4+2NYzCbBA==", + "cpu": [ + "x64" ], - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] }, - "node_modules/micromark-factory-whitespace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.56.0.tgz", + "integrity": "sha512-LhN/Reh+7F3RCgQIRbgw8ZMwUwyqJM+8pXNT6IIJAqm2IdKkzpCh/V9EdgOMBKuebIrzswqy4ATlrDgiOwbRcQ==", + "cpu": [ + "arm64" ], - "dependencies": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] }, - "node_modules/micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.56.0.tgz", + "integrity": "sha512-kbFsOObXp3LBULg1d3JIUQMa9Kv4UitDmpS+k0tinPBz3watcUiV2/LUDMMucA6pZO3WGE27P7DsfaN54l9ing==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.56.0.tgz", + "integrity": "sha512-vSSgny54D6P4vf2izbtFm/TcWYedw7f8eBrOiGGecyHyQB9q4Kqentjaj8hToe+995nob/Wv48pDqL5a62EWtg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.56.0.tgz", + "integrity": "sha512-FeCnkPCTHQJFbiGG49KjV5YGW/8b9rrXAM2Mz2kiIoktq2qsJxRD5giEMEOD2lPdgs72upzefaUvS+nc8E3UzQ==", + "cpu": [ + "x64" ], - "dependencies": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.56.0.tgz", + "integrity": "sha512-H8AE9Ur/t0+1VXujj90w0HrSOuv0Nq9r1vSZF2t5km20NTfosQsGGUXDaKdQZzwuLts7IyL1fYT4hM95TI9c4g==", + "cpu": [ + "x64" ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@shikijs/core": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-1.29.2.tgz", + "integrity": "sha512-vju0lY9r27jJfOY4Z7+Rt/nIOjzJpZ3y+nYpqtUZInVoXQ/TJZcfGnNOGnKjFdVZb8qexiCuSlZRKcGfhhTTZQ==", + "license": "MIT", "dependencies": { - "micromark-util-symbol": "^1.0.0" + "@shikijs/engine-javascript": "1.29.2", + "@shikijs/engine-oniguruma": "1.29.2", + "@shikijs/types": "1.29.2", + "@shikijs/vscode-textmate": "^10.0.1", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.4" } }, - "node_modules/micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/@shikijs/engine-javascript": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-1.29.2.tgz", + "integrity": "sha512-iNEZv4IrLYPv64Q6k7EPpOCE/nuvGiKl7zxdq0WFuRPF5PAE9PRo2JGq/d8crLusM59BRemJ4eOqrFrC4wiQ+A==", + "license": "MIT", "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "@shikijs/types": "1.29.2", + "@shikijs/vscode-textmate": "^10.0.1", + "oniguruma-to-es": "^2.2.0" } }, - "node_modules/micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/@shikijs/engine-oniguruma": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-1.29.2.tgz", + "integrity": "sha512-7iiOx3SG8+g1MnlzZVDYiaeHe7Ez2Kf2HrJzdmGwkRisT7r4rak0e655AcM/tF9JG/kg5fMNYlLLKglbN7gBqA==", + "license": "MIT", "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" + "@shikijs/types": "1.29.2", + "@shikijs/vscode-textmate": "^10.0.1" } }, - "node_modules/micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/@shikijs/langs": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-1.29.2.tgz", + "integrity": "sha512-FIBA7N3LZ+223U7cJDUYd5shmciFQlYkFXlkKVaHsCPgfVLiO+e12FmQE6Tf9vuyEsFe3dIl8qGWKXgEHL9wmQ==", + "license": "MIT", "dependencies": { - "micromark-util-symbol": "^1.0.0" + "@shikijs/types": "1.29.2" } }, - "node_modules/micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/@shikijs/themes": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-1.29.2.tgz", + "integrity": "sha512-i9TNZlsq4uoyqSbluIcZkmPL9Bfi3djVxRnofUHwvx/h6SRW3cwgBC5SML7vsDcWyukY0eCzVN980rqP6qNl9g==", + "license": "MIT", "dependencies": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" + "@shikijs/types": "1.29.2" } }, - "node_modules/micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] - }, - "node_modules/micromark-util-events-to-acorn": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.3.tgz", - "integrity": "sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/@shikijs/types": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-1.29.2.tgz", + "integrity": "sha512-VJjK0eIijTZf0QSTODEXCqinjBn0joAHQ+aPSBzrv4O2d/QSbsMw+ZeSRx03kV34Hy7NzUvV/7NqfYGRLrASmw==", + "license": "MIT", "dependencies": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "@types/unist": "^2.0.0", - "estree-util-visit": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0", - "vfile-message": "^3.0.0" + "@shikijs/vscode-textmate": "^10.0.1", + "@types/hast": "^3.0.4" } }, - "node_modules/micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@shikijs/vscode-textmate/-/vscode-textmate-10.0.2.tgz", + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==", + "license": "MIT" }, - "node_modules/micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "license": "MIT", "dependencies": { - "micromark-util-symbol": "^1.0.0" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" } }, - "node_modules/micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/@types/babel__generator": { + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", + "license": "MIT", "dependencies": { - "micromark-util-types": "^1.0.0" + "@babel/types": "^7.0.0" } }, - "node_modules/micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "license": "MIT", "dependencies": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" } }, - "node_modules/micromark-util-subtokenize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ], + "node_modules/@types/babel__traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", + "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", + "license": "MIT", "dependencies": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" + "@babel/types": "^7.28.2" } }, - "node_modules/micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] + "node_modules/@types/cookie": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==", + "license": "MIT" }, - "node_modules/micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", - "funding": [ - { - "type": "GitHub Sponsors", - "url": "https://github.com/sponsors/unifiedjs" - }, - { - "type": "OpenCollective", - "url": "https://opencollective.com/unified" - } - ] + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "license": "MIT" + }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" + "@types/estree": "*" } }, - "node_modules/mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=10.0.0" + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" } }, - "node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" } }, - "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/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==", + "license": "MIT" + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, + "node_modules/@types/nlcst": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-2.0.3.tgz", + "integrity": "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/@types/node": { + "version": "25.0.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-25.0.10.tgz", + "integrity": "sha512-zWW5KPngR/yvakJgGOmZ5vTBemDoSqF3AcV/LrO5u5wTWyEAVVh+IT39G4gtyAkh3CtTZs8aX/yRM82OfzHJRg==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.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/@types/picomatch": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/picomatch/-/picomatch-2.3.3.tgz", + "integrity": "sha512-Yll76ZHikRFCyz/pffKGjrCwe/le2CDwOP5F210KQo27kpRE46U2rDnzikNlVn6/ezH3Mhn46bJMTfeVTtcYMg==", + "license": "MIT" }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "engines": { - "node": ">=4" + "node_modules/@types/sax": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.7.tgz", + "integrity": "sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==", + "license": "MIT", + "dependencies": { + "@types/node": "*" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" }, - "node_modules/nanoid": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", - "integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "license": "MIT", "bin": { - "nanoid": "bin/nanoid.cjs" + "acorn": "bin/acorn" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=0.4.0" } }, - "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/acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } }, - "node_modules/nlcst-to-string": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-3.1.1.tgz", - "integrity": "sha512-63mVyqaqt0cmn2VcI2aH6kxe1rLAmSROqHMA0i4qqg1tidkfExgpb0FGMikMCn86mw5dFtBtEANfmSSK7TjNHw==", + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "license": "ISC", "dependencies": { - "@types/nlcst": "^1.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "string-width": "^4.1.0" } }, - "node_modules/node-abi": { - "version": "3.45.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.45.0.tgz", - "integrity": "sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ==", - "dependencies": { - "semver": "^7.3.5" - }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=8" } }, - "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/node-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/not": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz", - "integrity": "sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA==" - }, - "node_modules/npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { - "path-key": "^4.0.0" + "ansi-regex": "^5.0.1" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "license": "MIT", + "engines": { + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "license": "MIT", "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "dependencies": { - "boolbase": "^1.0.0" - }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/aria-query": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.2.tgz", + "integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/array-iterate": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==", + "license": "MIT", "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "license": "MIT", + "bin": { + "astring": "bin/astring" } }, - "node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dependencies": { - "mimic-fn": "^4.0.0" + "node_modules/astro": { + "version": "4.16.19", + "resolved": "https://registry.npmjs.org/astro/-/astro-4.16.19.tgz", + "integrity": "sha512-baeSswPC5ZYvhGDoj25L2FuzKRWMgx105FetOPQVJFMCAp0o08OonYC7AhwsFdhvp7GapqjnC1Fe3lKb2lupYw==", + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.10.3", + "@astrojs/internal-helpers": "0.4.1", + "@astrojs/markdown-remark": "5.3.0", + "@astrojs/telemetry": "3.1.0", + "@babel/core": "^7.26.0", + "@babel/plugin-transform-react-jsx": "^7.25.9", + "@babel/types": "^7.26.0", + "@oslojs/encoding": "^1.1.0", + "@rollup/pluginutils": "^5.1.3", + "@types/babel__core": "^7.20.5", + "@types/cookie": "^0.6.0", + "acorn": "^8.14.0", + "aria-query": "^5.3.2", + "axobject-query": "^4.1.0", + "boxen": "8.0.1", + "ci-info": "^4.1.0", + "clsx": "^2.1.1", + "common-ancestor-path": "^1.0.1", + "cookie": "^0.7.2", + "cssesc": "^3.0.0", + "debug": "^4.3.7", + "deterministic-object-hash": "^2.0.2", + "devalue": "^5.1.1", + "diff": "^5.2.0", + "dlv": "^1.1.3", + "dset": "^3.1.4", + "es-module-lexer": "^1.5.4", + "esbuild": "^0.21.5", + "estree-walker": "^3.0.3", + "fast-glob": "^3.3.2", + "flattie": "^1.1.1", + "github-slugger": "^2.0.0", + "gray-matter": "^4.0.3", + "html-escaper": "^3.0.3", + "http-cache-semantics": "^4.1.1", + "js-yaml": "^4.1.0", + "kleur": "^4.1.5", + "magic-string": "^0.30.14", + "magicast": "^0.3.5", + "micromatch": "^4.0.8", + "mrmime": "^2.0.0", + "neotraverse": "^0.6.18", + "ora": "^8.1.1", + "p-limit": "^6.1.0", + "p-queue": "^8.0.1", + "preferred-pm": "^4.0.0", + "prompts": "^2.4.2", + "rehype": "^13.0.2", + "semver": "^7.6.3", + "shiki": "^1.23.1", + "tinyexec": "^0.3.1", + "tsconfck": "^3.1.4", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.3", + "vite": "^5.4.11", + "vitefu": "^1.0.4", + "which-pm": "^3.0.0", + "xxhash-wasm": "^1.1.0", + "yargs-parser": "^21.1.1", + "zod": "^3.23.8", + "zod-to-json-schema": "^3.23.5", + "zod-to-ts": "^1.2.0" + }, + "bin": { + "astro": "astro.js" }, "engines": { - "node": ">=12" + "node": "^18.17.1 || ^20.3.0 || >=21.0.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "optionalDependencies": { + "sharp": "^0.33.3" } }, - "node_modules/ora": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-7.0.1.tgz", - "integrity": "sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==", + "node_modules/astro-expressive-code": { + "version": "0.35.6", + "resolved": "https://registry.npmjs.org/astro-expressive-code/-/astro-expressive-code-0.35.6.tgz", + "integrity": "sha512-1U4KrvFuodaCV3z4I1bIR16SdhQlPkolGsYTtiANxPZUVv/KitGSCTjzksrkPonn1XuwVqvnwmUUVzTLWngnBA==", + "license": "MIT", "dependencies": { - "chalk": "^5.3.0", - "cli-cursor": "^4.0.0", - "cli-spinners": "^2.9.0", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^1.3.0", - "log-symbols": "^5.1.0", - "stdin-discarder": "^0.1.0", - "string-width": "^6.1.0", - "strip-ansi": "^7.1.0" + "rehype-expressive-code": "^0.35.6" }, + "peerDependencies": { + "astro": "^4.0.0-beta || ^3.3.0" + } + }, + "node_modules/astro/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/ora/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "node_modules/astro/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=12" } }, - "node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dependencies": { - "yocto-queue": "^1.0.0" - }, + "node_modules/astro/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, + "node_modules/astro/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/p-locate/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, + "node_modules/astro/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/astro/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/p-locate/node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "node_modules/astro/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "node_modules/astro/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/pagefind": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.0.0-alpha.10.tgz", - "integrity": "sha512-ewzRIDzU4HsAaca9rzOFaipMctEoA0XIFyNIDfy1mPM98HCEeTFcZ3Lp4+KcPHZLadsdjLbFLcBFBIAeWisbQw==", - "bin": { - "pagefind": "lib/runner/bin.cjs" - }, - "optionalDependencies": { - "@pagefind/darwin-arm64": "1.0.0-alpha.10", - "@pagefind/darwin-x64": "1.0.0-alpha.10", - "@pagefind/linux-arm64": "1.0.0-alpha.10", - "@pagefind/linux-x64": "1.0.0-alpha.10", - "@pagefind/windows-x64": "1.0.0-alpha.10" + "node_modules/astro/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/parse-entities": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", - "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", - "dependencies": { - "@types/unist": "^2.0.0", - "character-entities": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/astro/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/parse-latin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-5.0.1.tgz", - "integrity": "sha512-b/K8ExXaWC9t34kKeDV8kGXBkXZ1HCSAZRYE7HR14eA1GlXX5L8iWhs8USJNhQU9q5ci413jCKF0gOyovvyRBg==", - "dependencies": { - "nlcst-to-string": "^3.0.0", - "unist-util-modify-children": "^3.0.0", - "unist-util-visit-children": "^2.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/astro/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/astro/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/astro/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" - }, - "node_modules/periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" + "node_modules/astro/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/astro/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "node": ">=12" } }, - "node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "node_modules/astro/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=6" + "node": ">=12" } }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dependencies": { - "find-up": "^4.0.0" - }, + "node_modules/astro/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, + "node_modules/astro/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dependencies": { - "p-locate": "^4.1.0" - }, + "node_modules/astro/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, + "node_modules/astro/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=12" } }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dependencies": { - "p-limit": "^2.2.0" - }, + "node_modules/astro/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/postcss": { - "version": "8.4.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", - "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } + "node_modules/astro/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" ], - "dependencies": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">=12" } }, - "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" - }, + "node_modules/astro/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, + "license": "MIT", "bin": { - "prebuild-install": "bin.js" + "esbuild": "bin/esbuild" }, "engines": { - "node": ">=10" - } - }, - "node_modules/prebuild-install/node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/astro/node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "optional": true, "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/axobject-query": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-4.1.0.tgz", + "integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==", + "license": "Apache-2.0", + "engines": { + "node": ">= 0.4" } }, - "node_modules/prebuild-install/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" + "node_modules/b4a": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" } }, - "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/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "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" + "node_modules/bare-events": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", + "license": "Apache-2.0", + "peerDependencies": { + "bare-abort-controller": "*" }, - "engines": { - "node": ">=6" + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } } }, - "node_modules/preferred-pm": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/preferred-pm/-/preferred-pm-3.0.3.tgz", - "integrity": "sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==", + "node_modules/bare-fs": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.2.tgz", + "integrity": "sha512-veTnRzkb6aPHOvSKIOy60KzURfBdUflr5VReI+NSaPL6xf+XLdONQgZgpYvUuZLVQ8dCqxpBAudaOM1+KpAUxw==", + "license": "Apache-2.0", + "optional": true, "dependencies": { - "find-up": "^5.0.0", - "find-yarn-workspace-root2": "1.2.16", - "path-exists": "^4.0.0", - "which-pm": "2.0.0" + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4", + "bare-url": "^2.2.2", + "fast-fifo": "^1.3.2" }, "engines": { - "node": ">=10" - } - }, - "node_modules/prettier": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz", - "integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==", - "bin": { - "prettier": "bin/prettier.cjs" + "bare": ">=1.16.0" }, - "engines": { - "node": ">=14" + "peerDependencies": { + "bare-buffer": "*" }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } } }, - "node_modules/prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==", + "node_modules/bare-os": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", + "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", + "license": "Apache-2.0", + "optional": true, "engines": { - "node": ">=6" + "bare": ">=1.14.0" } }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "node_modules/bare-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", + "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", + "license": "Apache-2.0", + "optional": true, "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prompts/node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "engines": { - "node": ">=6" + "bare-os": "^3.0.1" } }, - "node_modules/property-information": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz", - "integrity": "sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/bare-stream": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", + "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "streamx": "^2.21.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": 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==", + "node_modules/bare-url": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", + "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", + "license": "Apache-2.0", + "optional": true, "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" + "bare-path": "^3.0.0" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "node_modules/base-64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", + "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", + "license": "MIT" + }, + "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", @@ -4865,255 +2938,298 @@ "type": "consulting", "url": "https://feross.org/support" } - ] + ], + "license": "MIT" }, - "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/baseline-browser-mapping": { + "version": "2.9.18", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.18.tgz", + "integrity": "sha512-e23vBV1ZLfjb9apvfPk4rHVu2ry6RIr2Wfs+O324okSidrX7pTAnEJPCh/O5BtRlr7QtZI7ktOP3vsqr7Z5XoA==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "node_modules/bcp-47": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", + "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", + "license": "MIT", "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" + "is-alphabetical": "^2.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0" }, - "bin": { - "rc": "cli.js" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "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==", + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "license": "ISC" + }, + "node_modules/boxen": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-8.0.1.tgz", + "integrity": "sha512-F3PH5k5juxom4xktynS7MoFY+NUWH5LC4CnH11YB8NPew+HLpmBLCybSAEyb2F+4pRXhuhWqFesoQd6DAyc2hw==", + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^8.0.0", + "chalk": "^5.3.0", + "cli-boxes": "^3.0.0", + "string-width": "^7.2.0", + "type-fest": "^4.21.0", + "widest-line": "^5.0.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">= 6" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", "dependencies": { - "picomatch": "^2.2.1" + "fill-range": "^7.1.1" }, "engines": { - "node": ">=8.10.0" + "node": ">=8" } }, - "node_modules/rehype": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/rehype/-/rehype-12.0.1.tgz", - "integrity": "sha512-ey6kAqwLM3X6QnMDILJthGvG1m1ULROS9NT4uG9IDCuv08SFyLlreSuvOa//DgEvbXx62DS6elGVqusWhRUbgw==", + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", "dependencies": { - "@types/hast": "^2.0.0", - "rehype-parse": "^8.0.0", - "rehype-stringify": "^9.0.0", - "unified": "^10.0.0" + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/rehype-parse": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-8.0.4.tgz", - "integrity": "sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg==", - "dependencies": { - "@types/hast": "^2.0.0", - "hast-util-from-parse5": "^7.0.0", - "parse5": "^6.0.0", - "unified": "^10.0.0" + "bin": { + "browserslist": "cli.js" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/rehype-raw": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz", - "integrity": "sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==", + "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" + } + ], + "license": "MIT", "dependencies": { - "@types/hast": "^2.0.0", - "hast-util-raw": "^7.2.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" } }, - "node_modules/rehype-stringify": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-9.0.4.tgz", - "integrity": "sha512-Uk5xu1YKdqobe5XpSskwPvo1XeHUUucWEQSl8hTrXt5selvca1e8K1EZ37E6YoZ4BT8BCqCdVfQW7OfHfthtVQ==", - "dependencies": { - "@types/hast": "^2.0.0", - "hast-util-to-html": "^8.0.0", - "unified": "^10.0.0" + "node_modules/camelcase": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", + "integrity": "sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==", + "license": "MIT", + "engines": { + "node": ">=16" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/remark-directive": { + "node_modules/caniuse-lite": { + "version": "1.0.30001766", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001766.tgz", + "integrity": "sha512-4C0lfJ0/YPjJQHagaE9x2Elb69CIqEPZeG0anQt9SIvIoOH4a4uaRl73IavyO+0qZh6MDLH//DrXThEYKHkmYA==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-2.0.1.tgz", - "integrity": "sha512-oosbsUAkU/qmUE78anLaJePnPis4ihsE7Agp0T/oqTzvTea8pOiaYEtfInU/+xMOVTS9PN5AhGOiaIVe4GD8gw==", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-directive": "^2.0.0", - "micromark-extension-directive": "^2.0.0", - "unified": "^10.0.0" - }, + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/remark-frontmatter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-4.0.1.tgz", - "integrity": "sha512-38fJrB0KnmD3E33a5jZC/5+gGAC2WKNiPw1/fdXJvijBlhA7RCsvJklrYJakS0HedninvaCYW8lQGf9C918GfA==", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-frontmatter": "^1.0.0", - "micromark-extension-frontmatter": "^1.0.0", - "unified": "^10.0.0" + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/remark-gfm": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz", - "integrity": "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-gfm": "^2.0.0", - "micromark-extension-gfm": "^2.0.0", - "unified": "^10.0.0" - }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/remark-mdx": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-2.3.0.tgz", - "integrity": "sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g==", - "dependencies": { - "mdast-util-mdx": "^2.0.0", - "micromark-extension-mdxjs": "^1.0.0" - }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/remark-parse": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz", - "integrity": "sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==", - "dependencies": { - "@types/mdast": "^3.0.0", - "mdast-util-from-markdown": "^1.0.0", - "unified": "^10.0.0" - }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/remark-rehype": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz", - "integrity": "sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==", - "dependencies": { - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-to-hast": "^12.1.0", - "unified": "^10.0.0" - }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/remark-smartypants": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-2.0.0.tgz", - "integrity": "sha512-Rc0VDmr/yhnMQIz8n2ACYXlfw/P/XZev884QU1I5u+5DgJls32o97Vc1RbK3pfumLsJomS2yy8eT4Fxj/2MDVA==", - "dependencies": { - "retext": "^8.1.0", - "retext-smartypants": "^5.1.0", - "unist-util-visit": "^4.1.0" - }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/ci-info": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", + "integrity": "sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=8" } }, - "node_modules/resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "license": "MIT", + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "license": "MIT", "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" + "restore-cursor": "^5.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/restore-cursor/node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/restore-cursor/node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "license": "MIT", "engines": { "node": ">=6" }, @@ -5121,461 +3237,407 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/retext": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/retext/-/retext-8.1.0.tgz", - "integrity": "sha512-N9/Kq7YTn6ZpzfiGW45WfEGJqFf1IM1q8OsRa1CGzIebCJBNCANDRmOrholiDRGKo/We7ofKR4SEvcGAWEMD3Q==", - "dependencies": { - "@types/nlcst": "^1.0.0", - "retext-latin": "^3.0.0", - "retext-stringify": "^3.0.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/retext-latin": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-3.1.0.tgz", - "integrity": "sha512-5MrD1tuebzO8ppsja5eEu+ZbBeUNCjoEarn70tkXOS7Bdsdf6tNahsv2bY0Z8VooFF6cw7/6S+d3yI/TMlMVVQ==", - "dependencies": { - "@types/nlcst": "^1.0.0", - "parse-latin": "^5.0.0", - "unherit": "^3.0.0", - "unified": "^10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "node_modules/clsx": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", + "integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==", + "license": "MIT", + "engines": { + "node": ">=6" } }, - "node_modules/retext-smartypants": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-5.2.0.tgz", - "integrity": "sha512-Do8oM+SsjrbzT2UNIKgheP0hgUQTDDQYyZaIY3kfq0pdFzoPk+ZClYJ+OERNXveog4xf1pZL4PfRxNoVL7a/jw==", - "dependencies": { - "@types/nlcst": "^1.0.0", - "nlcst-to-string": "^3.0.0", - "unified": "^10.0.0", - "unist-util-visit": "^4.0.0" - }, + "node_modules/collapse-white-space": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-2.1.0.tgz", + "integrity": "sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==", + "license": "MIT", "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/retext-stringify": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-3.1.0.tgz", - "integrity": "sha512-767TLOaoXFXyOnjx/EggXlb37ZD2u4P1n0GJqVdpipqACsQP+20W+BNpMYrlJkq7hxffnFk+jc6mAK9qrbuB8w==", + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", "dependencies": { - "@types/nlcst": "^1.0.0", - "nlcst-to-string": "^3.0.0", - "unified": "^10.0.0" + "color-convert": "^2.0.1", + "color-string": "^1.9.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" + "node": ">=12.5.0" } }, - "node_modules/rollup": { - "version": "3.28.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.0.tgz", - "integrity": "sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw==", - "bin": { - "rollup": "dist/bin/rollup" + "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==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" }, "engines": { - "node": ">=14.18.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "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": { - "queue-microtask": "^1.2.2" + "node": ">=7.0.0" } }, - "node_modules/sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "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==", + "license": "MIT" + }, + "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==", + "license": "MIT", "dependencies": { - "mri": "^1.1.0" - }, + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/common-ancestor-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", + "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", + "license": "ISC" + }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 0.6" } }, - "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==", + "node_modules/css-selector-parser": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-3.3.0.tgz", + "integrity": "sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g==", "funding": [ { "type": "github", - "url": "https://github.com/sponsors/feross" + "url": "https://github.com/sponsors/mdevils" }, { "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" + "url": "https://patreon.com/mdevils" } - ] - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + ], + "license": "MIT" }, - "node_modules/section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "dependencies": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" }, "engines": { "node": ">=4" } }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "license": "MIT", "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "ms": "^2.1.3" }, "engines": { - "node": ">=10" + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/semver/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", "dependencies": { - "yallist": "^4.0.0" + "character-entities": "^2.0.0" }, - "engines": { - "node": ">=10" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "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==" - }, - "node_modules/server-destroy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", - "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==" - }, - "node_modules/sharp": { - "version": "0.32.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.5.tgz", - "integrity": "sha512-0dap3iysgDkNaPOaOL4X/0akdu0ma62GcdC2NBQ+93eqpePdDdr2/LM0sFdDSMmN7yS+odyZtPsb7tx/cYBKnQ==", - "hasInstallScript": true, + "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==", + "license": "MIT", "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" + "mimic-response": "^3.1.0" }, "engines": { - "node": ">=14.15.0" + "node": ">=10" }, "funding": { - "url": "https://opencollective.com/libvips" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, + "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==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=4.0.0" } }, - "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==", + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/shiki": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.3.tgz", - "integrity": "sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==", - "dependencies": { - "ansi-sequence-parser": "^1.1.0", - "jsonc-parser": "^3.2.0", - "vscode-oniguruma": "^1.7.0", - "vscode-textmate": "^8.0.0" + "node": ">=6" } }, - "node_modules/shiki/node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" - }, - "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/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" } }, - "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==", + "node_modules/deterministic-object-hash": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/deterministic-object-hash/-/deterministic-object-hash-2.0.2.tgz", + "integrity": "sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==", + "license": "MIT", "dependencies": { - "is-arrayish": "^0.3.1" + "base-64": "^1.0.0" + }, + "engines": { + "node": ">=18" } }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" + "node_modules/devalue": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.2.tgz", + "integrity": "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==", + "license": "MIT" }, - "node_modules/sitemap": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", - "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", "dependencies": { - "@types/node": "^17.0.5", - "@types/sax": "^1.2.1", - "arg": "^5.0.0", - "sax": "^1.2.4" - }, - "bin": { - "sitemap": "dist/cli.js" + "dequal": "^2.0.0" }, - "engines": { - "node": ">=12.0.0", - "npm": ">=5.6.0" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "engines": { - "node": ">= 8" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "node_modules/diff": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.2.tgz", + "integrity": "sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==", + "license": "BSD-3-Clause", "engines": { - "node": ">=0.10.0" + "node": ">=0.3.1" } }, - "node_modules/space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "node_modules/direction": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz", + "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==", + "license": "MIT", + "bin": { + "direction": "cli.js" + }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "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/dlv": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", + "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", + "license": "MIT" }, - "node_modules/stdin-discarder": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", - "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", - "dependencies": { - "bl": "^5.0.0" - }, + "node_modules/dotenv": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", + "license": "BSD-2-Clause", "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://dotenvx.com" } }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "node_modules/dset": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.4.tgz", + "integrity": "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==", + "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": ">=4" } }, - "node_modules/streamx": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz", - "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==", - "dependencies": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" - } + "node_modules/electron-to-chromium": { + "version": "1.5.278", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.278.tgz", + "integrity": "sha512-dQ0tM1svDRQOwxnXxm+twlGTjr9Upvt8UFWAgmLsxEzFQxhbti4VwxmMjsDxVC51Zo84swW7FVCXEV+VAkhuPw==", + "license": "ISC" }, - "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==", + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "license": "MIT" + }, + "node_modules/emoji-regex-xs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex-xs/-/emoji-regex-xs-1.0.0.tgz", + "integrity": "sha512-LRlerrMYoIDrT6jgpeZ2YYl/L8EulRTt5hQcYjy5AInh7HWXKimpqx68aknBFpGL2+/IcogTcaydJEgaTmOpDg==", + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", "dependencies": { - "safe-buffer": "~5.2.0" + "once": "^1.4.0" } }, - "node_modules/string-width": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz", - "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^10.2.1", - "strip-ansi": "^7.0.1" - }, + "node_modules/entities": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", + "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", + "dev": true, + "license": "BSD-2-Clause", "engines": { - "node": ">=16" + "node": ">=0.12" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/stringify-entities": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", - "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "license": "MIT" + }, + "node_modules/esast-util-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/esast-util-from-estree/-/esast-util-from-estree-2.0.0.tgz", + "integrity": "sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==", + "license": "MIT", "dependencies": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "node_modules/esast-util-from-js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/esast-util-from-js/-/esast-util-from-js-2.0.1.tgz", + "integrity": "sha512-8Ja+rNJ0Lt56Pcf3TAmpBZjmx8ZcK5Ts4cAzIOjsjevg9oSXJnl6SUQ2EevU8tv3h6ZLWmoKL5H4fgWvdvfETw==", + "license": "MIT", "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" + "@types/estree-jsx": "^1.0.0", + "acorn": "^8.0.0", + "esast-util-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" }, "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "node_modules/esbuild": { + "version": "0.19.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.12.tgz", + "integrity": "sha512-aARqgq8roFBj054KvQr5f1sFu0D65G+miZRCuJyJ0G13Zwx7vRar5Zhn2tkQNzIXcBrNVsv/8stehpj+GAjgbg==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, "engines": { - "node": ">=8" + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.19.12", + "@esbuild/android-arm": "0.19.12", + "@esbuild/android-arm64": "0.19.12", + "@esbuild/android-x64": "0.19.12", + "@esbuild/darwin-arm64": "0.19.12", + "@esbuild/darwin-x64": "0.19.12", + "@esbuild/freebsd-arm64": "0.19.12", + "@esbuild/freebsd-x64": "0.19.12", + "@esbuild/linux-arm": "0.19.12", + "@esbuild/linux-arm64": "0.19.12", + "@esbuild/linux-ia32": "0.19.12", + "@esbuild/linux-loong64": "0.19.12", + "@esbuild/linux-mips64el": "0.19.12", + "@esbuild/linux-ppc64": "0.19.12", + "@esbuild/linux-riscv64": "0.19.12", + "@esbuild/linux-s390x": "0.19.12", + "@esbuild/linux-x64": "0.19.12", + "@esbuild/netbsd-x64": "0.19.12", + "@esbuild/openbsd-x64": "0.19.12", + "@esbuild/sunos-x64": "0.19.12", + "@esbuild/win32-arm64": "0.19.12", + "@esbuild/win32-ia32": "0.19.12", + "@esbuild/win32-x64": "0.19.12" } }, - "node_modules/strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=6" } }, - "node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -5583,989 +3645,987 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "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==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/style-to-object": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.2.tgz", - "integrity": "sha512-1JGpfPB3lo42ZX8cuPrheZbfQ6kqPPnPHlKMyeRYtfKD+0jG+QsXgXN57O/dvJlzlB2elI6dGmrPnl5VPQFPaA==", + "node_modules/estree-util-attach-comments": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-3.0.0.tgz", + "integrity": "sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==", + "license": "MIT", "dependencies": { - "inline-style-parser": "0.1.1" + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "node_modules/estree-util-build-jsx": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-3.0.1.tgz", + "integrity": "sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==", + "license": "MIT", "dependencies": { - "has-flag": "^3.0.0" + "@types/estree-jsx": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "estree-walker": "^3.0.0" }, - "engines": { - "node": ">=4" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/supports-preserve-symlinks-flag": { + "node_modules/estree-util-scope": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" + "resolved": "https://registry.npmjs.org/estree-util-scope/-/estree-util-scope-1.0.0.tgz", + "integrity": "sha512-2CAASclonf+JFWBNJPndcOpA8EMJwa0Q8LUFJEKqXLW6+qBvbFZuF5gItbQOs/umBUkjviCSDCbBwU2cXbmrhQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "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==", + "node_modules/estree-util-to-js": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-2.0.0.tgz", + "integrity": "sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==", + "license": "MIT", "dependencies": { - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "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==", + "node_modules/estree-util-visit": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-2.0.0.tgz", + "integrity": "sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==", + "license": "MIT", "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "engines": { - "node": ">=4" + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "license": "Apache-2.0", "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" + "bare-events": "^2.7.0" } }, - "node_modules/trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "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==", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" } }, - "node_modules/trough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", - "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/expressive-code": { + "version": "0.35.6", + "resolved": "https://registry.npmjs.org/expressive-code/-/expressive-code-0.35.6.tgz", + "integrity": "sha512-+mx+TPTbMqgo0mL92Xh9QgjW0kSQIsEivMgEcOnaqKqL7qCw8Vkqc5Rg/di7ZYw4aMUSr74VTc+w8GQWu05j1g==", + "license": "MIT", + "dependencies": { + "@expressive-code/core": "^0.35.6", + "@expressive-code/plugin-frames": "^0.35.6", + "@expressive-code/plugin-shiki": "^0.35.6", + "@expressive-code/plugin-text-markers": "^0.35.6" } }, - "node_modules/tsconfig-resolver": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tsconfig-resolver/-/tsconfig-resolver-3.0.1.tgz", - "integrity": "sha512-ZHqlstlQF449v8glscGRXzL6l2dZvASPCdXJRWG4gHEZlUVx2Jtmr+a2zeVG4LCsKhDXKRj5R3h0C/98UcVAQg==", + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "license": "MIT", "dependencies": { - "@types/json5": "^0.0.30", - "@types/resolve": "^1.17.0", - "json5": "^2.1.3", - "resolve": "^1.17.0", - "strip-bom": "^4.0.0", - "type-fest": "^0.13.1" + "is-extendable": "^0.1.0" }, - "funding": { - "url": "https://github.com/sponsors/ifiokjr" + "engines": { + "node": ">=0.10.0" } }, - "node_modules/tsconfig-resolver/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "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==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, "engines": { - "node": ">=10" + "node": ">=8.6.0" + } + }, + "node_modules/fastq": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "engines": { + "node": ">=8" } }, - "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==", + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "license": "MIT", "dependencies": { - "safe-buffer": "^5.0.1" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "node_modules/find-up-simple": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.1.tgz", + "integrity": "sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==", + "license": "MIT", "engines": { - "node": ">=12.20" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, - "node_modules/undici": { - "version": "5.23.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.23.0.tgz", - "integrity": "sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg==", + "node_modules/find-yarn-workspace-root2": { + "version": "1.2.16", + "resolved": "https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz", + "integrity": "sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==", + "license": "Apache-2.0", "dependencies": { - "busboy": "^1.6.0" - }, - "engines": { - "node": ">=14.0" + "micromatch": "^4.0.2", + "pkg-dir": "^4.2.0" } }, - "node_modules/unherit": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-3.0.1.tgz", - "integrity": "sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" + "node_modules/flattie": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flattie/-/flattie-1.1.1.tgz", + "integrity": "sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==", + "license": "MIT", + "engines": { + "node": ">=8" } }, - "node_modules/unified": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", - "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", - "dependencies": { - "@types/unist": "^2.0.0", - "bail": "^2.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^5.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "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==", + "license": "MIT" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/unist-util-generated": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", - "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "node_modules/unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "dependencies": { - "@types/unist": "^2.0.0" + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", + "license": "MIT", + "engines": { + "node": ">=18" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/unist-util-modify-children": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-3.1.1.tgz", - "integrity": "sha512-yXi4Lm+TG5VG+qvokP6tpnk+r1EPwyYL04JWDxLvgvPV40jANh7nm3udk65OOWquvbMDe+PL9+LmkxDpTv/7BA==", - "dependencies": { - "@types/unist": "^2.0.0", - "array-iterate": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "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==", + "license": "MIT" }, - "node_modules/unist-util-position": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", - "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } + "node_modules/github-slugger": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==", + "license": "ISC" }, - "node_modules/unist-util-position-from-estree": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.2.tgz", - "integrity": "sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww==", + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", "dependencies": { - "@types/unist": "^2.0.0" + "is-glob": "^4.0.1" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">= 6" } }, - "node_modules/unist-util-remove": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-3.1.1.tgz", - "integrity": "sha512-kfCqZK5YVY5yEa89tvpl7KnBBHu2c6CzMkqHUrlOqaRgGOMp0sMvwWOVrbAtj03KhovQB7i96Gda72v/EFE0vw==", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" + }, + "node_modules/gray-matter": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", + "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", + "license": "MIT", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.0.0" + "js-yaml": "^3.13.1", + "kind-of": "^6.0.2", + "section-matter": "^1.0.0", + "strip-bom-string": "^1.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">=6.0" } }, - "node_modules/unist-util-remove-position": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz", - "integrity": "sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==", + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-visit": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "sprintf-js": "~1.0.2" } }, - "node_modules/unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "license": "MIT", "dependencies": { - "@types/unist": "^2.0.0" + "argparse": "^1.0.7", + "esprima": "^4.0.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "node_modules/hast-util-embedded": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-embedded/-/hast-util-embedded-3.0.0.tgz", + "integrity": "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==", + "license": "MIT", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" + "@types/hast": "^3.0.0", + "hast-util-is-element": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-visit-children": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-2.0.2.tgz", - "integrity": "sha512-+LWpMFqyUwLGpsQxpumsQ9o9DG2VGLFrpz+rpVXYIEdPy57GSy5HioC0g3bg/8WP9oCLlapQtklOzQ8uLS496Q==", + "node_modules/hast-util-format": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hast-util-format/-/hast-util-format-1.1.0.tgz", + "integrity": "sha512-yY1UDz6bC9rDvCWHpx12aIBGRG7krurX0p0Fm6pT547LwDIZZiNr8a+IHDogorAdreULSEzP82Nlv5SZkHZcjA==", + "license": "MIT", "dependencies": { - "@types/unist": "^2.0.0" + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-minify-whitespace": "^1.0.0", + "hast-util-phrasing": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "html-whitespace-sensitive-tag-names": "^3.0.0", + "unist-util-visit-parents": "^6.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "node_modules/hast-util-from-html": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.3.tgz", + "integrity": "sha512-CUSRHXyKjzHov8yKsQjGOElXy/3EKpyX56ELnkHH34vDVw1N1XSQ1ZcAvTyAPtGqLTuKP/uxM+aLkSPqF/EtMw==", + "license": "MIT", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/urlpattern-polyfill": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", - "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==" - }, - "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==" - }, - "node_modules/uvu": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", - "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", - "dependencies": { - "dequal": "^2.0.0", - "diff": "^5.0.0", - "kleur": "^4.0.3", - "sade": "^1.7.3" - }, - "bin": { - "uvu": "bin.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/vfile": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", - "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", - "dependencies": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-location": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", - "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", + "node_modules/hast-util-has-property": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-3.0.0.tgz", + "integrity": "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==", + "license": "MIT", "dependencies": { - "@types/unist": "^2.0.0", - "vfile": "^5.0.0" + "@types/hast": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/vfile-message": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", - "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", + "node_modules/hast-util-is-body-ok-link": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-is-body-ok-link/-/hast-util-is-body-ok-link-3.0.1.tgz", + "integrity": "sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==", + "license": "MIT", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" + "@types/hast": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/vite": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", - "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", - "dependencies": { - "esbuild": "^0.18.10", - "postcss": "^8.4.27", - "rollup": "^3.27.1" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - }, - "peerDependencies": { - "@types/node": ">= 14", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/vite/node_modules/@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" + "node_modules/hast-util-is-element": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-3.0.0.tgz", + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" + "node_modules/hast-util-minify-whitespace": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hast-util-minify-whitespace/-/hast-util-minify-whitespace-1.0.1.tgz", + "integrity": "sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "node_modules/hast-util-phrasing": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-phrasing/-/hast-util-phrasing-3.0.1.tgz", + "integrity": "sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-embedded": "^3.0.0", + "hast-util-has-property": "^3.0.0", + "hast-util-is-body-ok-link": "^3.0.0", + "hast-util-is-element": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "node_modules/hast-util-select": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-6.0.4.tgz", + "integrity": "sha512-RqGS1ZgI0MwxLaKLDxjprynNzINEkRHY2i8ln4DDjgv9ZhcYVIHN9rlpiYsqtFwrgpYU361SyWDQcGNIBVu3lw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "bcp-47-match": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "css-selector-parser": "^3.0.0", + "devlop": "^1.0.0", + "direction": "^2.0.0", + "hast-util-has-property": "^3.0.0", + "hast-util-to-string": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "nth-check": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "cpu": [ - "loong64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "node_modules/hast-util-to-estree": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-3.1.3.tgz", + "integrity": "sha512-48+B/rJWAp0jamNbAAf9M7Uf//UVqAoMmgXhBdxTDJLGKY+LRnZ99qcG+Qjl5HfMpYNzS5v4EAwVEF34LeAj7w==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-attach-comments": "^3.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "cpu": [ - "mips64el" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-9.0.5.tgz", + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "cpu": [ - "ppc64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "cpu": [ - "riscv64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "node_modules/hast-util-to-parse5": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.1.tgz", + "integrity": "sha512-MlWT6Pjt4CG9lFCjiz4BH7l9wmrMkfkJYCxFwKQic8+RTZgWPuWxwAfjJElsXkex7DJjfSJsQIt931ilUgmwdA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "node_modules/hast-util-to-string": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-3.0.1.tgz", + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" + "node_modules/hast-util-to-text": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-4.0.2.tgz", + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "hast-util-is-element": "^3.0.0", + "unist-util-find-after": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" + "node_modules/html-escaper": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", + "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==", + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/vite/node_modules/@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" + "node_modules/html-whitespace-sensitive-tag-names": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-whitespace-sensitive-tag-names/-/html-whitespace-sensitive-tag-names-3.0.1.tgz", + "integrity": "sha512-q+310vW8zmymYHALr1da4HyXUQ0zgiIwIicEfotYPWGN0OJVEN/58IJ3A4GBYcEq3LGAZqKb+ugvP0GNB9CEAA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/vite/node_modules/@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "license": "BSD-2-Clause" + }, + "node_modules/i18next": { + "version": "23.16.8", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.16.8.tgz", + "integrity": "sha512-06r/TitrM88Mg5FdUXAKL96dJMzgqLE5dv3ryBAra4KCwD9mJ4ndOTS95ZuymIGoE+2hzfdaMak2X11/es7ZWg==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } ], - "engines": { - "node": ">=12" + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.23.2" } }, - "node_modules/vite/node_modules/@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" + "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" + } ], - "engines": { - "node": ">=12" + "license": "BSD-3-Clause" + }, + "node_modules/import-meta-resolve": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz", + "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/vite/node_modules/esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/is-absolute-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-4.0.1.tgz", + "integrity": "sha512-/51/TKE88Lmm7Gc4/8btclNXWS+g50wXhYJq8HWIBAGUBnoAdRu1aXeh364t/O7wXDAcTJDP8PNuNKWUDWie+A==", + "license": "MIT", "engines": { - "node": ">=12" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, - "optionalDependencies": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/vitefu": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.4.tgz", - "integrity": "sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==", - "peerDependencies": { - "vite": "^3.0.0 || ^4.0.0" - }, - "peerDependenciesMeta": { - "vite": { - "optional": true - } + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/vscode-oniguruma": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", - "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==" + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "node_modules/vscode-textmate": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", - "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==" + "node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "license": "MIT" }, - "node_modules/web-namespaces": { + "node_modules/is-decimal": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "license": "MIT", "bin": { - "node-which": "bin/node-which" + "is-docker": "cli.js" }, "engines": { - "node": ">= 8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/which-pm": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-2.0.0.tgz", - "integrity": "sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==", - "dependencies": { - "load-yaml-file": "^0.2.0", - "path-exists": "^4.0.0" - }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "license": "MIT", "engines": { - "node": ">=8.15" + "node": ">=0.10.0" } }, - "node_modules/which-pm-runs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", - "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "dependencies": { - "string-width": "^5.0.1" - }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, - "node_modules/widest-line/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/widest-line/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" + "is-extglob": "^2.1.1" }, "engines": { - "node": ">=12" - }, + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "license": "MIT", "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" }, "engines": { - "node": ">=12" + "node": ">=14.16" }, "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", + "license": "MIT", "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/wrap-ansi/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } }, - "node_modules/wrap-ansi/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", "engines": { "node": ">=12" }, @@ -6573,4384 +4633,3954 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "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==" - }, - "node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "engines": { - "node": ">=12" - } - }, - "node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "license": "MIT", "engines": { - "node": ">=12.20" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/zod": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.1.tgz", - "integrity": "sha512-+dTu2m6gmCbO9Ahm4ZBDapx2O6ZY9QSPXst2WXjcznPMwf2YNpn3RevLx4KkZp1OPW/ouFcoBtBzFz/LeY69oA==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zwitch": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", - "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@astrojs/compiler": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.0.1.tgz", - "integrity": "sha512-DfBR7Cf+tOgQ4n7TIgTtU5x5SEA/08DNshpEPcT+91A0KbBlmUOYMBM/O6qAaHkmVo1KIoXQYhAmfdTT1zx9PQ==" - }, - "@astrojs/internal-helpers": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.2.0.tgz", - "integrity": "sha512-NQ4ppp1CM0HNkKbJNM4saVSfmUYzGlRalF6wx7F6T/MYHYSWGuojY89/oFTy4t8VlOGUCUijlsVNNeziWaUo5g==" - }, - "@astrojs/markdown-remark": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/markdown-remark/-/markdown-remark-3.0.0.tgz", - "integrity": "sha512-s8I49Je4++ImgYAgwL32HgN8m6we2qz3RtBpN4AjObMODPwDylmzUHZksD8Toy31q/P59ED3MuwphqOGm9l03w==", - "requires": { - "@astrojs/prism": "^3.0.0", - "github-slugger": "^2.0.0", - "import-meta-resolve": "^3.0.0", - "rehype-raw": "^6.1.1", - "rehype-stringify": "^9.0.4", - "remark-gfm": "^3.0.1", - "remark-parse": "^10.0.2", - "remark-rehype": "^10.1.0", - "remark-smartypants": "^2.0.0", - "shiki": "^0.14.3", - "unified": "^10.1.2", - "unist-util-visit": "^4.1.2", - "vfile": "^5.3.7" - } - }, - "@astrojs/mdx": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-1.0.0.tgz", - "integrity": "sha512-Gmeleci8o4X7dST9E85c1+k273zcKW8cSFgZLTwU5K4dC0qHfY/EaDKHWrtzOB2wjZlT1JDRzTJ68LJYGrF2OA==", - "requires": { - "@astrojs/markdown-remark": "3.0.0", - "@astrojs/prism": "3.0.0", - "@mdx-js/mdx": "^2.3.0", - "acorn": "^8.10.0", - "es-module-lexer": "^1.3.0", - "estree-util-visit": "^1.2.1", - "github-slugger": "^2.0.0", - "gray-matter": "^4.0.3", - "hast-util-to-html": "^8.0.4", - "kleur": "^4.1.4", - "rehype-raw": "^6.1.1", - "remark-frontmatter": "^4.0.1", - "remark-gfm": "^3.0.1", - "remark-smartypants": "^2.0.0", - "shiki": "^0.14.3", - "source-map": "^0.7.4", - "unist-util-visit": "^4.1.2", - "vfile": "^5.3.7" - } - }, - "@astrojs/netlify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/netlify/-/netlify-3.0.0.tgz", - "integrity": "sha512-v76HpoaEAK9uZHRJCCA8LV51e344ZhChfSMTlvNRvYa+ExJvPZCusBW3EaiyUFKpVozjs9AkIf3xmZ6cc+hFgQ==", - "requires": { - "@astrojs/underscore-redirects": "0.3.0", - "@netlify/functions": "^2.0.1", - "esbuild": "^0.19.2" + "url": "https://github.com/sponsors/sindresorhus" } }, - "@astrojs/prism": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-3.0.0.tgz", - "integrity": "sha512-g61lZupWq1bYbcBnYZqdjndShr/J3l/oFobBKPA3+qMat146zce3nz2kdO4giGbhYDt4gYdhmoBz0vZJ4sIurQ==", - "requires": { - "prismjs": "^1.29.0" - } + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" }, - "@astrojs/sitemap": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.0.0.tgz", - "integrity": "sha512-qm7npHuUW4q3OOmulqhJ1g69jEQu0Sdc6P8NbOzqIoosj/L+3v4i8dtKBnp6n1UQ4Sx8H8Vdi3Z/On7i9/ZJhw==", - "requires": { - "sitemap": "^7.1.1", - "zod": "3.21.1" - } - }, - "@astrojs/starlight": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@astrojs/starlight/-/starlight-0.9.0.tgz", - "integrity": "sha512-RK1QGfcU7bCxiOaGhVwJiA2NojswFq39v675IqS1/P97S0uHHQEtPHyiOd3vS2N/fAhwE78Vru9ykeB29BQlxw==", - "requires": { - "@astrojs/mdx": "^1.0.0", - "@astrojs/sitemap": "^3.0.0", - "@pagefind/default-ui": "^1.0.0-alpha.5", - "@types/mdast": "^3.0.11", - "bcp-47": "^2.1.0", - "execa": "^7.1.1", - "hast-util-select": "^5.0.5", - "hastscript": "^7.2.0", - "pagefind": "^1.0.0-alpha.5", - "rehype": "^12.0.1", - "remark-directive": "^2.0.1", - "unified": "^10.1.2", - "unist-util-remove": "^3.1.1", - "unist-util-visit": "^4.1.2", - "vfile": "^5.3.7" - } - }, - "@astrojs/telemetry": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.0.1.tgz", - "integrity": "sha512-7zJMuikRDQ0LLLivteu0+y4pqdgznrChFiRrY3qmKlOEkLWD1T3u1a5M970lvpErP7Vgh4P298JBPjv8LTj+sw==", - "requires": { - "ci-info": "^3.8.0", - "debug": "^4.3.4", - "dlv": "^1.1.3", - "dset": "^3.1.2", - "is-docker": "^3.0.0", - "is-wsl": "^3.0.0", - "undici": "^5.23.0", - "which-pm-runs": "^1.1.0" + "node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "@astrojs/underscore-redirects": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@astrojs/underscore-redirects/-/underscore-redirects-0.3.0.tgz", - "integrity": "sha512-dWBOH6hlGeaERmbdi+jFV2rnTcjOJrNOFYTnTTf8G2x0Gs3Radsh1ObSNEL5Z+xUhXNZLymhLbnN9yQSmh+PQw==" - }, - "@babel/code-frame": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.10.tgz", - "integrity": "sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==", - "requires": { - "@babel/highlight": "^7.22.10", - "chalk": "^2.4.2" - } - }, - "@babel/compat-data": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.9.tgz", - "integrity": "sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==" - }, - "@babel/core": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.10.tgz", - "integrity": "sha512-fTmqbbUBAwCcre6zPzNngvsI0aNrPZe77AeqvDxWM9Nm+04RrJ3CAmGHA9f7lJQY6ZMhRztNemy4uslDxTX4Qw==", - "requires": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-compilation-targets": "^7.22.10", - "@babel/helper-module-transforms": "^7.22.9", - "@babel/helpers": "^7.22.10", - "@babel/parser": "^7.22.10", - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.2", - "semver": "^6.3.1" + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } + "engines": { + "node": ">=6" } }, - "@babel/generator": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.10.tgz", - "integrity": "sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==", - "requires": { - "@babel/types": "^7.22.10", - "@jridgewell/gen-mapping": "^0.3.2", - "@jridgewell/trace-mapping": "^0.3.17", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz", - "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.10.tgz", - "integrity": "sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==", - "requires": { - "@babel/compat-data": "^7.22.9", - "@babel/helper-validator-option": "^7.22.5", - "browserslist": "^4.21.9", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "license": "MIT", + "bin": { + "json5": "lib/cli.js" }, - "dependencies": { - "semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" - } + "engines": { + "node": ">=6" } }, - "@babel/helper-environment-visitor": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz", - "integrity": "sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==" - }, - "@babel/helper-function-name": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz", - "integrity": "sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==", - "requires": { - "@babel/template": "^7.22.5", - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-hoist-variables": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", - "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-module-imports": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz", - "integrity": "sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-module-transforms": { - "version": "7.22.9", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz", - "integrity": "sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==", - "requires": { - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-simple-access": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/helper-validator-identifier": "^7.22.5" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz", - "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==" - }, - "@babel/helper-simple-access": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", - "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-split-export-declaration": { - "version": "7.22.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", - "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", - "requires": { - "@babel/types": "^7.22.5" - } - }, - "@babel/helper-string-parser": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", - "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==" - }, - "@babel/helper-validator-identifier": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz", - "integrity": "sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==" - }, - "@babel/helper-validator-option": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz", - "integrity": "sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==" - }, - "@babel/helpers": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.10.tgz", - "integrity": "sha512-a41J4NW8HyZa1I1vAndrraTlPZ/eZoga2ZgS7fEr0tZJGVU4xqdE80CEm0CcNjha5EZ8fTBYLKHF0kqDUuAwQw==", - "requires": { - "@babel/template": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10" - } - }, - "@babel/highlight": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.10.tgz", - "integrity": "sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==", - "requires": { - "@babel/helper-validator-identifier": "^7.22.5", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0" - } - }, - "@babel/parser": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.10.tgz", - "integrity": "sha512-lNbdGsQb9ekfsnjFGhEiF4hfFqGgfOP3H3d27re3n+CGhNuTSUEQdfWk556sTLNTloczcdM5TYF2LhzmDQKyvQ==" - }, - "@babel/plugin-syntax-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz", - "integrity": "sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==", - "requires": { - "@babel/helper-plugin-utils": "^7.22.5" - } - }, - "@babel/plugin-transform-react-jsx": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.5.tgz", - "integrity": "sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.22.5", - "@babel/helper-module-imports": "^7.22.5", - "@babel/helper-plugin-utils": "^7.22.5", - "@babel/plugin-syntax-jsx": "^7.22.5", - "@babel/types": "^7.22.5" - } - }, - "@babel/template": { - "version": "7.22.5", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.5.tgz", - "integrity": "sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==", - "requires": { - "@babel/code-frame": "^7.22.5", - "@babel/parser": "^7.22.5", - "@babel/types": "^7.22.5" - } - }, - "@babel/traverse": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.10.tgz", - "integrity": "sha512-Q/urqV4pRByiNNpb/f5OSv28ZlGJiFiiTh+GAHktbIrkPhPbl90+uW6SmpoLyZqutrg9AEaEf3Q/ZBRHBXgxig==", - "requires": { - "@babel/code-frame": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/helper-environment-visitor": "^7.22.5", - "@babel/helper-function-name": "^7.22.5", - "@babel/helper-hoist-variables": "^7.22.5", - "@babel/helper-split-export-declaration": "^7.22.6", - "@babel/parser": "^7.22.10", - "@babel/types": "^7.22.10", - "debug": "^4.1.0", - "globals": "^11.1.0" + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "@babel/types": { - "version": "7.22.10", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.22.10.tgz", - "integrity": "sha512-obaoigiLrlDZ7TUQln/8m4mSqIW2QFeOrCQc9r+xsaHGNoplVNYlRVpsfE8Vj35GEm2ZH4ZhrNYogs/3fj85kg==", - "requires": { - "@babel/helper-string-parser": "^7.22.5", - "@babel/helper-validator-identifier": "^7.22.5", - "to-fast-properties": "^2.0.0" + "node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "license": "MIT", + "engines": { + "node": ">=6" } }, - "@esbuild/android-arm": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.19.2.tgz", - "integrity": "sha512-tM8yLeYVe7pRyAu9VMi/Q7aunpLwD139EY1S99xbQkT4/q2qa6eA4ige/WJQYdJ8GBL1K33pPFhPfPdJ/WzT8Q==", - "optional": true - }, - "@esbuild/android-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.19.2.tgz", - "integrity": "sha512-lsB65vAbe90I/Qe10OjkmrdxSX4UJDjosDgb8sZUKcg3oefEuW2OT2Vozz8ef7wrJbMcmhvCC+hciF8jY/uAkw==", - "optional": true - }, - "@esbuild/android-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.19.2.tgz", - "integrity": "sha512-qK/TpmHt2M/Hg82WXHRc/W/2SGo/l1thtDHZWqFq7oi24AjZ4O/CpPSu6ZuYKFkEgmZlFoa7CooAyYmuvnaG8w==", - "optional": true - }, - "@esbuild/darwin-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.19.2.tgz", - "integrity": "sha512-Ora8JokrvrzEPEpZO18ZYXkH4asCdc1DLdcVy8TGf5eWtPO1Ie4WroEJzwI52ZGtpODy3+m0a2yEX9l+KUn0tA==", - "optional": true - }, - "@esbuild/darwin-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.19.2.tgz", - "integrity": "sha512-tP+B5UuIbbFMj2hQaUr6EALlHOIOmlLM2FK7jeFBobPy2ERdohI4Ka6ZFjZ1ZYsrHE/hZimGuU90jusRE0pwDw==", - "optional": true - }, - "@esbuild/freebsd-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.19.2.tgz", - "integrity": "sha512-YbPY2kc0acfzL1VPVK6EnAlig4f+l8xmq36OZkU0jzBVHcOTyQDhnKQaLzZudNJQyymd9OqQezeaBgkTGdTGeQ==", - "optional": true - }, - "@esbuild/freebsd-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.19.2.tgz", - "integrity": "sha512-nSO5uZT2clM6hosjWHAsS15hLrwCvIWx+b2e3lZ3MwbYSaXwvfO528OF+dLjas1g3bZonciivI8qKR/Hm7IWGw==", - "optional": true - }, - "@esbuild/linux-arm": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.19.2.tgz", - "integrity": "sha512-Odalh8hICg7SOD7XCj0YLpYCEc+6mkoq63UnExDCiRA2wXEmGlK5JVrW50vZR9Qz4qkvqnHcpH+OFEggO3PgTg==", - "optional": true - }, - "@esbuild/linux-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.19.2.tgz", - "integrity": "sha512-ig2P7GeG//zWlU0AggA3pV1h5gdix0MA3wgB+NsnBXViwiGgY77fuN9Wr5uoCrs2YzaYfogXgsWZbm+HGr09xg==", - "optional": true - }, - "@esbuild/linux-ia32": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.19.2.tgz", - "integrity": "sha512-mLfp0ziRPOLSTek0Gd9T5B8AtzKAkoZE70fneiiyPlSnUKKI4lp+mGEnQXcQEHLJAcIYDPSyBvsUbKUG2ri/XQ==", - "optional": true - }, - "@esbuild/linux-loong64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.19.2.tgz", - "integrity": "sha512-hn28+JNDTxxCpnYjdDYVMNTR3SKavyLlCHHkufHV91fkewpIyQchS1d8wSbmXhs1fiYDpNww8KTFlJ1dHsxeSw==", - "optional": true - }, - "@esbuild/linux-mips64el": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.19.2.tgz", - "integrity": "sha512-KbXaC0Sejt7vD2fEgPoIKb6nxkfYW9OmFUK9XQE4//PvGIxNIfPk1NmlHmMg6f25x57rpmEFrn1OotASYIAaTg==", - "optional": true - }, - "@esbuild/linux-ppc64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.19.2.tgz", - "integrity": "sha512-dJ0kE8KTqbiHtA3Fc/zn7lCd7pqVr4JcT0JqOnbj4LLzYnp+7h8Qi4yjfq42ZlHfhOCM42rBh0EwHYLL6LEzcw==", - "optional": true - }, - "@esbuild/linux-riscv64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.19.2.tgz", - "integrity": "sha512-7Z/jKNFufZ/bbu4INqqCN6DDlrmOTmdw6D0gH+6Y7auok2r02Ur661qPuXidPOJ+FSgbEeQnnAGgsVynfLuOEw==", - "optional": true - }, - "@esbuild/linux-s390x": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.19.2.tgz", - "integrity": "sha512-U+RinR6aXXABFCcAY4gSlv4CL1oOVvSSCdseQmGO66H+XyuQGZIUdhG56SZaDJQcLmrSfRmx5XZOWyCJPRqS7g==", - "optional": true - }, - "@esbuild/linux-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.19.2.tgz", - "integrity": "sha512-oxzHTEv6VPm3XXNaHPyUTTte+3wGv7qVQtqaZCrgstI16gCuhNOtBXLEBkBREP57YTd68P0VgDgG73jSD8bwXQ==", - "optional": true - }, - "@esbuild/netbsd-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.19.2.tgz", - "integrity": "sha512-WNa5zZk1XpTTwMDompZmvQLHszDDDN7lYjEHCUmAGB83Bgs20EMs7ICD+oKeT6xt4phV4NDdSi/8OfjPbSbZfQ==", - "optional": true - }, - "@esbuild/openbsd-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.19.2.tgz", - "integrity": "sha512-S6kI1aT3S++Dedb7vxIuUOb3oAxqxk2Rh5rOXOTYnzN8JzW1VzBd+IqPiSpgitu45042SYD3HCoEyhLKQcDFDw==", - "optional": true - }, - "@esbuild/sunos-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.19.2.tgz", - "integrity": "sha512-VXSSMsmb+Z8LbsQGcBMiM+fYObDNRm8p7tkUDMPG/g4fhFX5DEFmjxIEa3N8Zr96SjsJ1woAhF0DUnS3MF3ARw==", - "optional": true - }, - "@esbuild/win32-arm64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.19.2.tgz", - "integrity": "sha512-5NayUlSAyb5PQYFAU9x3bHdsqB88RC3aM9lKDAz4X1mo/EchMIT1Q+pSeBXNgkfNmRecLXA0O8xP+x8V+g/LKg==", - "optional": true - }, - "@esbuild/win32-ia32": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.19.2.tgz", - "integrity": "sha512-47gL/ek1v36iN0wL9L4Q2MFdujR0poLZMJwhO2/N3gA89jgHp4MR8DKCmwYtGNksbfJb9JoTtbkoe6sDhg2QTA==", - "optional": true - }, - "@esbuild/win32-x64": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.19.2.tgz", - "integrity": "sha512-tcuhV7ncXBqbt/Ybf0IyrMcwVOAPDckMK9rXNHtF17UTK18OKLpg08glminN06pt2WCoALhXdLfSPbVvK/6fxw==", - "optional": true - }, - "@jridgewell/gen-mapping": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", - "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "node_modules/linkify-it": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", + "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^1.0.1" } }, - "@jridgewell/resolve-uri": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", - "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==" - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==" - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz", - "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==", - "requires": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "node_modules/load-yaml-file": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz", + "integrity": "sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.5", + "js-yaml": "^3.13.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" } }, - "@mdx-js/mdx": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-2.3.0.tgz", - "integrity": "sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "@types/mdx": "^2.0.0", - "estree-util-build-jsx": "^2.0.0", - "estree-util-is-identifier-name": "^2.0.0", - "estree-util-to-js": "^1.1.0", - "estree-walker": "^3.0.0", - "hast-util-to-estree": "^2.0.0", - "markdown-extensions": "^1.0.0", - "periscopic": "^3.0.0", - "remark-mdx": "^2.0.0", - "remark-parse": "^10.0.0", - "remark-rehype": "^10.0.0", - "unified": "^10.0.0", - "unist-util-position-from-estree": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "unist-util-visit": "^4.0.0", - "vfile": "^5.0.0" - } - }, - "@netlify/functions": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@netlify/functions/-/functions-2.0.2.tgz", - "integrity": "sha512-goWRtaIPUK/q47qLYtfGGj7HgJIRaT0snw7zZ0yeoNTfQfCRwQwvRrMAsXkCsCtq2N2Oo81L26SpkMxEQMk9hg==", - "requires": { - "@netlify/serverless-functions-api": "1.7.3", - "is-promise": "^4.0.0" + "node_modules/load-yaml-file/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" } }, - "@netlify/node-cookies": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@netlify/node-cookies/-/node-cookies-0.1.0.tgz", - "integrity": "sha512-OAs1xG+FfLX0LoRASpqzVntVV/RpYkgpI0VrUnw2u0Q1qiZUzcPffxRK8HF3gc4GjuhG5ahOEMJ9bswBiZPq0g==" - }, - "@netlify/serverless-functions-api": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@netlify/serverless-functions-api/-/serverless-functions-api-1.7.3.tgz", - "integrity": "sha512-n6/7cJlSWvvbBlUOEAbkGyEld80S6KbG/ldQI9OhLfe1lTatgKmrTNIgqVNpaWpUdTgP2OHWFjmFBzkxxBWs5w==", - "requires": { - "@netlify/node-cookies": "^0.1.0", - "urlpattern-polyfill": "8.0.2" + "node_modules/load-yaml-file/node_modules/js-yaml": { + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" } }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" } }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" + "node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@pagefind/darwin-arm64": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-arm64/-/darwin-arm64-1.0.0-alpha.10.tgz", - "integrity": "sha512-npjow0ZhicK47KqPcS4qtlWft2kV0jClyEh0iuumdzJstt4PTacapuyxUAIm5NRR0GH2XoLyaH+TZzaaOmMuJw==", - "optional": true - }, - "@pagefind/darwin-x64": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/@pagefind/darwin-x64/-/darwin-x64-1.0.0-alpha.10.tgz", - "integrity": "sha512-WYik242Lz0Qv+eTD0brqkE6kndHMDoG7kD8WvdJPKzCSA3MHXVCYm9OyG8EWAWLYxSaDCI+Dx5+NZ1crcQ3Hbw==", - "optional": true - }, - "@pagefind/default-ui": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/@pagefind/default-ui/-/default-ui-1.0.0-alpha.10.tgz", - "integrity": "sha512-BHuRcd3ycJw2oEXxO8SARbWwLp7UP2f3Cv/PhvFh9opLvs0Cf+b/rqo8M7Rm3ldFTPxQuASvY4tt4leIX4DWDg==" - }, - "@pagefind/linux-arm64": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/@pagefind/linux-arm64/-/linux-arm64-1.0.0-alpha.10.tgz", - "integrity": "sha512-puc21zq/AsQAqAKKqaBsS7lWy16XYjNt2qssTIfhWXmzVQ1jl3wbUK5jm1rvjco5CQAq5cH+y0QdOwrFeuGo3w==", - "optional": true - }, - "@pagefind/linux-x64": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/@pagefind/linux-x64/-/linux-x64-1.0.0-alpha.10.tgz", - "integrity": "sha512-SfTd1ABl4otyEiu8rXqLY+tF78yUcfhNW7h4TsgJW8smIKgLJu0CO3YGBze+ddmHGU3dLDCJ5Z+AgHc//VUGfg==", - "optional": true - }, - "@pagefind/windows-x64": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/@pagefind/windows-x64/-/windows-x64-1.0.0-alpha.10.tgz", - "integrity": "sha512-GevBJZ+O0V/2VcNNaBrdWa1NFf6hg2mREhaj3o35WBYCOMSoZmofKuKdLI/w5X0v2AiMbM7CRhOlLwqqW4gKuQ==", - "optional": true - }, - "@types/acorn": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", - "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", - "requires": { - "@types/estree": "*" + "node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@types/babel__core": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.1.tgz", - "integrity": "sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==", - "requires": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "requires": { - "@babel/types": "^7.0.0" + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" } }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "@types/babel__traverse": { - "version": "7.20.1", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.1.tgz", - "integrity": "sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==", - "requires": { - "@babel/types": "^7.20.7" + "node_modules/magicast": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz", + "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.25.4", + "@babel/types": "^7.25.4", + "source-map-js": "^1.2.0" } }, - "@types/debug": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", - "integrity": "sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==", - "requires": { - "@types/ms": "*" + "node_modules/markdown-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-2.0.0.tgz", + "integrity": "sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==", + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==" - }, - "@types/estree-jsx": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.0.tgz", - "integrity": "sha512-3qvGd0z8F2ENTGr/GG1yViqfiKmRfrXVx5sJyHGFu3z7m5g5utCQtGp/g29JnjflhtQJBv1WDQukHiT58xPcYQ==", - "requires": { - "@types/estree": "*" + "node_modules/markdown-it": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", + "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "~3.0.1", + "linkify-it": "^4.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" } }, - "@types/hast": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@types/hast/-/hast-2.3.5.tgz", - "integrity": "sha512-SvQi0L/lNpThgPoleH53cdjB3y9zpLlVjRbqB3rH8hx1jiRSBGAhyjV3H+URFjNVRqt2EdYNrbZE5IsGlNfpRg==", - "requires": { - "@types/unist": "^2" + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "@types/json5": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.30.tgz", - "integrity": "sha512-sqm9g7mHlPY/43fcSNrCYfOeX9zkTTK+euO5E6+CVijSMm5tTjkVdwdqRkY3ljjIAf8679vps5jKUoJBCLsMDA==" - }, - "@types/mdast": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.12.tgz", - "integrity": "sha512-DT+iNIRNX884cx0/Q1ja7NyUPpZuv0KPyL5rGNxm1WC1OtHstl7n4Jb7nk+xacNShQMbczJjt8uFzznpp6kYBg==", - "requires": { - "@types/unist": "^2" + "node_modules/markdownlint": { + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.31.1.tgz", + "integrity": "sha512-CKMR2hgcIBrYlIUccDCOvi966PZ0kJExDrUi1R+oF9PvqQmCrTqjOsgIvf2403OmJ+CWomuzDoylr6KbuMyvHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "markdown-it": "13.0.1", + "markdownlint-micromark": "0.1.7" + }, + "engines": { + "node": ">=16" } }, - "@types/mdx": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.7.tgz", - "integrity": "sha512-BG4tyr+4amr3WsSEmHn/fXPqaCba/AYZ7dsaQTiavihQunHSIxk+uAtqsjvicNpyHN6cm+B9RVrUOtW9VzIKHw==" - }, - "@types/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" - }, - "@types/nlcst": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/nlcst/-/nlcst-1.0.1.tgz", - "integrity": "sha512-aVIyXt6pZiiMOtVByE4Y0gf+BLm1Cxc4ZLSK8VRHn1CgkO+kXbQwN/EBhQmhPdBMjFJCMBKtmNW2zWQuFywz8Q==", - "requires": { - "@types/unist": "^2" + "node_modules/markdownlint-micromark": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.7.tgz", + "integrity": "sha512-BbRPTC72fl5vlSKv37v/xIENSRDYL/7X/XoFzZ740FGEbs9vZerLrIkFRY0rv7slQKxDczToYuMmqQFN61fi4Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" } }, - "@types/node": { - "version": "17.0.45", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", - "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==" - }, - "@types/parse5": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", - "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" - }, - "@types/resolve": { - "version": "1.20.2", - "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz", - "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==" - }, - "@types/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-pSAff4IAxJjfAXUG6tFkO7dsSbTmf8CtUpfhhZ5VhkRpC4628tJhh3+V6H1E+/Gs9piSzYKT5yzHO5M4GG9jkw==", - "requires": { - "@types/node": "*" + "node_modules/mdast-util-definitions": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-6.0.0.tgz", + "integrity": "sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "@types/unist": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.7.tgz", - "integrity": "sha512-cputDpIbFgLUaGQn6Vqg3/YsJwxUwHLO13v3i5ouxT4lat0khip9AEWxtERujXV9wxIB1EyF97BSJFt6vpdI8g==" - }, - "acorn": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", - "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==" - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "requires": {} - }, - "ansi-align": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", - "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", - "requires": { - "string-width": "^4.1.0" - }, + "node_modules/mdast-util-directive": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-3.1.0.tgz", + "integrity": "sha512-I3fNFt+DHmpWCYAT7quoM6lHf9wuqtI+oCOfvILnoicNIqjh5E3dEJWiXuYME2gNe8vl1iMQwyUHa7bgFmak6Q==", + "license": "MIT", "dependencies": { - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - } + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==" - }, - "ansi-sequence-parser": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz", - "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==" - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" + "node_modules/mdast-util-from-markdown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz", + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "arg": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", - "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==" - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "array-iterate": { + "node_modules/mdast-util-gfm-autolink-literal": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-2.0.1.tgz", - "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==" - }, - "astring": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz", - "integrity": "sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==" - }, - "astro": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/astro/-/astro-3.0.7.tgz", - "integrity": "sha512-slUnDBXfxMzq5abE4svcKbaeYC/tHZsJYOrzwDNU9lLye3/4cqYP7OuHMTXiRlx7LSpHQlUhwbMe2HqCv2GKag==", - "requires": { - "@astrojs/compiler": "^2.0.1", - "@astrojs/internal-helpers": "0.2.0", - "@astrojs/markdown-remark": "3.0.0", - "@astrojs/telemetry": "3.0.1", - "@babel/core": "^7.22.10", - "@babel/generator": "^7.22.10", - "@babel/parser": "^7.22.10", - "@babel/plugin-transform-react-jsx": "^7.22.5", - "@babel/traverse": "^7.22.10", - "@babel/types": "^7.22.10", - "@types/babel__core": "^7.20.1", - "acorn": "^8.10.0", - "boxen": "^7.1.1", - "chokidar": "^3.5.3", - "ci-info": "^3.8.0", - "clsx": "^2.0.0", - "common-ancestor-path": "^1.0.1", - "cookie": "^0.5.0", - "debug": "^4.3.4", - "devalue": "^4.3.2", - "diff": "^5.1.0", - "es-module-lexer": "^1.3.0", - "esbuild": "^0.19.2", - "estree-walker": "^3.0.3", - "execa": "^8.0.1", - "fast-glob": "^3.3.1", - "github-slugger": "^2.0.0", - "gray-matter": "^4.0.3", - "html-escaper": "^3.0.3", - "http-cache-semantics": "^4.1.1", - "js-yaml": "^4.1.0", - "kleur": "^4.1.4", - "magic-string": "^0.30.3", - "mime": "^3.0.0", - "ora": "^7.0.1", - "p-limit": "^4.0.0", - "path-to-regexp": "^6.2.1", - "preferred-pm": "^3.0.3", - "prompts": "^2.4.2", - "rehype": "^12.0.1", - "resolve": "^1.22.4", - "semver": "^7.5.4", - "server-destroy": "^1.0.1", - "sharp": "^0.32.5", - "shiki": "^0.14.3", - "string-width": "^6.1.0", - "strip-ansi": "^7.1.0", - "tsconfig-resolver": "^3.0.1", - "undici": "^5.23.0", - "unist-util-visit": "^4.1.2", - "vfile": "^5.3.7", - "vite": "^4.4.9", - "vitefu": "^0.2.4", - "which-pm": "^2.0.0", - "yargs-parser": "^21.1.1", - "zod": "3.21.1" - }, - "dependencies": { - "execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" - } - }, - "get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==" - }, - "human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==" - }, - "signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" - } + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==" - }, - "bail": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", - "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==" - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "bcp-47": { + "node_modules/mdast-util-gfm-footnote": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/bcp-47/-/bcp-47-2.1.0.tgz", - "integrity": "sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==", - "requires": { - "is-alphabetical": "^2.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0" + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "bcp-47-match": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", - "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==" + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==" + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "bl": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz", - "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==", - "requires": { - "buffer": "^6.0.3", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==" + "node_modules/mdast-util-mdx": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-3.0.0.tgz", + "integrity": "sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "boxen": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.1.1.tgz", - "integrity": "sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==", - "requires": { - "ansi-align": "^3.0.1", - "camelcase": "^7.0.1", - "chalk": "^5.2.0", - "cli-boxes": "^3.0.0", - "string-width": "^5.1.2", - "type-fest": "^2.13.0", - "widest-line": "^4.0.1", - "wrap-ansi": "^8.1.0" + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", "dependencies": { - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==" - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - } + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "requires": { - "fill-range": "^7.0.1" + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "browserslist": { - "version": "4.21.10", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.10.tgz", - "integrity": "sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==", - "requires": { - "caniuse-lite": "^1.0.30001517", - "electron-to-chromium": "^1.4.477", - "node-releases": "^2.0.13", - "update-browserslist-db": "^1.0.11" + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "requires": { - "streamsearch": "^1.1.0" + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "camelcase": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", - "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==" - }, - "caniuse-lite": { - "version": "1.0.30001519", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001519.tgz", - "integrity": "sha512-0QHgqR+Jv4bxHMp8kZ1Kn8CH55OikjKJ6JmKkZYP1F3D7w+lnFXF70nG5eNfsZS89jadi5Ywy5UCSKLAglIRkg==" - }, - "ccount": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", - "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==" + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true, + "license": "MIT" }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" } }, - "character-entities": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", - "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==" - }, - "character-entities-html4": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", - "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==" - }, - "character-entities-legacy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", - "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==" - }, - "character-reference-invalid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", - "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==" - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - } - }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" - }, - "ci-info": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz", - "integrity": "sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==" - }, - "cli-boxes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", - "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==" - }, - "cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", - "requires": { - "restore-cursor": "^4.0.0" + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "cli-spinners": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.0.tgz", - "integrity": "sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==" - }, - "clsx": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.0.0.tgz", - "integrity": "sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==" - }, - "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" - } + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" }, - "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==" + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" + "node_modules/micromark-extension-directive": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "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" + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "comma-separated-tokens": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", - "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==" - }, - "common-ancestor-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", - "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==" - }, - "convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "css-selector-parser": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz", - "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==" - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "decode-named-character-reference": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", - "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", - "requires": { - "character-entities": "^2.0.0" + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "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" + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "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==" - }, - "dequal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", - "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" - }, - "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==" - }, - "devalue": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-4.3.2.tgz", - "integrity": "sha512-KqFl6pOgOW+Y6wJgu80rHpo2/3H07vr8ntR9rkkFIRETewbf5GaYYcakYfiKz89K+sLsuPkQIZaXDMjUObZwWg==" - }, - "diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==" - }, - "direction": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz", - "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==" - }, - "dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==" - }, - "dset": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/dset/-/dset-3.1.2.tgz", - "integrity": "sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q==" - }, - "eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "electron-to-chromium": { - "version": "1.4.490", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.490.tgz", - "integrity": "sha512-6s7NVJz+sATdYnIwhdshx/N/9O6rvMxmhVoDSDFdj6iA45gHR8EQje70+RYsF4GeB+k0IeNSBnP7yG9ZXJFr7A==" - }, - "emoji-regex": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.2.1.tgz", - "integrity": "sha512-97g6QgOk8zlDRdgq1WxwgTMgEWGVAQvB5Fdpgc1MkNy56la5SKP9GsMXKDOdqwn90/41a8yPwIGk1Y6WVbeMQA==" + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "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" + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "entities": { + "node_modules/micromark-extension-mdx-expression": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "dev": true - }, - "es-module-lexer": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.3.0.tgz", - "integrity": "sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==" - }, - "esbuild": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.19.2.tgz", - "integrity": "sha512-G6hPax8UbFakEj3hWO0Vs52LQ8k3lnBhxZWomUJDxfz3rZTLqF5k/FCzuNdLx2RbpBiQQF9H9onlDDH1lZsnjg==", - "requires": { - "@esbuild/android-arm": "0.19.2", - "@esbuild/android-arm64": "0.19.2", - "@esbuild/android-x64": "0.19.2", - "@esbuild/darwin-arm64": "0.19.2", - "@esbuild/darwin-x64": "0.19.2", - "@esbuild/freebsd-arm64": "0.19.2", - "@esbuild/freebsd-x64": "0.19.2", - "@esbuild/linux-arm": "0.19.2", - "@esbuild/linux-arm64": "0.19.2", - "@esbuild/linux-ia32": "0.19.2", - "@esbuild/linux-loong64": "0.19.2", - "@esbuild/linux-mips64el": "0.19.2", - "@esbuild/linux-ppc64": "0.19.2", - "@esbuild/linux-riscv64": "0.19.2", - "@esbuild/linux-s390x": "0.19.2", - "@esbuild/linux-x64": "0.19.2", - "@esbuild/netbsd-x64": "0.19.2", - "@esbuild/openbsd-x64": "0.19.2", - "@esbuild/sunos-x64": "0.19.2", - "@esbuild/win32-arm64": "0.19.2", - "@esbuild/win32-ia32": "0.19.2", - "@esbuild/win32-x64": "0.19.2" - } - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==" - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-3.0.1.tgz", + "integrity": "sha512-dD/ADLJ1AeMvSAKBwO22zG22N4ybhe7kFIZ3LsDI0GlsNr2A3KYxb0LdC1u5rj4Nw+CHKY0RVdnHX8vj8ejm4Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } }, - "estree-util-attach-comments": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-2.1.1.tgz", - "integrity": "sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w==", - "requires": { - "@types/estree": "^1.0.0" + "node_modules/micromark-extension-mdx-jsx": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-3.0.2.tgz", + "integrity": "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "micromark-factory-mdx-expression": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "estree-util-build-jsx": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-2.2.2.tgz", - "integrity": "sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "estree-util-is-identifier-name": "^2.0.0", - "estree-walker": "^3.0.0" + "node_modules/micromark-extension-mdx-md": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-2.0.0.tgz", + "integrity": "sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "estree-util-is-identifier-name": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.1.0.tgz", - "integrity": "sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ==" + "node_modules/micromark-extension-mdxjs": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-3.0.0.tgz", + "integrity": "sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==", + "license": "MIT", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^3.0.0", + "micromark-extension-mdx-jsx": "^3.0.0", + "micromark-extension-mdx-md": "^2.0.0", + "micromark-extension-mdxjs-esm": "^3.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "estree-util-to-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-1.2.0.tgz", - "integrity": "sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "astring": "^1.8.0", - "source-map": "^0.7.0" + "node_modules/micromark-extension-mdxjs-esm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-3.0.0.tgz", + "integrity": "sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "estree-util-visit": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-1.2.1.tgz", - "integrity": "sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "@types/unist": "^2.0.0" + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "estree-walker": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", - "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", - "requires": { - "@types/estree": "^1.0.0" + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "execa": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-7.2.0.tgz", - "integrity": "sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==", - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.1", - "human-signals": "^4.3.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", - "signal-exit": "^3.0.7", - "strip-final-newline": "^3.0.0" - } - }, - "expand-template": { + "node_modules/micromark-factory-mdx-expression": { "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==" + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-2.0.3.tgz", + "integrity": "sha512-kQnEtA3vzucU2BkrIa8/VaSAsP+EJ3CKOvhMuJgOEGg9KDC6OAY6nSnNDVRiVNRqj7Y4SlSzcStaH/5jge8JdQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-events-to-acorn": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-position-from-estree": "^2.0.0", + "vfile-message": "^4.0.0" + } }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } }, - "extend-shallow": { + "node_modules/micromark-factory-title": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "requires": { - "is-extendable": "^0.1.0" + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "fast-fifo": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.0.tgz", - "integrity": "sha512-IgfweLvEpwyA4WgiQe9Nx6VV2QkML2NkvZnk1oKnIzXgXdWxuhF7zw4DvLTPZJn6PIUneiAXPF24QmoEqHTjyw==" - }, - "fast-glob": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.1.tgz", - "integrity": "sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==", - "requires": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", - "requires": { - "reusify": "^1.0.4" + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "fault": { + "node_modules/micromark-util-chunked": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", - "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", - "requires": { - "format": "^0.2.0" + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" } }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "requires": { - "to-regex-range": "^5.0.1" + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "find-yarn-workspace-root2": { - "version": "1.2.16", - "resolved": "https://registry.npmjs.org/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz", - "integrity": "sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==", - "requires": { - "micromatch": "^4.0.2", - "pkg-dir": "^4.2.0" + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" } }, - "format": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", - "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==" - }, - "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==" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } }, - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" }, - "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/micromark-util-events-to-acorn": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-2.0.3.tgz", + "integrity": "sha512-jmsiEIiZ1n7X1Rr5k8wVExBQCg5jy4UXVADItHmNk1zkwEVhBuIUKRu3fqv+hs4nxLISi2DQGlqIOGiFxgbfHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "estree-util-visit": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "vfile-message": "^4.0.0" + } }, - "github-slugger": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", - "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==" + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" }, - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "requires": { - "is-glob": "^4.0.1" + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" } }, - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" - }, - "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "gray-matter": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/gray-matter/-/gray-matter-4.0.3.tgz", - "integrity": "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==", - "requires": { - "js-yaml": "^3.13.1", - "kind-of": "^6.0.2", - "section-matter": "^1.0.0", - "strip-bom-string": "^1.0.0" - }, - "dependencies": { - "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" - } + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" }, - "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" - } + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" } }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==" - }, - "hast-util-from-parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", - "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", - "requires": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "hastscript": "^7.0.0", - "property-information": "^6.0.0", - "vfile": "^5.0.0", - "vfile-location": "^4.0.0", - "web-namespaces": "^2.0.0" + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" } }, - "hast-util-has-property": { + "node_modules/micromark-util-symbol": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-2.0.1.tgz", - "integrity": "sha512-X2+RwZIMTMKpXUzlotatPzWj8bspCymtXH3cfG3iQKV+wPF53Vgaqxi/eLqGck0wKq1kS9nvoB1wchbCPEL8sg==" - }, - "hast-util-parse-selector": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", - "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", - "requires": { - "@types/hast": "^2.0.0" - } - }, - "hast-util-raw": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", - "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", - "requires": { - "@types/hast": "^2.0.0", - "@types/parse5": "^6.0.0", - "hast-util-from-parse5": "^7.0.0", - "hast-util-to-parse5": "^7.0.0", - "html-void-elements": "^2.0.0", - "parse5": "^6.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0", - "vfile": "^5.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" - } + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" }, - "hast-util-select": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-5.0.5.tgz", - "integrity": "sha512-QQhWMhgTFRhCaQdgTKzZ5g31GLQ9qRb1hZtDPMqQaOhpLBziWcshUS0uCR5IJ0U1jrK/mxg35fmcq+Dp/Cy2Aw==", - "requires": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "bcp-47-match": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "css-selector-parser": "^1.0.0", - "direction": "^2.0.0", - "hast-util-has-property": "^2.0.0", - "hast-util-to-string": "^2.0.0", - "hast-util-whitespace": "^2.0.0", - "not": "^0.1.0", - "nth-check": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "unist-util-visit": "^4.0.0", - "zwitch": "^2.0.0" - } + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" }, - "hast-util-to-estree": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-2.3.3.tgz", - "integrity": "sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ==", - "requires": { - "@types/estree": "^1.0.0", - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "estree-util-attach-comments": "^2.0.0", - "estree-util-is-identifier-name": "^2.0.0", - "hast-util-whitespace": "^2.0.0", - "mdast-util-mdx-expression": "^1.0.0", - "mdast-util-mdxjs-esm": "^1.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "style-to-object": "^0.4.1", - "unist-util-position": "^4.0.0", - "zwitch": "^2.0.0" + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" } }, - "hast-util-to-html": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/hast-util-to-html/-/hast-util-to-html-8.0.4.tgz", - "integrity": "sha512-4tpQTUOr9BMjtYyNlt0P50mH7xj0Ks2xpo8M943Vykljf99HW6EzulIoJP1N3eKOSScEHzyzi9dm7/cn0RfGwA==", - "requires": { - "@types/hast": "^2.0.0", - "@types/unist": "^2.0.0", - "ccount": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-raw": "^7.0.0", - "hast-util-whitespace": "^2.0.0", - "html-void-elements": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "stringify-entities": "^4.0.0", - "zwitch": "^2.0.4" + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "hast-util-to-parse5": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", - "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", - "requires": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0", - "web-namespaces": "^2.0.0", - "zwitch": "^2.0.0" + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "hast-util-to-string": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-2.0.0.tgz", - "integrity": "sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==", - "requires": { - "@types/hast": "^2.0.0" + "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==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "hast-util-whitespace": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", - "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==" - }, - "hastscript": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", - "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", - "requires": { - "@types/hast": "^2.0.0", - "comma-separated-tokens": "^2.0.0", - "hast-util-parse-selector": "^3.0.0", - "property-information": "^6.0.0", - "space-separated-tokens": "^2.0.0" + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "html-escaper": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-3.0.3.tgz", - "integrity": "sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==" - }, - "html-void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", - "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==" - }, - "http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, - "human-signals": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz", - "integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==" - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "import-meta-resolve": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-3.0.0.tgz", - "integrity": "sha512-4IwhLhNNA8yy445rPjD/lWh++7hMDOml2eHtd58eG7h+qK3EryMuuRbsHGPikCoAgIkkDnckKfWSk2iDla/ejg==" - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "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==" - }, - "inline-style-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz", - "integrity": "sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==" - }, - "is-alphabetical": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", - "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==" + "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==", + "license": "MIT" }, - "is-alphanumerical": { + "node_modules/mrmime": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", - "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", - "requires": { - "is-alphabetical": "^2.0.0", - "is-decimal": "^2.0.0" + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "license": "MIT", + "engines": { + "node": ">=10" } }, - "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/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "requires": { - "binary-extensions": "^2.0.0" + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==" + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "license": "MIT" }, - "is-core-module": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.0.tgz", - "integrity": "sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==", - "requires": { - "has": "^1.0.3" + "node_modules/neotraverse": { + "version": "0.6.18", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.18.tgz", + "integrity": "sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==", + "license": "MIT", + "engines": { + "node": ">= 10" } }, - "is-decimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", - "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==" - }, - "is-docker": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", - "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==" - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==" - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "requires": { - "is-extglob": "^2.1.1" + "node_modules/nlcst-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-4.0.0.tgz", + "integrity": "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "is-hexadecimal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", - "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==" - }, - "is-interactive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", - "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "node_modules/node-abi": { + "version": "3.87.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.87.0.tgz", + "integrity": "sha512-+CGM1L1CgmtheLcBuleyYOn7NWPVu0s0EJH2C4puxgEZb9h8QpR9G2dBfZJOAUhi7VQxuBPMd0hiISWcTyiYyQ==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } }, - "is-plain-obj": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", - "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" + "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==", + "license": "MIT" }, - "is-promise": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", - "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==" + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", + "license": "MIT" }, - "is-reference": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.1.tgz", - "integrity": "sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w==", - "requires": { - "@types/estree": "*" + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==" + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } }, - "is-unicode-supported": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", - "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==" + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "is-wsl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.0.0.tgz", - "integrity": "sha512-TQ7xXW/fTBaz/HhGSV779AC99ocpvb9qJPuPwyIea+F+Z+htcQ1wouAA0xEQaa4saVqyP8mwkoYp5efeM/4Gbg==", - "requires": { - "is-docker": "^3.0.0" + "node_modules/oniguruma-to-es": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-2.3.0.tgz", + "integrity": "sha512-bwALDxriqfKGfUufKGGepCzu9x7nJQuoRoAFp4AnwehhC2crqrDIAP/uN2qdlsAvSMpeRC3+Yzhqc7hLmle5+g==", + "license": "MIT", + "dependencies": { + "emoji-regex-xs": "^1.0.0", + "regex": "^5.1.1", + "regex-recursion": "^5.1.1" } }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "node_modules/ora": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", + "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^5.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.2", + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + "node_modules/p-limit": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-6.2.0.tgz", + "integrity": "sha512-kuUqqHNUqoIWp/c467RI4X6mmyuojY5jGutNU0wVTmEOOfcuwLqyMVoAi9MKi2Ak+5i9+nhmrK4ufZE8069kHA==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "js-yaml": { + "node_modules/p-locate": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "requires": { - "argparse": "^2.0.1" + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" } }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + "node_modules/p-locate/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + "node_modules/p-queue": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-8.1.1.tgz", + "integrity": "sha512-aNZ+VfjobsWryoiPnEApGGmf5WmNsCo9xu8dfaYamG5qaLP7ClhLN6NgsFe6SwJ2UbLEBK5dv9x8Mn5+RVhMWQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.1", + "p-timeout": "^6.1.2" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==" + "node_modules/p-timeout": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-6.1.4.tgz", + "integrity": "sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "linkify-it": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz", - "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==", - "dev": true, - "requires": { - "uc.micro": "^1.0.1" + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "license": "MIT", + "engines": { + "node": ">=6" } }, - "load-yaml-file": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/load-yaml-file/-/load-yaml-file-0.2.0.tgz", - "integrity": "sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==", - "requires": { - "graceful-fs": "^4.1.5", - "js-yaml": "^3.13.0", - "pify": "^4.0.1", - "strip-bom": "^3.0.0" + "node_modules/pagefind": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.4.0.tgz", + "integrity": "sha512-z2kY1mQlL4J8q5EIsQkLzQjilovKzfNVhX8De6oyE6uHpfFtyBaqUpcl/XzJC/4fjD8vBDyh1zolimIcVrCn9g==", + "license": "MIT", + "bin": { + "pagefind": "lib/runner/bin.cjs" }, - "dependencies": { - "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" - } - }, - "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" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==" - } + "optionalDependencies": { + "@pagefind/darwin-arm64": "1.4.0", + "@pagefind/darwin-x64": "1.4.0", + "@pagefind/freebsd-x64": "1.4.0", + "@pagefind/linux-arm64": "1.4.0", + "@pagefind/linux-x64": "1.4.0", + "@pagefind/windows-x64": "1.4.0" } }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "requires": { - "p-locate": "^5.0.0" + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "log-symbols": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz", - "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==", - "requires": { - "chalk": "^5.0.0", - "is-unicode-supported": "^1.1.0" - }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, + "node_modules/parse-latin": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-7.0.0.tgz", + "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", + "license": "MIT", "dependencies": { - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==" - } + "@types/nlcst": "^2.0.0", + "@types/unist": "^3.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-modify-children": "^4.0.0", + "unist-util-visit-children": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "longest-streak": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", - "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==" + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "magic-string": { - "version": "0.30.3", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.3.tgz", - "integrity": "sha512-B7xGbll2fG/VjP+SWg4sX3JynwIU0mjoTc6MPpKNuIvftk6u6vqhDnk1R80b8C2GBR6ywqy+1DcKBrevBg+bmw==", - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" } }, - "markdown-extensions": { + "node_modules/picocolors": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", - "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==" + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" }, - "markdown-it": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz", - "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==", - "dev": true, - "requires": { - "argparse": "^2.0.1", - "entities": "~3.0.1", - "linkify-it": "^4.0.1", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "markdown-table": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", - "integrity": "sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==" + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "markdownlint": { - "version": "0.31.1", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.31.1.tgz", - "integrity": "sha512-CKMR2hgcIBrYlIUccDCOvi966PZ0kJExDrUi1R+oF9PvqQmCrTqjOsgIvf2403OmJ+CWomuzDoylr6KbuMyvHA==", - "dev": true, - "requires": { - "markdown-it": "13.0.1", - "markdownlint-micromark": "0.1.7" + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "markdownlint-micromark": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/markdownlint-micromark/-/markdownlint-micromark-0.1.7.tgz", - "integrity": "sha512-BbRPTC72fl5vlSKv37v/xIENSRDYL/7X/XoFzZ740FGEbs9vZerLrIkFRY0rv7slQKxDczToYuMmqQFN61fi4Q==", - "dev": true + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } }, - "mdast-util-definitions": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", - "integrity": "sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==", - "requires": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "unist-util-visit": "^4.0.0" + "node_modules/postcss-nested": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.2.0.tgz", + "integrity": "sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "postcss-selector-parser": "^6.1.1" + }, + "engines": { + "node": ">=12.0" + }, + "peerDependencies": { + "postcss": "^8.2.14" } }, - "mdast-util-directive": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/mdast-util-directive/-/mdast-util-directive-2.2.4.tgz", - "integrity": "sha512-sK3ojFP+jpj1n7Zo5ZKvoxP1MvLyzVG63+gm40Z/qI00avzdPCYxt7RBMgofwAva9gBjbDBWVRB/i+UD+fUCzQ==", - "requires": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "mdast-util-from-markdown": "^1.3.0", - "mdast-util-to-markdown": "^1.5.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-visit-parents": "^5.1.3" + "node_modules/postcss-selector-parser": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", + "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" } }, - "mdast-util-find-and-replace": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz", - "integrity": "sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw==", - "requires": { - "@types/mdast": "^3.0.0", - "escape-string-regexp": "^5.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.0.0" - }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "license": "MIT", "dependencies": { - "escape-string-regexp": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", - "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==" - } + "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": "^2.0.0", + "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" } }, - "mdast-util-from-markdown": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", - "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", - "requires": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "mdast-util-to-string": "^3.1.0", - "micromark": "^3.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-decode-string": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-stringify-position": "^3.0.0", - "uvu": "^0.5.0" - } - }, - "mdast-util-frontmatter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-frontmatter/-/mdast-util-frontmatter-1.0.1.tgz", - "integrity": "sha512-JjA2OjxRqAa8wEG8hloD0uTU0kdn8kbtOWpPP94NBkfAlbxn4S8gCGf/9DwFtEeGPXrDcNXdiDjVaRdUFqYokw==", - "requires": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0", - "micromark-extension-frontmatter": "^1.0.0" + "node_modules/prebuild-install/node_modules/tar-fs": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" } }, - "mdast-util-gfm": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz", - "integrity": "sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg==", - "requires": { - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-gfm-autolink-literal": "^1.0.0", - "mdast-util-gfm-footnote": "^1.0.0", - "mdast-util-gfm-strikethrough": "^1.0.0", - "mdast-util-gfm-table": "^1.0.0", - "mdast-util-gfm-task-list-item": "^1.0.0", - "mdast-util-to-markdown": "^1.0.0" - } - }, - "mdast-util-gfm-autolink-literal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz", - "integrity": "sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA==", - "requires": { - "@types/mdast": "^3.0.0", - "ccount": "^2.0.0", - "mdast-util-find-and-replace": "^2.0.0", - "micromark-util-character": "^1.0.0" + "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==", + "license": "MIT", + "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" } }, - "mdast-util-gfm-footnote": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz", - "integrity": "sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ==", - "requires": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0", - "micromark-util-normalize-identifier": "^1.0.0" + "node_modules/preferred-pm": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/preferred-pm/-/preferred-pm-4.1.1.tgz", + "integrity": "sha512-rU+ZAv1Ur9jAUZtGPebQVQPzdGhNzaEiQ7VL9+cjsAWPHFYOccNXPNiev1CCDSOg/2j7UujM7ojNhpkuILEVNQ==", + "license": "MIT", + "dependencies": { + "find-up-simple": "^1.0.0", + "find-yarn-workspace-root2": "1.2.16", + "which-pm": "^3.0.1" + }, + "engines": { + "node": ">=18.12" } }, - "mdast-util-gfm-strikethrough": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz", - "integrity": "sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ==", - "requires": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0" - } - }, - "mdast-util-gfm-table": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz", - "integrity": "sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg==", - "requires": { - "@types/mdast": "^3.0.0", - "markdown-table": "^3.0.0", - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-to-markdown": "^1.3.0" + "node_modules/prettier": { + "version": "3.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.1.tgz", + "integrity": "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "mdast-util-gfm-task-list-item": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz", - "integrity": "sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ==", - "requires": { - "@types/mdast": "^3.0.0", - "mdast-util-to-markdown": "^1.3.0" + "node_modules/prismjs": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", + "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", + "license": "MIT", + "engines": { + "node": ">=6" } }, - "mdast-util-mdx": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-2.0.1.tgz", - "integrity": "sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw==", - "requires": { - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-mdx-expression": "^1.0.0", - "mdast-util-mdx-jsx": "^2.0.0", - "mdast-util-mdxjs-esm": "^1.0.0", - "mdast-util-to-markdown": "^1.0.0" + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" } }, - "mdast-util-mdx-expression": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.3.2.tgz", - "integrity": "sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-to-markdown": "^1.0.0" + "node_modules/prompts/node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "license": "MIT", + "engines": { + "node": ">=6" } }, - "mdast-util-mdx-jsx": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-2.1.4.tgz", - "integrity": "sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "ccount": "^2.0.0", - "mdast-util-from-markdown": "^1.1.0", - "mdast-util-to-markdown": "^1.3.0", - "parse-entities": "^4.0.0", - "stringify-entities": "^4.0.0", - "unist-util-remove-position": "^4.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "mdast-util-mdxjs-esm": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-1.3.1.tgz", - "integrity": "sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w==", - "requires": { - "@types/estree-jsx": "^1.0.0", - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-from-markdown": "^1.0.0", - "mdast-util-to-markdown": "^1.0.0" + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "mdast-util-phrasing": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz", - "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", - "requires": { - "@types/mdast": "^3.0.0", - "unist-util-is": "^5.0.0" - } - }, - "mdast-util-to-hast": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz", - "integrity": "sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==", - "requires": { - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-definitions": "^5.0.0", - "micromark-util-sanitize-uri": "^1.1.0", - "trim-lines": "^3.0.0", - "unist-util-generated": "^2.0.0", - "unist-util-position": "^4.0.0", - "unist-util-visit": "^4.0.0" + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" } }, - "mdast-util-to-markdown": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", - "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", - "requires": { - "@types/mdast": "^3.0.0", - "@types/unist": "^2.0.0", - "longest-streak": "^3.0.0", - "mdast-util-phrasing": "^3.0.0", - "mdast-util-to-string": "^3.0.0", - "micromark-util-decode-string": "^1.0.0", - "unist-util-visit": "^4.0.0", - "zwitch": "^2.0.0" + "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==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "mdast-util-to-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", - "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", - "requires": { - "@types/mdast": "^3.0.0" + "node_modules/recma-build-jsx": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-build-jsx/-/recma-build-jsx-1.0.0.tgz", + "integrity": "sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-build-jsx": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "mdurl": { + "node_modules/recma-jsx": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" - }, - "micromark": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", - "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", - "requires": { - "@types/debug": "^4.0.0", - "debug": "^4.0.0", - "decode-named-character-reference": "^1.0.0", - "micromark-core-commonmark": "^1.0.1", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "micromark-core-commonmark": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", - "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", - "requires": { - "decode-named-character-reference": "^1.0.0", - "micromark-factory-destination": "^1.0.0", - "micromark-factory-label": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-factory-title": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-html-tag-name": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-subtokenize": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.1", - "uvu": "^0.5.0" - } - }, - "micromark-extension-directive": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-2.2.1.tgz", - "integrity": "sha512-ZFKZkNaEqAP86IghX1X7sE8NNnx6kFNq9mSBRvEHjArutTCJZ3LYg6VH151lXVb1JHpmIcW/7rX25oMoIHuSug==", - "requires": { - "micromark-factory-space": "^1.0.0", - "micromark-factory-whitespace": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "parse-entities": "^4.0.0", - "uvu": "^0.5.0" + "resolved": "https://registry.npmjs.org/recma-jsx/-/recma-jsx-1.0.1.tgz", + "integrity": "sha512-huSIy7VU2Z5OLv6oFLosQGGDqPqdO1iq6bWNAdhzMxSJP7RAso4fCZ1cKu8j9YHCZf3TPrq4dw3okhrylgcd7w==", + "license": "MIT", + "dependencies": { + "acorn-jsx": "^5.0.0", + "estree-util-to-js": "^2.0.0", + "recma-parse": "^1.0.0", + "recma-stringify": "^1.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "micromark-extension-frontmatter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/micromark-extension-frontmatter/-/micromark-extension-frontmatter-1.1.1.tgz", - "integrity": "sha512-m2UH9a7n3W8VAH9JO9y01APpPKmNNNs71P0RbknEmYSaZU5Ghogv38BYO94AI5Xw6OYfxZRdHZZ2nYjs/Z+SZQ==", - "requires": { - "fault": "^2.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "node_modules/recma-parse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-parse/-/recma-parse-1.0.0.tgz", + "integrity": "sha512-OYLsIGBB5Y5wjnSnQW6t3Xg7q3fQ7FWbw/vcXtORTnyaSFscOtABg+7Pnz6YZ6c27fG1/aN8CjfwoUEUIdwqWQ==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "esast-util-from-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-extension-gfm": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz", - "integrity": "sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ==", - "requires": { - "micromark-extension-gfm-autolink-literal": "^1.0.0", - "micromark-extension-gfm-footnote": "^1.0.0", - "micromark-extension-gfm-strikethrough": "^1.0.0", - "micromark-extension-gfm-table": "^1.0.0", - "micromark-extension-gfm-tagfilter": "^1.0.0", - "micromark-extension-gfm-task-list-item": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-extension-gfm-autolink-literal": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz", - "integrity": "sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" - } - }, - "micromark-extension-gfm-footnote": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz", - "integrity": "sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q==", - "requires": { - "micromark-core-commonmark": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-normalize-identifier": "^1.0.0", - "micromark-util-sanitize-uri": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "micromark-extension-gfm-strikethrough": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz", - "integrity": "sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw==", - "requires": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-classify-character": "^1.0.0", - "micromark-util-resolve-all": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "micromark-extension-gfm-table": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz", - "integrity": "sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw==", - "requires": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "micromark-extension-gfm-tagfilter": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz", - "integrity": "sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g==", - "requires": { - "micromark-util-types": "^1.0.0" + "node_modules/recma-stringify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/recma-stringify/-/recma-stringify-1.0.0.tgz", + "integrity": "sha512-cjwII1MdIIVloKvC9ErQ+OgAtwHBmcZ0Bg4ciz78FtbT8In39aAYbaA7zvxQ61xVMSPE8WxhLwLbhif4Js2C+g==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-util-to-js": "^2.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-extension-gfm-task-list-item": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz", - "integrity": "sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ==", - "requires": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" + "node_modules/regex": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/regex/-/regex-5.1.1.tgz", + "integrity": "sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" } }, - "micromark-extension-mdx-expression": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.8.tgz", - "integrity": "sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==", - "requires": { - "@types/estree": "^1.0.0", - "micromark-factory-mdx-expression": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-events-to-acorn": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" + "node_modules/regex-recursion": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-5.1.1.tgz", + "integrity": "sha512-ae7SBCbzVNrIjgSbh7wMznPcQel1DNlDtzensnFxpiNpXt1U2ju/bHugH422r+4LAVS1FpW1YCwilmnNsjum9w==", + "license": "MIT", + "dependencies": { + "regex": "^5.1.1", + "regex-utilities": "^2.3.0" } }, - "micromark-extension-mdx-jsx": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-1.0.5.tgz", - "integrity": "sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA==", - "requires": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "estree-util-is-identifier-name": "^2.0.0", - "micromark-factory-mdx-expression": "^1.0.0", - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0", - "vfile-message": "^3.0.0" + "node_modules/regex-utilities": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/regex-utilities/-/regex-utilities-2.3.0.tgz", + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==", + "license": "MIT" + }, + "node_modules/rehype": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/rehype/-/rehype-13.0.2.tgz", + "integrity": "sha512-j31mdaRFrwFRUIlxGeuPXXKWQxet52RBQRvCmzl5eCefn/KGbomK5GMHNMsOJf55fgo3qw5tST5neDuarDYR2A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "rehype-parse": "^9.0.0", + "rehype-stringify": "^10.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-extension-mdx-md": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-1.0.1.tgz", - "integrity": "sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA==", - "requires": { - "micromark-util-types": "^1.0.0" + "node_modules/rehype-expressive-code": { + "version": "0.35.6", + "resolved": "https://registry.npmjs.org/rehype-expressive-code/-/rehype-expressive-code-0.35.6.tgz", + "integrity": "sha512-pPdE+pRcRw01kxMOwHQjuRxgwlblZt5+wAc3w2aPGgmcnn57wYjn07iKO7zaznDxYVxMYVvYlnL+R3vWFQS4Gw==", + "license": "MIT", + "dependencies": { + "expressive-code": "^0.35.6" } }, - "micromark-extension-mdxjs": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-1.0.1.tgz", - "integrity": "sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q==", - "requires": { - "acorn": "^8.0.0", - "acorn-jsx": "^5.0.0", - "micromark-extension-mdx-expression": "^1.0.0", - "micromark-extension-mdx-jsx": "^1.0.0", - "micromark-extension-mdx-md": "^1.0.0", - "micromark-extension-mdxjs-esm": "^1.0.0", - "micromark-util-combine-extensions": "^1.0.0", - "micromark-util-types": "^1.0.0" + "node_modules/rehype-format": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/rehype-format/-/rehype-format-5.0.1.tgz", + "integrity": "sha512-zvmVru9uB0josBVpr946OR8ui7nJEdzZobwLOOqHb/OOD88W0Vk2SqLwoVOj0fM6IPCCO6TaV9CvQvJMWwukFQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-format": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-extension-mdxjs-esm": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-1.0.5.tgz", - "integrity": "sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w==", - "requires": { - "@types/estree": "^1.0.0", - "micromark-core-commonmark": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-events-to-acorn": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-position-from-estree": "^1.1.0", - "uvu": "^0.5.0", - "vfile-message": "^3.0.0" + "node_modules/rehype-parse": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-9.0.1.tgz", + "integrity": "sha512-ksCzCD0Fgfh7trPDxr2rSylbwq9iYDkSn8TCDmEJ49ljEUBxDVCzCHv7QNzZOfODanX4+bWQ4WZqLCRWYLfhag==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-from-html": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-factory-destination": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", - "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-factory-label": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", - "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" - } - }, - "micromark-factory-mdx-expression": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.9.tgz", - "integrity": "sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==", - "requires": { + "node_modules/rehype-recma": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rehype-recma/-/rehype-recma-1.0.0.tgz", + "integrity": "sha512-lqA4rGUf1JmacCNWWZx0Wv1dHqMwxzsDWYMTowuplHF3xH0N/MmrZ/G3BDZnzAkRmxDadujCjaKM2hqYdCBOGw==", + "license": "MIT", + "dependencies": { "@types/estree": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-events-to-acorn": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "unist-util-position-from-estree": "^1.0.0", - "uvu": "^0.5.0", - "vfile-message": "^3.0.0" + "@types/hast": "^3.0.0", + "hast-util-to-estree": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-factory-space": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", - "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-types": "^1.0.0" + "node_modules/rehype-stringify": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.1.tgz", + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-to-html": "^9.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-factory-title": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", - "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", - "requires": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "node_modules/remark-directive": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-3.0.1.tgz", + "integrity": "sha512-gwglrEQEZcZYgVyG1tQuA+h58EZfq5CSULw7J90AFuCTyib1thgHPoqQ+h9iFvU6R+vnZ5oNFQR5QKgGpk741A==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-directive": "^3.0.0", + "micromark-extension-directive": "^3.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-factory-whitespace": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", - "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", - "requires": { - "micromark-factory-space": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-util-character": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", - "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", - "requires": { - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "node_modules/remark-mdx": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-3.1.1.tgz", + "integrity": "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg==", + "license": "MIT", + "dependencies": { + "mdast-util-mdx": "^3.0.0", + "micromark-extension-mdxjs": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-util-chunked": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", - "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", - "requires": { - "micromark-util-symbol": "^1.0.0" + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-util-classify-character": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", - "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0" + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-util-combine-extensions": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", - "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", - "requires": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-types": "^1.0.0" + "node_modules/remark-smartypants": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-3.0.2.tgz", + "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", + "license": "MIT", + "dependencies": { + "retext": "^9.0.0", + "retext-smartypants": "^6.0.0", + "unified": "^11.0.4", + "unist-util-visit": "^5.0.0" + }, + "engines": { + "node": ">=16.0.0" } }, - "micromark-util-decode-numeric-character-reference": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", - "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", - "requires": { - "micromark-util-symbol": "^1.0.0" + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-util-decode-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", - "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", - "requires": { - "decode-named-character-reference": "^1.0.0", - "micromark-util-character": "^1.0.0", - "micromark-util-decode-numeric-character-reference": "^1.0.0", - "micromark-util-symbol": "^1.0.0" + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "micromark-util-encode": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", - "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==" - }, - "micromark-util-events-to-acorn": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.3.tgz", - "integrity": "sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==", - "requires": { - "@types/acorn": "^4.0.0", - "@types/estree": "^1.0.0", - "@types/unist": "^2.0.0", - "estree-util-visit": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0", - "vfile-message": "^3.0.0" + "node_modules/retext": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/retext/-/retext-9.0.0.tgz", + "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "retext-latin": "^4.0.0", + "retext-stringify": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-util-html-tag-name": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", - "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==" - }, - "micromark-util-normalize-identifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", - "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", - "requires": { - "micromark-util-symbol": "^1.0.0" + "node_modules/retext-latin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-4.0.0.tgz", + "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "parse-latin": "^7.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-util-resolve-all": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", - "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", - "requires": { - "micromark-util-types": "^1.0.0" + "node_modules/retext-smartypants": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-6.2.0.tgz", + "integrity": "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-util-sanitize-uri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", - "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", - "requires": { - "micromark-util-character": "^1.0.0", - "micromark-util-encode": "^1.0.0", - "micromark-util-symbol": "^1.0.0" + "node_modules/retext-stringify": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-4.0.0.tgz", + "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", + "license": "MIT", + "dependencies": { + "@types/nlcst": "^2.0.0", + "nlcst-to-string": "^4.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "micromark-util-subtokenize": { + "node_modules/reusify": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", - "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", - "requires": { - "micromark-util-chunked": "^1.0.0", - "micromark-util-symbol": "^1.0.0", - "micromark-util-types": "^1.0.0", - "uvu": "^0.5.0" + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "micromark-util-symbol": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", - "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==" - }, - "micromark-util-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", - "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==" - }, - "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" + "node_modules/rollup": { + "version": "4.56.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.56.0.tgz", + "integrity": "sha512-9FwVqlgUHzbXtDg9RCMgodF3Ua4Na6Gau+Sdt9vyCN4RhHfVKX2DCHy3BjMLTDd47ITDhYAnTwGulWTblJSDLg==", + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.56.0", + "@rollup/rollup-android-arm64": "4.56.0", + "@rollup/rollup-darwin-arm64": "4.56.0", + "@rollup/rollup-darwin-x64": "4.56.0", + "@rollup/rollup-freebsd-arm64": "4.56.0", + "@rollup/rollup-freebsd-x64": "4.56.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.56.0", + "@rollup/rollup-linux-arm-musleabihf": "4.56.0", + "@rollup/rollup-linux-arm64-gnu": "4.56.0", + "@rollup/rollup-linux-arm64-musl": "4.56.0", + "@rollup/rollup-linux-loong64-gnu": "4.56.0", + "@rollup/rollup-linux-loong64-musl": "4.56.0", + "@rollup/rollup-linux-ppc64-gnu": "4.56.0", + "@rollup/rollup-linux-ppc64-musl": "4.56.0", + "@rollup/rollup-linux-riscv64-gnu": "4.56.0", + "@rollup/rollup-linux-riscv64-musl": "4.56.0", + "@rollup/rollup-linux-s390x-gnu": "4.56.0", + "@rollup/rollup-linux-x64-gnu": "4.56.0", + "@rollup/rollup-linux-x64-musl": "4.56.0", + "@rollup/rollup-openbsd-x64": "4.56.0", + "@rollup/rollup-openharmony-arm64": "4.56.0", + "@rollup/rollup-win32-arm64-msvc": "4.56.0", + "@rollup/rollup-win32-ia32-msvc": "4.56.0", + "@rollup/rollup-win32-x64-gnu": "4.56.0", + "@rollup/rollup-win32-x64-msvc": "4.56.0", + "fsevents": "~2.3.2" } }, - "mime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", - "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==" - }, - "mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==" - }, - "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==" - }, - "minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" - }, - "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==" - }, - "mri": { + "node_modules/run-parallel": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nanoid": { - "version": "3.3.6", - "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==" - }, - "nlcst-to-string": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-3.1.1.tgz", - "integrity": "sha512-63mVyqaqt0cmn2VcI2aH6kxe1rLAmSROqHMA0i4qqg1tidkfExgpb0FGMikMCn86mw5dFtBtEANfmSSK7TjNHw==", - "requires": { - "@types/nlcst": "^1.0.0" - } - }, - "node-abi": { - "version": "3.45.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.45.0.tgz", - "integrity": "sha512-iwXuFrMAcFVi/ZoZiqq8BzAdsLw9kxDfTC0HMyjXfSL/6CSDAGD5UmR7azrAgWV1zKYq7dUUMj4owusBWKLsiQ==", - "requires": { - "semver": "^7.3.5" + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" } }, - "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-releases": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", - "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==" - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" + "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" + } + ], + "license": "MIT" }, - "not": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz", - "integrity": "sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA==" + "node_modules/sax": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.4.tgz", + "integrity": "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } }, - "npm-run-path": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz", - "integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==", - "requires": { - "path-key": "^4.0.0" - }, + "node_modules/section-matter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", + "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", + "license": "MIT", "dependencies": { - "path-key": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", - "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==" - } + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" } }, - "nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", - "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", - "requires": { - "boolbase": "^1.0.0" + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { - "wrappy": "1" + "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, + "license": "Apache-2.0", + "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" } }, - "onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "requires": { - "mimic-fn": "^4.0.0" + "node_modules/shiki": { + "version": "1.29.2", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-1.29.2.tgz", + "integrity": "sha512-njXuliz/cP+67jU2hukkxCNuH1yUi4QfdZZY+sMr5PPrIyXSu5iTb/qYC4BiWWB0vZ+7TbdvYUCeL23zpwCfbg==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "1.29.2", + "@shikijs/engine-javascript": "1.29.2", + "@shikijs/engine-oniguruma": "1.29.2", + "@shikijs/langs": "1.29.2", + "@shikijs/themes": "1.29.2", + "@shikijs/types": "1.29.2", + "@shikijs/vscode-textmate": "^10.0.1", + "@types/hast": "^3.0.4" } }, - "ora": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-7.0.1.tgz", - "integrity": "sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==", - "requires": { - "chalk": "^5.3.0", - "cli-cursor": "^4.0.0", - "cli-spinners": "^2.9.0", - "is-interactive": "^2.0.0", - "is-unicode-supported": "^1.3.0", - "log-symbols": "^5.1.0", - "stdin-discarder": "^0.1.0", - "string-width": "^6.1.0", - "strip-ansi": "^7.1.0" + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" }, - "dependencies": { - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==" - } - } - }, - "p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "requires": { - "yocto-queue": "^1.0.0" + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "requires": { - "p-limit": "^3.0.2" - }, - "dependencies": { - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } + "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" }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" } - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" - }, - "pagefind": { - "version": "1.0.0-alpha.10", - "resolved": "https://registry.npmjs.org/pagefind/-/pagefind-1.0.0-alpha.10.tgz", - "integrity": "sha512-ewzRIDzU4HsAaca9rzOFaipMctEoA0XIFyNIDfy1mPM98HCEeTFcZ3Lp4+KcPHZLadsdjLbFLcBFBIAeWisbQw==", - "requires": { - "@pagefind/darwin-arm64": "1.0.0-alpha.10", - "@pagefind/darwin-x64": "1.0.0-alpha.10", - "@pagefind/linux-arm64": "1.0.0-alpha.10", - "@pagefind/linux-x64": "1.0.0-alpha.10", - "@pagefind/windows-x64": "1.0.0-alpha.10" - } + ], + "license": "MIT" }, - "parse-entities": { + "node_modules/simple-get": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz", - "integrity": "sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==", - "requires": { - "@types/unist": "^2.0.0", - "character-entities": "^2.0.0", - "character-entities-legacy": "^3.0.0", - "character-reference-invalid": "^2.0.0", - "decode-named-character-reference": "^1.0.0", - "is-alphanumerical": "^2.0.0", - "is-decimal": "^2.0.0", - "is-hexadecimal": "^2.0.0" + "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" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" } }, - "parse-latin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-5.0.1.tgz", - "integrity": "sha512-b/K8ExXaWC9t34kKeDV8kGXBkXZ1HCSAZRYE7HR14eA1GlXX5L8iWhs8USJNhQU9q5ci413jCKF0gOyovvyRBg==", - "requires": { - "nlcst-to-string": "^3.0.0", - "unist-util-modify-children": "^3.0.0", - "unist-util-visit-children": "^2.0.0" + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" } }, - "parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + "node_modules/sitemap": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-8.0.2.tgz", + "integrity": "sha512-LwktpJcyZDoa0IL6KT++lQ53pbSrx2c9ge41/SeLTyqy2XUNA6uR4+P9u5IVo5lPeL2arAcOKn1aZAxoYbCKlQ==", + "license": "MIT", + "dependencies": { + "@types/node": "^17.0.5", + "@types/sax": "^1.2.1", + "arg": "^5.0.0", + "sax": "^1.4.1" + }, + "bin": { + "sitemap": "dist/cli.js" + }, + "engines": { + "node": ">=14.0.0", + "npm": ">=6.0.0" + } }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" + "node_modules/sitemap/node_modules/@types/node": { + "version": "17.0.45", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz", + "integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==", + "license": "MIT" }, - "path-to-regexp": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz", - "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } }, - "periscopic": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", - "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", - "requires": { - "@types/estree": "^1.0.0", - "estree-walker": "^3.0.0", - "is-reference": "^3.0.0" + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" } }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "license": "BSD-3-Clause" }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + "node_modules/starlight": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/starlight/-/starlight-0.3.9.tgz", + "integrity": "sha512-pOZUSpeLrUi891CI6z6OD0vJrG9Ue0B8CSn4vIl/rKgFV9V9xPBDob1AIaE2baLxxkYtJx+djUOCiXnrekeegg==", + "license": "MIT" }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "requires": { - "find-up": "^4.0.0" - }, + "node_modules/starlight-blog": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/starlight-blog/-/starlight-blog-0.4.0.tgz", + "integrity": "sha512-3mVQ0hwH1XDews/EaG+rN1RA+7yqa7LTqBtTVfjiODC6IL1MRspKqe3MgEU4QFksh9/hEnk5jxC4GPAp2mUFPA==", + "license": "MIT", "dependencies": { - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "requires": { - "p-limit": "^2.2.0" - } - } + "github-slugger": "2.0.0" + }, + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "@astrojs/starlight": ">=0.11.0", + "astro": ">=3.2.0" } }, - "postcss": { - "version": "8.4.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.27.tgz", - "integrity": "sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ==", - "requires": { - "nanoid": "^3.3.6", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "node_modules/starlight-links-validator": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/starlight-links-validator/-/starlight-links-validator-0.12.4.tgz", + "integrity": "sha512-4MJ/BoTpdlKxfCL/pk931TGHYf7kNt812gRyNbhnIdwubjjzUy4J6J57TBY1yXcDVizWjHpGqHrqTeK0QhbemQ==", + "license": "MIT", + "dependencies": { + "@types/picomatch": "2.3.3", + "github-slugger": "2.0.0", + "hast-util-from-html": "2.0.1", + "hast-util-has-property": "3.0.0", + "is-absolute-url": "4.0.1", + "kleur": "4.1.5", + "mdast-util-to-string": "4.0.0", + "picomatch": "4.0.2", + "unist-util-visit": "5.0.0" + }, + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "@astrojs/starlight": ">=0.15.0", + "astro": ">=4.0.0" } }, - "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" - }, + "node_modules/starlight-links-validator/node_modules/hast-util-from-html": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-2.0.1.tgz", + "integrity": "sha512-RXQBLMl9kjKVNkJTIO6bZyb2n+cUH8LFaSSzo82jiLT6Tfc+Pt7VQCS+/h3YwG4jaNE2TA2sdJisGWR+aJrp0g==", + "license": "MIT", "dependencies": { - "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" - } - }, - "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" - } - }, - "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" - } - } + "@types/hast": "^3.0.0", + "devlop": "^1.1.0", + "hast-util-from-parse5": "^8.0.0", + "parse5": "^7.0.0", + "vfile": "^6.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "preferred-pm": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/preferred-pm/-/preferred-pm-3.0.3.tgz", - "integrity": "sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ==", - "requires": { - "find-up": "^5.0.0", - "find-yarn-workspace-root2": "1.2.16", - "path-exists": "^4.0.0", - "which-pm": "2.0.0" + "node_modules/starlight-links-validator/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "prettier": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz", - "integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==" - }, - "prismjs": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", - "integrity": "sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==" + "node_modules/starlight-links-validator/node_modules/unist-util-visit": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.0.0.tgz", + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "requires": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", + "license": "MIT", + "engines": { + "node": ">=18" }, - "dependencies": { - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==" - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "property-information": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz", - "integrity": "sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==" + "node_modules/stream-replace-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-replace-string/-/stream-replace-string-2.0.0.tgz", + "integrity": "sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==", + "license": "MIT" }, - "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" + "node_modules/streamx": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", + "license": "MIT", + "dependencies": { + "events-universal": "^1.0.0", + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" } }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" - }, - "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/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==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } }, - "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" + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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" + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "requires": { - "picomatch": "^2.2.1" - } - }, - "rehype": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/rehype/-/rehype-12.0.1.tgz", - "integrity": "sha512-ey6kAqwLM3X6QnMDILJthGvG1m1ULROS9NT4uG9IDCuv08SFyLlreSuvOa//DgEvbXx62DS6elGVqusWhRUbgw==", - "requires": { - "@types/hast": "^2.0.0", - "rehype-parse": "^8.0.0", - "rehype-stringify": "^9.0.0", - "unified": "^10.0.0" - } - }, - "rehype-parse": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/rehype-parse/-/rehype-parse-8.0.4.tgz", - "integrity": "sha512-MJJKONunHjoTh4kc3dsM1v3C9kGrrxvA3U8PxZlP2SjH8RNUSrb+lF7Y0KVaUDnGH2QZ5vAn7ulkiajM9ifuqg==", - "requires": { - "@types/hast": "^2.0.0", - "hast-util-from-parse5": "^7.0.0", - "parse5": "^6.0.0", - "unified": "^10.0.0" - } - }, - "rehype-raw": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz", - "integrity": "sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==", - "requires": { - "@types/hast": "^2.0.0", - "hast-util-raw": "^7.2.0", - "unified": "^10.0.0" - } - }, - "rehype-stringify": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-9.0.4.tgz", - "integrity": "sha512-Uk5xu1YKdqobe5XpSskwPvo1XeHUUucWEQSl8hTrXt5selvca1e8K1EZ37E6YoZ4BT8BCqCdVfQW7OfHfthtVQ==", - "requires": { - "@types/hast": "^2.0.0", - "hast-util-to-html": "^8.0.0", - "unified": "^10.0.0" - } - }, - "remark-directive": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/remark-directive/-/remark-directive-2.0.1.tgz", - "integrity": "sha512-oosbsUAkU/qmUE78anLaJePnPis4ihsE7Agp0T/oqTzvTea8pOiaYEtfInU/+xMOVTS9PN5AhGOiaIVe4GD8gw==", - "requires": { - "@types/mdast": "^3.0.0", - "mdast-util-directive": "^2.0.0", - "micromark-extension-directive": "^2.0.0", - "unified": "^10.0.0" + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "remark-frontmatter": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/remark-frontmatter/-/remark-frontmatter-4.0.1.tgz", - "integrity": "sha512-38fJrB0KnmD3E33a5jZC/5+gGAC2WKNiPw1/fdXJvijBlhA7RCsvJklrYJakS0HedninvaCYW8lQGf9C918GfA==", - "requires": { - "@types/mdast": "^3.0.0", - "mdast-util-frontmatter": "^1.0.0", - "micromark-extension-frontmatter": "^1.0.0", - "unified": "^10.0.0" + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "license": "MIT", + "engines": { + "node": ">=4" } }, - "remark-gfm": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz", - "integrity": "sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig==", - "requires": { - "@types/mdast": "^3.0.0", - "mdast-util-gfm": "^2.0.0", - "micromark-extension-gfm": "^2.0.0", - "unified": "^10.0.0" + "node_modules/strip-bom-string": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", + "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "remark-mdx": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-2.3.0.tgz", - "integrity": "sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g==", - "requires": { - "mdast-util-mdx": "^2.0.0", - "micromark-extension-mdxjs": "^1.0.0" + "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==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "remark-parse": { - "version": "10.0.2", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz", - "integrity": "sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==", - "requires": { - "@types/mdast": "^3.0.0", - "mdast-util-from-markdown": "^1.0.0", - "unified": "^10.0.0" - } - }, - "remark-rehype": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz", - "integrity": "sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==", - "requires": { - "@types/hast": "^2.0.0", - "@types/mdast": "^3.0.0", - "mdast-util-to-hast": "^12.1.0", - "unified": "^10.0.0" - } - }, - "remark-smartypants": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-smartypants/-/remark-smartypants-2.0.0.tgz", - "integrity": "sha512-Rc0VDmr/yhnMQIz8n2ACYXlfw/P/XZev884QU1I5u+5DgJls32o97Vc1RbK3pfumLsJomS2yy8eT4Fxj/2MDVA==", - "requires": { - "retext": "^8.1.0", - "retext-smartypants": "^5.1.0", - "unist-util-visit": "^4.1.0" + "node_modules/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" } }, - "resolve": { - "version": "1.22.4", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.4.tgz", - "integrity": "sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==", - "requires": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" } }, - "restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, + "node_modules/tar-fs": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", + "license": "MIT", "dependencies": { - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - } + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" } }, - "retext": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/retext/-/retext-8.1.0.tgz", - "integrity": "sha512-N9/Kq7YTn6ZpzfiGW45WfEGJqFf1IM1q8OsRa1CGzIebCJBNCANDRmOrholiDRGKo/We7ofKR4SEvcGAWEMD3Q==", - "requires": { - "@types/nlcst": "^1.0.0", - "retext-latin": "^3.0.0", - "retext-stringify": "^3.0.0", - "unified": "^10.0.0" + "node_modules/tar-stream": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", + "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" } }, - "retext-latin": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/retext-latin/-/retext-latin-3.1.0.tgz", - "integrity": "sha512-5MrD1tuebzO8ppsja5eEu+ZbBeUNCjoEarn70tkXOS7Bdsdf6tNahsv2bY0Z8VooFF6cw7/6S+d3yI/TMlMVVQ==", - "requires": { - "@types/nlcst": "^1.0.0", - "parse-latin": "^5.0.0", - "unherit": "^3.0.0", - "unified": "^10.0.0" - } - }, - "retext-smartypants": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/retext-smartypants/-/retext-smartypants-5.2.0.tgz", - "integrity": "sha512-Do8oM+SsjrbzT2UNIKgheP0hgUQTDDQYyZaIY3kfq0pdFzoPk+ZClYJ+OERNXveog4xf1pZL4PfRxNoVL7a/jw==", - "requires": { - "@types/nlcst": "^1.0.0", - "nlcst-to-string": "^3.0.0", - "unified": "^10.0.0", - "unist-util-visit": "^4.0.0" - } - }, - "retext-stringify": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/retext-stringify/-/retext-stringify-3.1.0.tgz", - "integrity": "sha512-767TLOaoXFXyOnjx/EggXlb37ZD2u4P1n0GJqVdpipqACsQP+20W+BNpMYrlJkq7hxffnFk+jc6mAK9qrbuB8w==", - "requires": { - "@types/nlcst": "^1.0.0", - "nlcst-to-string": "^3.0.0", - "unified": "^10.0.0" + "node_modules/text-decoder": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", + "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" } }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "rollup": { - "version": "3.28.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-3.28.0.tgz", - "integrity": "sha512-d7zhvo1OUY2SXSM6pfNjgD5+d0Nz87CUp4mt8l/GgVP3oBsPwzNvSzyu1me6BSG9JIgWNTVcafIXBIyM8yQ3yw==", - "requires": { - "fsevents": "~2.3.2" - } + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "license": "MIT" }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "requires": { - "queue-microtask": "^1.2.2" + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "sade": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", - "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", - "requires": { - "mri": "^1.1.0" + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "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==" - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "section-matter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/section-matter/-/section-matter-1.0.0.tgz", - "integrity": "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==", - "requires": { - "extend-shallow": "^2.0.1", - "kind-of": "^6.0.0" + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "requires": { - "lru-cache": "^6.0.0" + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" }, - "dependencies": { - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true } } }, - "server-destroy": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/server-destroy/-/server-destroy-1.0.1.tgz", - "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==" - }, - "sharp": { - "version": "0.32.5", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.32.5.tgz", - "integrity": "sha512-0dap3iysgDkNaPOaOL4X/0akdu0ma62GcdC2NBQ+93eqpePdDdr2/LM0sFdDSMmN7yS+odyZtPsb7tx/cYBKnQ==", - "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" + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD", + "optional": true + }, + "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==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" } }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" + "node_modules/type-fest": { + "version": "4.41.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.41.0.tgz", + "integrity": "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "shiki": { - "version": "0.14.3", - "resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.3.tgz", - "integrity": "sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==", - "requires": { - "ansi-sequence-parser": "^1.1.0", - "jsonc-parser": "^3.2.0", - "vscode-oniguruma": "^1.7.0", - "vscode-textmate": "^8.0.0" - }, - "dependencies": { - "jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" - } + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" } }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true, + "license": "MIT" }, - "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==" + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "license": "MIT" }, - "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" + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "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" + "node_modules/unist-util-find-after": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-5.0.0.tgz", + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==" - }, - "sitemap": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/sitemap/-/sitemap-7.1.1.tgz", - "integrity": "sha512-mK3aFtjz4VdJN0igpIJrinf3EO8U8mxOPsTBzSsy06UtjZQJ3YY3o3Xa7zSc5nMqcMrRwlChHZ18Kxg0caiPBg==", - "requires": { - "@types/node": "^17.0.5", - "@types/sax": "^1.2.1", - "arg": "^5.0.0", - "sax": "^1.2.4" + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==" - }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==" - }, - "space-separated-tokens": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", - "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==" + "node_modules/unist-util-modify-children": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-4.0.0.tgz", + "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "array-iterate": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "stdin-discarder": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz", - "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==", - "requires": { - "bl": "^5.0.0" + "node_modules/unist-util-position-from-estree": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-2.0.0.tgz", + "integrity": "sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" + "node_modules/unist-util-remove-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-5.0.0.tgz", + "integrity": "sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-visit": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "streamx": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz", - "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==", - "requires": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "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" + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "string-width": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz", - "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==", - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^10.2.1", - "strip-ansi": "^7.0.1" + "node_modules/unist-util-visit-children": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-3.0.0.tgz", + "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "stringify-entities": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz", - "integrity": "sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==", - "requires": { - "character-entities-html4": "^2.0.0", - "character-entities-legacy": "^3.0.0" + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "requires": { - "ansi-regex": "^6.0.1" + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==" - }, - "strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==" + "node_modules/urlpattern-polyfill": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", + "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==", + "license": "MIT" }, - "strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==" + "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==", + "license": "MIT" }, - "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==" + "node_modules/vanilla-cookieconsent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vanilla-cookieconsent/-/vanilla-cookieconsent-3.1.0.tgz", + "integrity": "sha512-/McNRtm/3IXzb9dhqMIcbquoU45SzbN2VB+To4jxEPqMmp7uVniP6BhGLjU8MC7ZCDsNQVOp27fhQTM/ruIXAA==", + "license": "MIT" }, - "style-to-object": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.2.tgz", - "integrity": "sha512-1JGpfPB3lo42ZX8cuPrheZbfQ6kqPPnPHlKMyeRYtfKD+0jG+QsXgXN57O/dvJlzlB2elI6dGmrPnl5VPQFPaA==", - "requires": { - "inline-style-parser": "0.1.1" + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==" - }, - "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" + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "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" + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } } }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==" - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "requires": { - "is-number": "^7.0.0" + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" } }, - "trim-lines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", - "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==" + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } }, - "trough": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz", - "integrity": "sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==" + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } }, - "tsconfig-resolver": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/tsconfig-resolver/-/tsconfig-resolver-3.0.1.tgz", - "integrity": "sha512-ZHqlstlQF449v8glscGRXzL6l2dZvASPCdXJRWG4gHEZlUVx2Jtmr+a2zeVG4LCsKhDXKRj5R3h0C/98UcVAQg==", - "requires": { - "@types/json5": "^0.0.30", - "@types/resolve": "^1.17.0", - "json5": "^2.1.3", - "resolve": "^1.17.0", - "strip-bom": "^4.0.0", - "type-fest": "^0.13.1" - }, - "dependencies": { - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==" - } + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" } }, - "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" + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" } }, - "type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==" + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } }, - "undici": { - "version": "5.23.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.23.0.tgz", - "integrity": "sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg==", - "requires": { - "busboy": "^1.6.0" + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" } }, - "unherit": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-3.0.1.tgz", - "integrity": "sha512-akOOQ/Yln8a2sgcLj4U0Jmx0R5jpIg2IUyRrWOzmEbjBtGzBdHtSeFKgoEcoH4KYIG/Pb8GQ/BwtYm0GCq1Sqg==" - }, - "unified": { - "version": "10.1.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", - "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", - "requires": { - "@types/unist": "^2.0.0", - "bail": "^2.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^4.0.0", - "trough": "^2.0.0", - "vfile": "^5.0.0" + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "unist-util-generated": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", - "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==" + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } }, - "unist-util-is": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", - "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", - "requires": { - "@types/unist": "^2.0.0" + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "unist-util-modify-children": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-3.1.1.tgz", - "integrity": "sha512-yXi4Lm+TG5VG+qvokP6tpnk+r1EPwyYL04JWDxLvgvPV40jANh7nm3udk65OOWquvbMDe+PL9+LmkxDpTv/7BA==", - "requires": { - "@types/unist": "^2.0.0", - "array-iterate": "^2.0.0" + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "unist-util-position": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", - "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", - "requires": { - "@types/unist": "^2.0.0" + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "unist-util-position-from-estree": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.2.tgz", - "integrity": "sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww==", - "requires": { - "@types/unist": "^2.0.0" + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "unist-util-remove": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-3.1.1.tgz", - "integrity": "sha512-kfCqZK5YVY5yEa89tvpl7KnBBHu2c6CzMkqHUrlOqaRgGOMp0sMvwWOVrbAtj03KhovQB7i96Gda72v/EFE0vw==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.0.0" + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "unist-util-remove-position": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz", - "integrity": "sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-visit": "^4.0.0" + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "unist-util-stringify-position": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", - "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", - "requires": { - "@types/unist": "^2.0.0" + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "unist-util-visit": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", - "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0", - "unist-util-visit-parents": "^5.1.1" + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" } }, - "unist-util-visit-children": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-2.0.2.tgz", - "integrity": "sha512-+LWpMFqyUwLGpsQxpumsQ9o9DG2VGLFrpz+rpVXYIEdPy57GSy5HioC0g3bg/8WP9oCLlapQtklOzQ8uLS496Q==", - "requires": { - "@types/unist": "^2.0.0" + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" } }, - "unist-util-visit-parents": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", - "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-is": "^5.0.0" + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" } }, - "update-browserslist-db": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz", - "integrity": "sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==", - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" } }, - "urlpattern-polyfill": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-8.0.2.tgz", - "integrity": "sha512-Qp95D4TPJl1kC9SKigDcqgyM2VDVO4RiJc2d4qe5GrYm+zbIQCWWKAFaJNQ4BhdFeDGwBmAxqJBwWSJDb9T3BQ==" - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "uvu": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", - "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", - "requires": { - "dequal": "^2.0.0", - "diff": "^5.0.0", - "kleur": "^4.0.3", - "sade": "^1.7.3" - } - }, - "vfile": { - "version": "5.3.7", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", - "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", - "requires": { - "@types/unist": "^2.0.0", - "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^3.0.0", - "vfile-message": "^3.0.0" + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" } }, - "vfile-location": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", - "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", - "requires": { - "@types/unist": "^2.0.0", - "vfile": "^5.0.0" + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" } }, - "vfile-message": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", - "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", - "requires": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, - "vite": { - "version": "4.4.9", - "resolved": "https://registry.npmjs.org/vite/-/vite-4.4.9.tgz", - "integrity": "sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==", - "requires": { - "esbuild": "^0.18.10", - "fsevents": "~2.3.2", - "postcss": "^8.4.27", - "rollup": "^3.27.1" + "node_modules/vitefu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.1.tgz", + "integrity": "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ==", + "license": "MIT", + "workspaces": [ + "tests/deps/*", + "tests/projects/*", + "tests/projects/workspace/packages/*" + ], + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, - "dependencies": { - "@esbuild/android-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.18.20.tgz", - "integrity": "sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==", - "optional": true - }, - "@esbuild/android-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.18.20.tgz", - "integrity": "sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==", - "optional": true - }, - "@esbuild/android-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.18.20.tgz", - "integrity": "sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==", - "optional": true - }, - "@esbuild/darwin-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.18.20.tgz", - "integrity": "sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==", - "optional": true - }, - "@esbuild/darwin-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.18.20.tgz", - "integrity": "sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==", - "optional": true - }, - "@esbuild/freebsd-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.20.tgz", - "integrity": "sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==", - "optional": true - }, - "@esbuild/freebsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.18.20.tgz", - "integrity": "sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==", - "optional": true - }, - "@esbuild/linux-arm": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.18.20.tgz", - "integrity": "sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==", - "optional": true - }, - "@esbuild/linux-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.18.20.tgz", - "integrity": "sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==", - "optional": true - }, - "@esbuild/linux-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.18.20.tgz", - "integrity": "sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==", - "optional": true - }, - "@esbuild/linux-loong64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.18.20.tgz", - "integrity": "sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==", - "optional": true - }, - "@esbuild/linux-mips64el": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.18.20.tgz", - "integrity": "sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==", - "optional": true - }, - "@esbuild/linux-ppc64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.18.20.tgz", - "integrity": "sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==", - "optional": true - }, - "@esbuild/linux-riscv64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.18.20.tgz", - "integrity": "sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==", - "optional": true - }, - "@esbuild/linux-s390x": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.18.20.tgz", - "integrity": "sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==", - "optional": true - }, - "@esbuild/linux-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.18.20.tgz", - "integrity": "sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==", - "optional": true - }, - "@esbuild/netbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.18.20.tgz", - "integrity": "sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==", - "optional": true - }, - "@esbuild/openbsd-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.18.20.tgz", - "integrity": "sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==", - "optional": true - }, - "@esbuild/sunos-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.18.20.tgz", - "integrity": "sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==", - "optional": true - }, - "@esbuild/win32-arm64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.18.20.tgz", - "integrity": "sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==", - "optional": true - }, - "@esbuild/win32-ia32": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.18.20.tgz", - "integrity": "sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==", - "optional": true - }, - "@esbuild/win32-x64": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.18.20.tgz", - "integrity": "sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==", + "peerDependenciesMeta": { + "vite": { "optional": true - }, - "esbuild": { - "version": "0.18.20", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", - "integrity": "sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==", - "requires": { - "@esbuild/android-arm": "0.18.20", - "@esbuild/android-arm64": "0.18.20", - "@esbuild/android-x64": "0.18.20", - "@esbuild/darwin-arm64": "0.18.20", - "@esbuild/darwin-x64": "0.18.20", - "@esbuild/freebsd-arm64": "0.18.20", - "@esbuild/freebsd-x64": "0.18.20", - "@esbuild/linux-arm": "0.18.20", - "@esbuild/linux-arm64": "0.18.20", - "@esbuild/linux-ia32": "0.18.20", - "@esbuild/linux-loong64": "0.18.20", - "@esbuild/linux-mips64el": "0.18.20", - "@esbuild/linux-ppc64": "0.18.20", - "@esbuild/linux-riscv64": "0.18.20", - "@esbuild/linux-s390x": "0.18.20", - "@esbuild/linux-x64": "0.18.20", - "@esbuild/netbsd-x64": "0.18.20", - "@esbuild/openbsd-x64": "0.18.20", - "@esbuild/sunos-x64": "0.18.20", - "@esbuild/win32-arm64": "0.18.20", - "@esbuild/win32-ia32": "0.18.20", - "@esbuild/win32-x64": "0.18.20" - } } } }, - "vitefu": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-0.2.4.tgz", - "integrity": "sha512-fanAXjSaf9xXtOOeno8wZXIhgia+CZury481LsDaV++lSvcU2R9Ch2bPh3PYFyoHW+w9LqAeYRISVQjUIew14g==", - "requires": {} - }, - "vscode-oniguruma": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz", - "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==" - }, - "vscode-textmate": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz", - "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==" - }, - "web-namespaces": { + "node_modules/web-namespaces": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", - "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==" - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "which-pm": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-2.0.0.tgz", - "integrity": "sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w==", - "requires": { - "load-yaml-file": "^0.2.0", - "path-exists": "^4.0.0" + "node_modules/which-pm": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/which-pm/-/which-pm-3.0.1.tgz", + "integrity": "sha512-v2JrMq0waAI4ju1xU5x3blsxBBMgdgZve580iYMN5frDaLGjbA24fok7wKCsya8KLVO19Ju4XDc5+zTZCJkQfg==", + "license": "MIT", + "dependencies": { + "load-yaml-file": "^0.2.0" + }, + "engines": { + "node": ">=18.12" } }, - "which-pm-runs": { + "node_modules/which-pm-runs": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.1.0.tgz", - "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==" + "integrity": "sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==", + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "widest-line": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", - "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", - "requires": { - "string-width": "^5.0.1" - }, + "node_modules/widest-line": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", + "integrity": "sha512-c9bZp7b5YtRj2wOe6dlj32MK+Bx/M/d+9VB2SHM1OtsUHR0aV0tdP6DWh/iMt0kWi1t5g1Iudu6hQRNd1A4PVA==", + "license": "MIT", "dependencies": { - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - } + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "requires": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, + "node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "license": "MIT", "dependencies": { - "ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } - } + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "wrappy": { + "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==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + }, + "node_modules/xxhash-wasm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.1.0.tgz", + "integrity": "sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==", + "license": "MIT" }, - "yallist": { + "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "license": "ISC" }, - "yargs-parser": { + "node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } }, - "yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==" + "node_modules/yocto-queue": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", + "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==", + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } }, - "zod": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.1.tgz", - "integrity": "sha512-+dTu2m6gmCbO9Ahm4ZBDapx2O6ZY9QSPXst2WXjcznPMwf2YNpn3RevLx4KkZp1OPW/ouFcoBtBzFz/LeY69oA==" + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, + "node_modules/zod-to-ts": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/zod-to-ts/-/zod-to-ts-1.2.0.tgz", + "integrity": "sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==", + "peerDependencies": { + "typescript": "^4.9.4 || ^5.0.2", + "zod": "^3" + } }, - "zwitch": { + "node_modules/zwitch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", - "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==" + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/package.json b/package.json index a4f70745..373d71b8 100644 --- a/package.json +++ b/package.json @@ -3,24 +3,29 @@ "type": "module", "version": "0.0.1", "scripts": { - "dev": "astro dev", - "start": "astro dev", + "dev": "astro dev --port 4321", + "start": "astro dev --port 4321", "build": "astro build", "preview": "astro preview", "astro": "astro", - "format": "prettier --write \"**/*.md\"", - "format:check": "prettier --check \"**/*.md\"", - "prose:check": "vale --minAlertLevel error --output=.vale/vale.tmpl docs", + "format": "prettier --write \"**/*.md\" && prettier --write \"**/*.mdx\"", + "format:check": "prettier --check \"**/*.md\" && prettier --check \"**/*.mdx\"", + "prose:check": "vale src/content/docs --minAlertLevel error", "lint": "npm run format:check && npm run prose:check" }, "dependencies": { "@astrojs/netlify": "^3.0.0", - "@astrojs/starlight": "^0.9.0", - "astro": "^3.0.7", - "prettier": "^3.1.0", - "sharp": "^0.32.3" + "@astrojs/partytown": "^2.1.2", + "@astrojs/starlight": "^0.28.6", + "astro": "^4.16.18", + "sharp": "^0.32.3", + "starlight": "^0.3.9", + "starlight-blog": "^0.4.0", + "starlight-links-validator": "^0.12.3", + "vanilla-cookieconsent": "^3.0.1" }, "devDependencies": { - "markdownlint": "^0.31.0" + "markdownlint": "^0.31.1", + "prettier": "^3.2.5" } } diff --git a/public/Architecture Diagram.png b/public/Architecture Diagram.png new file mode 100644 index 00000000..8b67497d Binary files /dev/null and b/public/Architecture Diagram.png differ diff --git a/public/Aspose.Words.c1eaed0e-7d01-4b23-bd08-e2a37f23ccf6.001.png b/public/Aspose.Words.c1eaed0e-7d01-4b23-bd08-e2a37f23ccf6.001.png new file mode 100644 index 00000000..c5c8b33a Binary files /dev/null and b/public/Aspose.Words.c1eaed0e-7d01-4b23-bd08-e2a37f23ccf6.001.png differ diff --git a/public/Aspose.Words.c1eaed0e-7d01-4b23-bd08-e2a37f23ccf6.002.png b/public/Aspose.Words.c1eaed0e-7d01-4b23-bd08-e2a37f23ccf6.002.png new file mode 100644 index 00000000..79b07cc6 Binary files /dev/null and b/public/Aspose.Words.c1eaed0e-7d01-4b23-bd08-e2a37f23ccf6.002.png differ diff --git a/public/Aspose.Words.c1eaed0e-7d01-4b23-bd08-e2a37f23ccf6.003.jpeg b/public/Aspose.Words.c1eaed0e-7d01-4b23-bd08-e2a37f23ccf6.003.jpeg new file mode 100644 index 00000000..68373944 Binary files /dev/null and b/public/Aspose.Words.c1eaed0e-7d01-4b23-bd08-e2a37f23ccf6.003.jpeg differ diff --git a/public/Aspose.Words.c1eaed0e-7d01-4b23-bd08-e2a37f23ccf6.004.jpeg b/public/Aspose.Words.c1eaed0e-7d01-4b23-bd08-e2a37f23ccf6.004.jpeg new file mode 100644 index 00000000..de86c1d5 Binary files /dev/null and b/public/Aspose.Words.c1eaed0e-7d01-4b23-bd08-e2a37f23ccf6.004.jpeg differ diff --git a/public/CourseFlow ERD.png b/public/CourseFlow ERD.png new file mode 100644 index 00000000..2cf9b6c8 Binary files /dev/null and b/public/CourseFlow ERD.png differ diff --git a/public/CourseFlow-AnalyticPage-Figma.PNG b/public/CourseFlow-AnalyticPage-Figma.PNG new file mode 100644 index 00000000..26815345 Binary files /dev/null and b/public/CourseFlow-AnalyticPage-Figma.PNG differ diff --git a/public/CourseFlow-DFD-0.png b/public/CourseFlow-DFD-0.png new file mode 100644 index 00000000..7a9596c9 Binary files /dev/null and b/public/CourseFlow-DFD-0.png differ diff --git a/public/CourseFlow-DFD-1.png b/public/CourseFlow-DFD-1.png new file mode 100644 index 00000000..c5bb3056 Binary files /dev/null and b/public/CourseFlow-DFD-1.png differ diff --git a/public/CourseFlow-PopUpUI-Figma.PNG b/public/CourseFlow-PopUpUI-Figma.PNG new file mode 100644 index 00000000..65d5ec90 Binary files /dev/null and b/public/CourseFlow-PopUpUI-Figma.PNG differ diff --git a/public/CourseFlow-SAD.png b/public/CourseFlow-SAD.png new file mode 100644 index 00000000..6a8a0c1e Binary files /dev/null and b/public/CourseFlow-SAD.png differ diff --git a/public/CourseFlow_Analytics_Page.png b/public/CourseFlow_Analytics_Page.png new file mode 100644 index 00000000..23ce1174 Binary files /dev/null and b/public/CourseFlow_Analytics_Page.png differ diff --git a/public/CourseFlow_SideBar.png b/public/CourseFlow_SideBar.png new file mode 100644 index 00000000..d5b1877a Binary files /dev/null and b/public/CourseFlow_SideBar.png differ diff --git a/public/CourseFlow_Timetable_View.png b/public/CourseFlow_Timetable_View.png new file mode 100644 index 00000000..03c6b363 Binary files /dev/null and b/public/CourseFlow_Timetable_View.png differ diff --git a/public/DataFlow.jpg b/public/DataFlow.jpg new file mode 100644 index 00000000..5003621d Binary files /dev/null and b/public/DataFlow.jpg differ diff --git a/public/Dependency_Injection.png b/public/Dependency_Injection.png new file mode 100644 index 00000000..3e7e6265 Binary files /dev/null and b/public/Dependency_Injection.png differ diff --git a/public/Flow Diagram.png b/public/Flow Diagram.png new file mode 100644 index 00000000..0cc1841d Binary files /dev/null and b/public/Flow Diagram.png differ diff --git a/public/GoogleCloud_CICD.jpg b/public/GoogleCloud_CICD.jpg new file mode 100644 index 00000000..b8d2cb24 Binary files /dev/null and b/public/GoogleCloud_CICD.jpg differ diff --git a/public/GoogleCloud_Doubtfire.jpg b/public/GoogleCloud_Doubtfire.jpg new file mode 100644 index 00000000..b0bd8f26 Binary files /dev/null and b/public/GoogleCloud_Doubtfire.jpg differ diff --git a/public/Import_TS_component.png b/public/Import_TS_component.png new file mode 100644 index 00000000..2a16f676 Binary files /dev/null and b/public/Import_TS_component.png differ diff --git a/public/InitialDesign1.png b/public/InitialDesign1.png new file mode 100644 index 00000000..9b4e6201 Binary files /dev/null and b/public/InitialDesign1.png differ diff --git a/public/InitialDesign2.png b/public/InitialDesign2.png new file mode 100644 index 00000000..6b592555 Binary files /dev/null and b/public/InitialDesign2.png differ diff --git a/public/InitialDesign3.png b/public/InitialDesign3.png new file mode 100644 index 00000000..8121aeb4 Binary files /dev/null and b/public/InitialDesign3.png differ diff --git a/public/InitialDesign4.png b/public/InitialDesign4.png new file mode 100644 index 00000000..6732aa2f Binary files /dev/null and b/public/InitialDesign4.png differ diff --git a/public/InitialDesign5.png b/public/InitialDesign5.png new file mode 100644 index 00000000..03cab6df Binary files /dev/null and b/public/InitialDesign5.png differ diff --git a/public/Orgchart_t3.png b/public/Orgchart_t3.png new file mode 100644 index 00000000..0d84e953 Binary files /dev/null and b/public/Orgchart_t3.png differ diff --git a/public/Section 1.jpg b/public/Section 1.jpg new file mode 100644 index 00000000..e67264a4 Binary files /dev/null and b/public/Section 1.jpg differ diff --git a/public/Section 2.jpg b/public/Section 2.jpg new file mode 100644 index 00000000..2ae7f703 Binary files /dev/null and b/public/Section 2.jpg differ diff --git a/public/Section 3.jpg b/public/Section 3.jpg new file mode 100644 index 00000000..06e1070d Binary files /dev/null and b/public/Section 3.jpg differ diff --git a/public/Section 5.jpg b/public/Section 5.jpg new file mode 100644 index 00000000..461ac50c Binary files /dev/null and b/public/Section 5.jpg differ diff --git a/public/Section 6.jpg b/public/Section 6.jpg new file mode 100644 index 00000000..b70f18a7 Binary files /dev/null and b/public/Section 6.jpg differ diff --git a/public/Section_1.png b/public/Section_1.png new file mode 100644 index 00000000..b3da99c6 Binary files /dev/null and b/public/Section_1.png differ diff --git a/public/Section_2.png b/public/Section_2.png new file mode 100644 index 00000000..80d9558c Binary files /dev/null and b/public/Section_2.png differ diff --git a/public/Section_3.png b/public/Section_3.png new file mode 100644 index 00000000..482b9b1a Binary files /dev/null and b/public/Section_3.png differ diff --git a/public/Section_4.png b/public/Section_4.png new file mode 100644 index 00000000..81732431 Binary files /dev/null and b/public/Section_4.png differ diff --git a/public/Section_5.png b/public/Section_5.png new file mode 100644 index 00000000..4c364e55 Binary files /dev/null and b/public/Section_5.png differ diff --git a/public/StudentView.jpg b/public/StudentView.jpg new file mode 100644 index 00000000..8fc003b1 Binary files /dev/null and b/public/StudentView.jpg differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-10.png b/public/TutorViewDesigns-T1-2023-Designs-10.png new file mode 100644 index 00000000..e121e363 Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-10.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-11.png b/public/TutorViewDesigns-T1-2023-Designs-11.png new file mode 100644 index 00000000..e7ddbb37 Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-11.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-12.png b/public/TutorViewDesigns-T1-2023-Designs-12.png new file mode 100644 index 00000000..86cae0d4 Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-12.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-13.png b/public/TutorViewDesigns-T1-2023-Designs-13.png new file mode 100644 index 00000000..210971c8 Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-13.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-14.png b/public/TutorViewDesigns-T1-2023-Designs-14.png new file mode 100644 index 00000000..4a5b9518 Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-14.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-15.png b/public/TutorViewDesigns-T1-2023-Designs-15.png new file mode 100644 index 00000000..7fdb91f4 Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-15.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-16.png b/public/TutorViewDesigns-T1-2023-Designs-16.png new file mode 100644 index 00000000..5f23b557 Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-16.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-17.png b/public/TutorViewDesigns-T1-2023-Designs-17.png new file mode 100644 index 00000000..eb0136b0 Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-17.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-18.png b/public/TutorViewDesigns-T1-2023-Designs-18.png new file mode 100644 index 00000000..bceee11f Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-18.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-19.png b/public/TutorViewDesigns-T1-2023-Designs-19.png new file mode 100644 index 00000000..ac18a667 Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-19.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-2.png b/public/TutorViewDesigns-T1-2023-Designs-2.png new file mode 100644 index 00000000..487979ea Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-2.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-20.png b/public/TutorViewDesigns-T1-2023-Designs-20.png new file mode 100644 index 00000000..23bb32f2 Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-20.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-24.png b/public/TutorViewDesigns-T1-2023-Designs-24.png new file mode 100644 index 00000000..76556486 Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-24.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-25.png b/public/TutorViewDesigns-T1-2023-Designs-25.png new file mode 100644 index 00000000..1f432c9b Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-25.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-26.png b/public/TutorViewDesigns-T1-2023-Designs-26.png new file mode 100644 index 00000000..c600fbf7 Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-26.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-27.png b/public/TutorViewDesigns-T1-2023-Designs-27.png new file mode 100644 index 00000000..70c1766c Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-27.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-3.png b/public/TutorViewDesigns-T1-2023-Designs-3.png new file mode 100644 index 00000000..e26cf31f Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-3.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-4.png b/public/TutorViewDesigns-T1-2023-Designs-4.png new file mode 100644 index 00000000..21767f9e Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-4.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-5.png b/public/TutorViewDesigns-T1-2023-Designs-5.png new file mode 100644 index 00000000..2ae0518a Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-5.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-6.png b/public/TutorViewDesigns-T1-2023-Designs-6.png new file mode 100644 index 00000000..5e1a6c5a Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-6.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-7.png b/public/TutorViewDesigns-T1-2023-Designs-7.png new file mode 100644 index 00000000..3a3070bd Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-7.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-8.png b/public/TutorViewDesigns-T1-2023-Designs-8.png new file mode 100644 index 00000000..9688dda3 Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-8.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs-9.png b/public/TutorViewDesigns-T1-2023-Designs-9.png new file mode 100644 index 00000000..e32133cc Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs-9.png differ diff --git a/public/TutorViewDesigns-T1-2023-Designs.png b/public/TutorViewDesigns-T1-2023-Designs.png new file mode 100644 index 00000000..446d47fb Binary files /dev/null and b/public/TutorViewDesigns-T1-2023-Designs.png differ diff --git a/public/UML Class Diagram - Staff Grant Extension.jpeg b/public/UML Class Diagram - Staff Grant Extension.jpeg new file mode 100644 index 00000000..3bd5faf0 Binary files /dev/null and b/public/UML Class Diagram - Staff Grant Extension.jpeg differ diff --git a/public/UML Use Case Diagram - Staff Grant Extension.jpeg b/public/UML Use Case Diagram - Staff Grant Extension.jpeg new file mode 100644 index 00000000..596c722d Binary files /dev/null and b/public/UML Use Case Diagram - Staff Grant Extension.jpeg differ diff --git a/public/UnitChair.jpg b/public/UnitChair.jpg new file mode 100644 index 00000000..222acc6a Binary files /dev/null and b/public/UnitChair.jpg differ diff --git a/public/Use Cases.png b/public/Use Cases.png new file mode 100644 index 00000000..0573b73e Binary files /dev/null and b/public/Use Cases.png differ diff --git a/public/VideoShowcase-TutorViewDesignPrototype copy 2.mp4 b/public/VideoShowcase-TutorViewDesignPrototype copy 2.mp4 new file mode 100644 index 00000000..e2ea8fe6 Binary files /dev/null and b/public/VideoShowcase-TutorViewDesignPrototype copy 2.mp4 differ diff --git a/public/VideoShowcase-TutorViewDesignPrototype copy.mp4 b/public/VideoShowcase-TutorViewDesignPrototype copy.mp4 new file mode 100644 index 00000000..e2ea8fe6 Binary files /dev/null and b/public/VideoShowcase-TutorViewDesignPrototype copy.mp4 differ diff --git a/public/VideoShowcase-TutorViewDesignPrototype.mp4 b/public/VideoShowcase-TutorViewDesignPrototype.mp4 new file mode 100644 index 00000000..e2ea8fe6 Binary files /dev/null and b/public/VideoShowcase-TutorViewDesignPrototype.mp4 differ diff --git a/public/Voice Enrolment Process Flow.png b/public/Voice Enrolment Process Flow.png new file mode 100644 index 00000000..c57bc2c2 Binary files /dev/null and b/public/Voice Enrolment Process Flow.png differ diff --git a/public/Voice Verification Main Process.png b/public/Voice Verification Main Process.png new file mode 100644 index 00000000..746a13a7 Binary files /dev/null and b/public/Voice Verification Main Process.png differ diff --git a/public/Voice-Verification-Architecture-Diagram.png b/public/Voice-Verification-Architecture-Diagram.png new file mode 100644 index 00000000..e3bcbfeb Binary files /dev/null and b/public/Voice-Verification-Architecture-Diagram.png differ diff --git a/public/Voiceprint Enrolment GUI.png b/public/Voiceprint Enrolment GUI.png new file mode 100644 index 00000000..58cfc34f Binary files /dev/null and b/public/Voiceprint Enrolment GUI.png differ diff --git a/public/Wireframes.png b/public/Wireframes.png new file mode 100644 index 00000000..c06bb905 Binary files /dev/null and b/public/Wireframes.png differ diff --git a/public/arcade-machine-files/es_systems.cfg b/public/arcade-machine-files/es_systems.cfg new file mode 100644 index 00000000..421b3d9e --- /dev/null +++ b/public/arcade-machine-files/es_systems.cfg @@ -0,0 +1,36 @@ + + + + + + + + pc + + + PC + + + /home/deakin/Games/LaunchScripts + + + .exe .sh + + + %ROM% + + + PC + + + N64 + + diff --git a/public/arcade-machine-files/themes/splashkit/art/OPENSANS-LIGHT.TTF b/public/arcade-machine-files/themes/splashkit/art/OPENSANS-LIGHT.TTF new file mode 100644 index 00000000..0d381897 Binary files /dev/null and b/public/arcade-machine-files/themes/splashkit/art/OPENSANS-LIGHT.TTF differ diff --git a/public/arcade-machine-files/themes/splashkit/art/OPENSANS.TTF b/public/arcade-machine-files/themes/splashkit/art/OPENSANS.TTF new file mode 100644 index 00000000..db433349 Binary files /dev/null and b/public/arcade-machine-files/themes/splashkit/art/OPENSANS.TTF differ diff --git a/public/arcade-machine-files/themes/splashkit/art/bright.png b/public/arcade-machine-files/themes/splashkit/art/bright.png new file mode 100644 index 00000000..68681baa Binary files /dev/null and b/public/arcade-machine-files/themes/splashkit/art/bright.png differ diff --git a/public/arcade-machine-files/themes/splashkit/art/dark.png b/public/arcade-machine-files/themes/splashkit/art/dark.png new file mode 100644 index 00000000..68681baa Binary files /dev/null and b/public/arcade-machine-files/themes/splashkit/art/dark.png differ diff --git a/public/arcade-machine-files/themes/splashkit/art/mid.png b/public/arcade-machine-files/themes/splashkit/art/mid.png new file mode 100644 index 00000000..64e5133b Binary files /dev/null and b/public/arcade-machine-files/themes/splashkit/art/mid.png differ diff --git a/public/arcade-machine-files/themes/splashkit/art/star_filled_spacing.svg b/public/arcade-machine-files/themes/splashkit/art/star_filled_spacing.svg new file mode 100644 index 00000000..f6aab18c --- /dev/null +++ b/public/arcade-machine-files/themes/splashkit/art/star_filled_spacing.svg @@ -0,0 +1,12 @@ + + + + + + diff --git a/public/arcade-machine-files/themes/splashkit/art/star_hollow_2_spacing.svg b/public/arcade-machine-files/themes/splashkit/art/star_hollow_2_spacing.svg new file mode 100644 index 00000000..75d1c25c --- /dev/null +++ b/public/arcade-machine-files/themes/splashkit/art/star_hollow_2_spacing.svg @@ -0,0 +1,21 @@ + + + + + + diff --git a/public/arcade-machine-files/themes/splashkit/art/star_hollow_3_spacing.svg b/public/arcade-machine-files/themes/splashkit/art/star_hollow_3_spacing.svg new file mode 100644 index 00000000..c6ce4fa8 --- /dev/null +++ b/public/arcade-machine-files/themes/splashkit/art/star_hollow_3_spacing.svg @@ -0,0 +1,21 @@ + + + + + + diff --git a/public/arcade-machine-files/themes/splashkit/art/star_hollow_spacing.svg b/public/arcade-machine-files/themes/splashkit/art/star_hollow_spacing.svg new file mode 100644 index 00000000..d1063e40 --- /dev/null +++ b/public/arcade-machine-files/themes/splashkit/art/star_hollow_spacing.svg @@ -0,0 +1,18 @@ + + + + + + diff --git a/public/arcade-machine-files/themes/splashkit/art/white.png b/public/arcade-machine-files/themes/splashkit/art/white.png new file mode 100644 index 00000000..b187f791 Binary files /dev/null and b/public/arcade-machine-files/themes/splashkit/art/white.png differ diff --git a/public/arcade-machine-files/themes/splashkit/simple.xml b/public/arcade-machine-files/themes/splashkit/simple.xml new file mode 100644 index 00000000..08ba2414 --- /dev/null +++ b/public/arcade-machine-files/themes/splashkit/simple.xml @@ -0,0 +1,121 @@ + + + + 3 + + + + + 0 1 + 0.5 0.5 + 0.5 0.5 + + + + + + + 393a3b + 1 + ./art/OPENSANS-LIGHT.TTF + 0.03 + 0.12 0.04 + + + + 393a3b + 1 + ./art/OPENSANS-LIGHT.TTF + 0.03 + 0.14 0.04 + + + + 393a3b + 1 + ./art/OPENSANS-LIGHT.TTF + 0.03 + + + + 393a3b + 1 + ./art/OPENSANS-LIGHT.TTF + 0.03 + 0 0.04 + + + + 0 0 + 0 0 + 1 0.16 + ./art/bright.png + + + + 0 1 + 0 1 + 1 0.065 + ./art/bright.png + + + + 0 0 + 0 0 + 1 1 + ./art/mid.png + + + + 393a3b + 97999b + 393a3b + 000000 + ./art/OPENSANS.TTF + 0.03 + 1 + + + + + + + + + + + + + + diff --git a/public/arcade-machine-files/themes/splashkit/sk/art/background.jpg b/public/arcade-machine-files/themes/splashkit/sk/art/background.jpg new file mode 100644 index 00000000..b3795a0f Binary files /dev/null and b/public/arcade-machine-files/themes/splashkit/sk/art/background.jpg differ diff --git a/public/arcade-machine-files/themes/splashkit/sk/art/backgroundprogress.pdn b/public/arcade-machine-files/themes/splashkit/sk/art/backgroundprogress.pdn new file mode 100644 index 00000000..8cdccf3a Binary files /dev/null and b/public/arcade-machine-files/themes/splashkit/sk/art/backgroundprogress.pdn differ diff --git a/public/arcade-machine-files/themes/splashkit/sk/art/font.PNG b/public/arcade-machine-files/themes/splashkit/sk/art/font.PNG new file mode 100644 index 00000000..8f8b1774 Binary files /dev/null and b/public/arcade-machine-files/themes/splashkit/sk/art/font.PNG differ diff --git a/public/arcade-machine-files/themes/splashkit/sk/art/logotext.png b/public/arcade-machine-files/themes/splashkit/sk/art/logotext.png new file mode 100644 index 00000000..02d99a82 Binary files /dev/null and b/public/arcade-machine-files/themes/splashkit/sk/art/logotext.png differ diff --git a/public/arcade-machine-files/themes/splashkit/sk/art/splashkit.png b/public/arcade-machine-files/themes/splashkit/sk/art/splashkit.png new file mode 100644 index 00000000..06dcae37 Binary files /dev/null and b/public/arcade-machine-files/themes/splashkit/sk/art/splashkit.png differ diff --git a/public/arcade-machine-files/themes/splashkit/sk/art/thoth_artwork.png b/public/arcade-machine-files/themes/splashkit/sk/art/thoth_artwork.png new file mode 100644 index 00000000..759b031c Binary files /dev/null and b/public/arcade-machine-files/themes/splashkit/sk/art/thoth_artwork.png differ diff --git a/public/arcade-machine-files/themes/splashkit/sk/art/thothlogo.png b/public/arcade-machine-files/themes/splashkit/sk/art/thothlogo.png new file mode 100644 index 00000000..df5e1635 Binary files /dev/null and b/public/arcade-machine-files/themes/splashkit/sk/art/thothlogo.png differ diff --git a/public/arcade-machine-files/themes/splashkit/sk/theme.xml b/public/arcade-machine-files/themes/splashkit/sk/theme.xml new file mode 100644 index 00000000..855b9831 --- /dev/null +++ b/public/arcade-machine-files/themes/splashkit/sk/theme.xml @@ -0,0 +1,161 @@ + + 3 + ./../simple.xml + + + + + ./art/background.jpg + + + + ./art/logotext.png + + + + ffffff88 + ffffff88 + + + + + + + + Splashkit + 1 + 0.45 0.08 + 0.527 0.04 + F5A623 + ./../art/OPENSANS-LIGHT.TTF + 0.055 + right + + + + + ./art/logotext.png + 0.025 0.079 + 0.47 0.1 + 0 0.5 + + + + + + + + 0.025 0.22 + 0.950 0.68 + center + 0.01 + + + + + + + + + + 0.025 0.22 + 0.12 0.301 + 0 0 + + + + 0.172 0.21 + + + + 0.172 0.25 + + + + 0.172 0.29 + 0.133 0.04 + + + + 0.172 0.33 + 0.133 0.04 + + + + 0.172 0.37 + + + + 0.172 0.41 + + + + 0.172 0.45 + + + + 0.172 0.49 + + + + 0.305 0.49 + + + + 0.305 0.45 + + + + 0.305 0.41 + + + + 0.305 0.37 + 0.25 0.04 + + + + 0.305 0.33 + 0.25 0.04 + + + + 0.305 0.29 + 0.25 0.04 + + + + 0.305 0.25 + + + + 0.305 0.216 + 0.028 0.028 + ./../art/star_filled_spacing.svg + ./../art/star_hollow_3_spacing.svg + + + + 0.52 0.3 + 0.025 0.577 + + + + 0.615 0.22 + 0.359 0.68 + left + 0.01 + + + + + diff --git a/public/bootkeys.png b/public/bootkeys.png new file mode 100644 index 00000000..34ba7d85 Binary files /dev/null and b/public/bootkeys.png differ diff --git a/public/chathistorydisplayer-proposition.png b/public/chathistorydisplayer-proposition.png new file mode 100644 index 00000000..8d8e2ab9 Binary files /dev/null and b/public/chathistorydisplayer-proposition.png differ diff --git a/public/codespaces-1.png b/public/codespaces-1.png new file mode 100644 index 00000000..88c64cd5 Binary files /dev/null and b/public/codespaces-1.png differ diff --git a/public/codespaces-2.png b/public/codespaces-2.png new file mode 100644 index 00000000..bed59b68 Binary files /dev/null and b/public/codespaces-2.png differ diff --git a/public/codespaces-3.png b/public/codespaces-3.png new file mode 100644 index 00000000..2e3663b7 Binary files /dev/null and b/public/codespaces-3.png differ diff --git a/public/codespaces-4.png b/public/codespaces-4.png new file mode 100644 index 00000000..f579377c Binary files /dev/null and b/public/codespaces-4.png differ diff --git a/public/codespaces-5.png b/public/codespaces-5.png new file mode 100644 index 00000000..32cce4f5 Binary files /dev/null and b/public/codespaces-5.png differ diff --git a/public/codespaces-6.png b/public/codespaces-6.png new file mode 100644 index 00000000..4d31f956 Binary files /dev/null and b/public/codespaces-6.png differ diff --git a/public/codespaces-7.png b/public/codespaces-7.png new file mode 100644 index 00000000..6494c87f Binary files /dev/null and b/public/codespaces-7.png differ diff --git a/public/codespaces-8.png b/public/codespaces-8.png new file mode 100644 index 00000000..e64fd43a Binary files /dev/null and b/public/codespaces-8.png differ diff --git a/public/codespaces-9.png b/public/codespaces-9.png new file mode 100644 index 00000000..ee8b18fc Binary files /dev/null and b/public/codespaces-9.png differ diff --git a/public/company-structure/2024-t2-thoth-tech-structure.png b/public/company-structure/2024-t2-thoth-tech-structure.png new file mode 100644 index 00000000..89be3f69 Binary files /dev/null and b/public/company-structure/2024-t2-thoth-tech-structure.png differ diff --git a/public/company-structure/2024-t3-thoth-tech-structure.png b/public/company-structure/2024-t3-thoth-tech-structure.png new file mode 100644 index 00000000..121a282d Binary files /dev/null and b/public/company-structure/2024-t3-thoth-tech-structure.png differ diff --git a/public/company-structure/2025-t1-thoth-tech-structure.png b/public/company-structure/2025-t1-thoth-tech-structure.png new file mode 100644 index 00000000..98136bee Binary files /dev/null and b/public/company-structure/2025-t1-thoth-tech-structure.png differ diff --git a/public/cookieconsent-config.js b/public/cookieconsent-config.js new file mode 100644 index 00000000..94d0827a --- /dev/null +++ b/public/cookieconsent-config.js @@ -0,0 +1,105 @@ +import 'https://cdn.jsdelivr.net/gh/orestbida/cookieconsent@3.0.1/dist/cookieconsent.umd.js'; + +// Enable dark mode +document.documentElement.classList.add('cc--darkmode'); + +CookieConsent.run({ + guiOptions: { + consentModal: { + layout: "box", + position: "bottom right", + equalWeightButtons: true, + flipButtons: false + }, + preferencesModal: { + layout: "box", + position: "right", + equalWeightButtons: true, + flipButtons: false + } + }, + categories: { + necessary: { + readOnly: true + }, + analytics: { + services: { + ga4: { + label: 'Google Analytics 4', + onAccept: () => { + console.log("Analytics consent granted"); + window.gtag('consent', 'update', { + ad_storage: 'granted', + ad_user_data: 'granted', + ad_personalization: 'granted', + analytics_storage: 'granted', + }); + }, + onReject: () => { + console.log("Analytics consent denied"); + window.gtag('consent', 'update', { + ad_storage: 'denied', + ad_user_data: 'denied', + ad_personalization: 'denied', + analytics_storage: 'denied', + }); + }, + cookies: [ + { + name: /^_ga/, + path: '/', + }, + ], + }, + }, + }, + marketing: {} + }, + language: { + default: "en", + autoDetect: "browser", + translations: { + en: { + consentModal: { + title: "Your Privacy Matters to Us", + description: "We use cookies to enhance your experience and gather anonymised analytics data to improve our website. We are a non-profit open-source project and will never use your data for advertising or sell it to third parties. For more details, see our Privacy Policy.", + acceptAllBtn: "Accept All Cookies", + acceptNecessaryBtn: "Reject Non-Essential Cookies", + showPreferencesBtn: "Manage Preferences", + }, + preferencesModal: { + title: "Manage Your Privacy Preferences", + acceptAllBtn: "Accept All", + acceptNecessaryBtn: "Reject Non-Essential", + savePreferencesBtn: "Save Preferences", + closeIconLabel: "Close Modal", + serviceCounterLabel: "Service|Services", + sections: [ + { + title: "Why We Use Cookies", + description: "We use cookies to understand how you interact with our website and to improve our resources. Your data will never be used for advertising purposes or shared without your consent." + }, + { + title: "Strictly Necessary Cookies Always Enabled", + description: "These cookies are essential for the basic functionality of our website and cannot be disabled." + }, + { + title: "Analytics Cookies", + description: "Analytics cookies help us gather anonymised data about website usage to improve the user experience. Your data remains secure and is not shared for advertising purposes.", + linkedCategory: "analytics" + }, + { + title: "Advertisement Cookies", + description: "Our website does not use advertisement cookies. We are a non-profit organisation and do not display ads." + }, + { + title: "More Information", + description: "Please see our privacy policy for more information." + } + ] + } + } + } + }, + disablePageInteraction: false +}); diff --git a/public/course-flow-course-map-1.png b/public/course-flow-course-map-1.png new file mode 100644 index 00000000..8f16c23f Binary files /dev/null and b/public/course-flow-course-map-1.png differ diff --git a/public/course-flow-course-map-2.png b/public/course-flow-course-map-2.png new file mode 100644 index 00000000..eb857977 Binary files /dev/null and b/public/course-flow-course-map-2.png differ diff --git a/public/course-flow-detailed-unit.png b/public/course-flow-detailed-unit.png new file mode 100644 index 00000000..fc07332b Binary files /dev/null and b/public/course-flow-detailed-unit.png differ diff --git a/public/course-flow-entry.png b/public/course-flow-entry.png new file mode 100644 index 00000000..e7eb0b8f Binary files /dev/null and b/public/course-flow-entry.png differ diff --git a/public/course-flow-erd.png b/public/course-flow-erd.png new file mode 100644 index 00000000..32674324 Binary files /dev/null and b/public/course-flow-erd.png differ diff --git a/public/courseflow-dfd-level-0.png b/public/courseflow-dfd-level-0.png new file mode 100644 index 00000000..852aae5d Binary files /dev/null and b/public/courseflow-dfd-level-0.png differ diff --git a/public/courseflow-enhanced-erd.png b/public/courseflow-enhanced-erd.png new file mode 100644 index 00000000..edf280f5 Binary files /dev/null and b/public/courseflow-enhanced-erd.png differ diff --git a/public/courseflow-high-level-entity-relationship.png b/public/courseflow-high-level-entity-relationship.png new file mode 100644 index 00000000..c729ef3e Binary files /dev/null and b/public/courseflow-high-level-entity-relationship.png differ diff --git a/public/courseflow-system-architecture.png b/public/courseflow-system-architecture.png new file mode 100644 index 00000000..a596e437 Binary files /dev/null and b/public/courseflow-system-architecture.png differ diff --git a/public/create_branch.png b/public/create_branch.png new file mode 100644 index 00000000..786cc93c Binary files /dev/null and b/public/create_branch.png differ diff --git a/public/custom-layout.png b/public/custom-layout.png new file mode 100644 index 00000000..c61dfba6 Binary files /dev/null and b/public/custom-layout.png differ diff --git a/public/deakin_setup_page.png b/public/deakin_setup_page.png new file mode 100644 index 00000000..f5890eb7 Binary files /dev/null and b/public/deakin_setup_page.png differ diff --git a/public/deakin_setup_terminal.png b/public/deakin_setup_terminal.png new file mode 100644 index 00000000..a6abce54 Binary files /dev/null and b/public/deakin_setup_terminal.png differ diff --git a/public/delete_import.png b/public/delete_import.png new file mode 100644 index 00000000..7b04d406 Binary files /dev/null and b/public/delete_import.png differ diff --git a/public/delete_injection.png b/public/delete_injection.png new file mode 100644 index 00000000..5c4a778f Binary files /dev/null and b/public/delete_injection.png differ diff --git a/public/demonstration.mp4 b/public/demonstration.mp4 new file mode 100644 index 00000000..eb5d54df Binary files /dev/null and b/public/demonstration.mp4 differ diff --git a/public/dockerimage.png b/public/dockerimage.png new file mode 100644 index 00000000..c28a7f7a Binary files /dev/null and b/public/dockerimage.png differ diff --git a/public/doubtfire-localhost-compose.png b/public/doubtfire-localhost-compose.png new file mode 100644 index 00000000..5ca7e3dc Binary files /dev/null and b/public/doubtfire-localhost-compose.png differ diff --git a/public/doubtfire-localhost-docker.png b/public/doubtfire-localhost-docker.png new file mode 100644 index 00000000..8a584770 Binary files /dev/null and b/public/doubtfire-localhost-docker.png differ diff --git a/public/doubtfire-localhost.png b/public/doubtfire-localhost.png new file mode 100644 index 00000000..5b34e403 Binary files /dev/null and b/public/doubtfire-localhost.png differ diff --git a/public/downgrade.png b/public/downgrade.png new file mode 100644 index 00000000..7c03a16b Binary files /dev/null and b/public/downgrade.png differ diff --git a/public/edit-profile-form.png b/public/edit-profile-form.png new file mode 100644 index 00000000..ec6f329a Binary files /dev/null and b/public/edit-profile-form.png differ diff --git a/public/favicon-alternative.svg b/public/favicon-alternative.svg new file mode 100644 index 00000000..9d948c42 --- /dev/null +++ b/public/favicon-alternative.svg @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/favicon-small.svg b/public/favicon-small.svg new file mode 100644 index 00000000..b52be39e --- /dev/null +++ b/public/favicon-small.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 00000000..43df1f79 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/feedbackform.html b/public/feedbackform.html new file mode 100644 index 00000000..8873d154 --- /dev/null +++ b/public/feedbackform.html @@ -0,0 +1,97 @@ + + + + + +Feedback Form + + + +
+

Feedback Page

+

We would love your feedback

+

Our goal is to make a platform that simplifies your workday. You’ve been using Thoth Tech Documentation Website for a while now, and we’d love to know what you think about it. We really appreciate your feedback!

+ +
+ + + + + +
+ +
+ + +
+ + + + +
+ + + +
+
+ + + diff --git a/public/fetch_thoth.png b/public/fetch_thoth.png new file mode 100644 index 00000000..737297c8 Binary files /dev/null and b/public/fetch_thoth.png differ diff --git a/public/figure1.PNG b/public/figure1.PNG new file mode 100644 index 00000000..c920c54b Binary files /dev/null and b/public/figure1.PNG differ diff --git a/public/figure1.jpeg b/public/figure1.jpeg new file mode 100644 index 00000000..8f161569 Binary files /dev/null and b/public/figure1.jpeg differ diff --git a/public/figure2 copy.PNG b/public/figure2 copy.PNG new file mode 100644 index 00000000..6c964fad Binary files /dev/null and b/public/figure2 copy.PNG differ diff --git a/public/figure2.PNG b/public/figure2.PNG new file mode 100644 index 00000000..0d762a0d Binary files /dev/null and b/public/figure2.PNG differ diff --git a/public/figure3 copy.PNG b/public/figure3 copy.PNG new file mode 100644 index 00000000..df60b675 Binary files /dev/null and b/public/figure3 copy.PNG differ diff --git a/public/figure3.png b/public/figure3.png new file mode 100644 index 00000000..6014a2f8 Binary files /dev/null and b/public/figure3.png differ diff --git a/public/figure4.PNG b/public/figure4.PNG new file mode 100644 index 00000000..614204dd Binary files /dev/null and b/public/figure4.PNG differ diff --git a/public/figure5.PNG b/public/figure5.PNG new file mode 100644 index 00000000..abf1c216 Binary files /dev/null and b/public/figure5.PNG differ diff --git a/public/figure6.PNG b/public/figure6.PNG new file mode 100644 index 00000000..e23c4c76 Binary files /dev/null and b/public/figure6.PNG differ diff --git a/public/figure7.PNG b/public/figure7.PNG new file mode 100644 index 00000000..2a0dcd3c Binary files /dev/null and b/public/figure7.PNG differ diff --git a/public/figure8.PNG b/public/figure8.PNG new file mode 100644 index 00000000..7476a159 Binary files /dev/null and b/public/figure8.PNG differ diff --git a/public/final-iteration-1-and-2-wireframes.png b/public/final-iteration-1-and-2-wireframes.png new file mode 100644 index 00000000..28e3a96e Binary files /dev/null and b/public/final-iteration-1-and-2-wireframes.png differ diff --git a/public/force-directed-graph.png b/public/force-directed-graph.png new file mode 100644 index 00000000..6cb0d23e Binary files /dev/null and b/public/force-directed-graph.png differ diff --git a/public/gcp-instance-connect.png b/public/gcp-instance-connect.png new file mode 100644 index 00000000..d32199d1 Binary files /dev/null and b/public/gcp-instance-connect.png differ diff --git a/public/gcp-instance-docker.png b/public/gcp-instance-docker.png new file mode 100644 index 00000000..c2a2438a Binary files /dev/null and b/public/gcp-instance-docker.png differ diff --git a/public/git_checkout.png b/public/git_checkout.png new file mode 100644 index 00000000..5b10144a Binary files /dev/null and b/public/git_checkout.png differ diff --git a/public/git_remote.png b/public/git_remote.png new file mode 100644 index 00000000..8b640ebf Binary files /dev/null and b/public/git_remote.png differ diff --git a/public/image-10.png b/public/image-10.png new file mode 100644 index 00000000..d2576b2c Binary files /dev/null and b/public/image-10.png differ diff --git a/public/image-11.png b/public/image-11.png new file mode 100644 index 00000000..e0e9ca86 Binary files /dev/null and b/public/image-11.png differ diff --git a/public/image-12.png b/public/image-12.png new file mode 100644 index 00000000..7055bb61 Binary files /dev/null and b/public/image-12.png differ diff --git a/public/image-13.png b/public/image-13.png new file mode 100644 index 00000000..7de87cc0 Binary files /dev/null and b/public/image-13.png differ diff --git a/public/import_to_angular.png b/public/import_to_angular.png new file mode 100644 index 00000000..85d036f7 Binary files /dev/null and b/public/import_to_angular.png differ diff --git a/public/import_to_ng_module.png b/public/import_to_ng_module.png new file mode 100644 index 00000000..e00579e1 Binary files /dev/null and b/public/import_to_ng_module.png differ diff --git a/public/install_ubuntu.png b/public/install_ubuntu.png new file mode 100644 index 00000000..2aa41d30 Binary files /dev/null and b/public/install_ubuntu.png differ diff --git a/public/installation_type.png b/public/installation_type.png new file mode 100644 index 00000000..2922a4b1 Binary files /dev/null and b/public/installation_type.png differ diff --git a/public/iteration-3-design-1.png b/public/iteration-3-design-1.png new file mode 100644 index 00000000..f88da9c8 Binary files /dev/null and b/public/iteration-3-design-1.png differ diff --git a/public/iteration-3-design-2.png b/public/iteration-3-design-2.png new file mode 100644 index 00000000..4a73a102 Binary files /dev/null and b/public/iteration-3-design-2.png differ diff --git a/public/logo.png b/public/logo.png new file mode 100644 index 00000000..9723b00c Binary files /dev/null and b/public/logo.png differ diff --git a/public/onboardingDemo.png b/public/onboardingDemo.png new file mode 100644 index 00000000..42c77d53 Binary files /dev/null and b/public/onboardingDemo.png differ diff --git a/public/onboardingDesign.png b/public/onboardingDesign.png new file mode 100644 index 00000000..5d3d9f63 Binary files /dev/null and b/public/onboardingDesign.png differ diff --git a/public/ontrack-login.png b/public/ontrack-login.png new file mode 100644 index 00000000..9ad66986 Binary files /dev/null and b/public/ontrack-login.png differ diff --git a/public/ontrack/contributing-guide/backendmigrationerror.png b/public/ontrack/contributing-guide/backendmigrationerror.png new file mode 100644 index 00000000..c7fc91c8 Binary files /dev/null and b/public/ontrack/contributing-guide/backendmigrationerror.png differ diff --git a/public/ontrack/contributing-guide/correctsigninpage.png b/public/ontrack/contributing-guide/correctsigninpage.png new file mode 100644 index 00000000..28734c36 Binary files /dev/null and b/public/ontrack/contributing-guide/correctsigninpage.png differ diff --git a/public/ontrack/contributing-guide/dockererror.png b/public/ontrack/contributing-guide/dockererror.png new file mode 100644 index 00000000..88f08a41 Binary files /dev/null and b/public/ontrack/contributing-guide/dockererror.png differ diff --git a/public/ontrack/contributing-guide/gitfetchexample.png b/public/ontrack/contributing-guide/gitfetchexample.png new file mode 100644 index 00000000..cc05a986 Binary files /dev/null and b/public/ontrack/contributing-guide/gitfetchexample.png differ diff --git a/public/ontrack/contributing-guide/gitremotes.png b/public/ontrack/contributing-guide/gitremotes.png new file mode 100644 index 00000000..21a238d9 Binary files /dev/null and b/public/ontrack/contributing-guide/gitremotes.png differ diff --git a/public/ontrack/contributing-guide/incorrectsigninpage.png b/public/ontrack/contributing-guide/incorrectsigninpage.png new file mode 100644 index 00000000..c04e50b6 Binary files /dev/null and b/public/ontrack/contributing-guide/incorrectsigninpage.png differ diff --git a/public/ontrack/contributing-guide/mysqlerror.png b/public/ontrack/contributing-guide/mysqlerror.png new file mode 100644 index 00000000..d4e297ff Binary files /dev/null and b/public/ontrack/contributing-guide/mysqlerror.png differ diff --git a/public/ontrack/contributing-guide/poststarterror.png b/public/ontrack/contributing-guide/poststarterror.png new file mode 100644 index 00000000..fd98e81b Binary files /dev/null and b/public/ontrack/contributing-guide/poststarterror.png differ diff --git a/public/picture.png b/public/picture.png new file mode 100644 index 00000000..0d84e953 Binary files /dev/null and b/public/picture.png differ diff --git a/public/push_to_origin.png b/public/push_to_origin.png new file mode 100644 index 00000000..78904c8a Binary files /dev/null and b/public/push_to_origin.png differ diff --git a/public/root_partition.png b/public/root_partition.png new file mode 100644 index 00000000..0f1850d3 Binary files /dev/null and b/public/root_partition.png differ diff --git a/public/rufus_screenshot.png b/public/rufus_screenshot.png new file mode 100644 index 00000000..1b95f6fa Binary files /dev/null and b/public/rufus_screenshot.png differ diff --git a/public/scripts/MSTeamsPlannerExportScript.py b/public/scripts/MSTeamsPlannerExportScript.py new file mode 100644 index 00000000..b49d2e03 --- /dev/null +++ b/public/scripts/MSTeamsPlannerExportScript.py @@ -0,0 +1,396 @@ +# ------------------------------------------------------- +#@title MS Graph API replacement! +# ------------------------------------------------------- + +# Much smaller than the actual Python API and has no dependencies. +# Should be extendable to support anything offered by the HTTP API as needed. + +import json +import os +import re +import base64 +import urllib.parse +import urllib.request +import urllib.error +import time + +# Useful abstractions over the MS Graph API +def make_api_request(url, headers, method="GET", data=None): + encoded_data = urllib.parse.urlencode(data).encode("utf-8") if data else None + request = urllib.request.Request(url, headers=headers, data=encoded_data, method=method) + try: + with urllib.request.urlopen(request) as response: + return json.loads(response.read()) + except urllib.error.HTTPError as e: + error =f"API Request failed: {e.reason}" + + try: + error_data = json.loads(e.read()) + error = error_data.get('error') + except: + pass + + raise Exception(error) from e + +def make_paginated_api_request(url, headers, callback): + while url: + response_data = make_api_request(url, headers) + callback(response_data.get("value", [])) + url = response_data.get("@odata.nextLink") + if url: + print("Fetching more...") + +def get_access_token(CLIENT_ID, TENANT_ID, scopes): + device_code_url = f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/devicecode" + device_code_data = { + 'client_id': CLIENT_ID, + 'scope': ' '.join([f'https://graph.microsoft.com/{scope}' for scope in scopes]) + } + + device_code_response = make_api_request(device_code_url, headers={}, method="POST", data=device_code_data) + + print(f"Please go to {device_code_response['verification_uri']} and enter this code: {device_code_response['user_code']}") + + retry_interval = device_code_response.get('interval', 5) # Default to 5 seconds if not provided + + token_url = f"https://login.microsoftonline.com/{TENANT_ID}/oauth2/v2.0/token" + token_data = { + "grant_type": "urn:ietf:params:oauth:grant-type:device_code", + "client_id": CLIENT_ID, + "device_code": device_code_response["device_code"], + } + + # Poll until access token is ready + while True: + try: + token_response = make_api_request(token_url, headers={}, method="POST", data=token_data) + return token_response.get("access_token") + except Exception as e: + if "authorization_pending" in str(e): + print("Waiting for user authorization... (Will check again in 5 seconds)") + time.sleep(retry_interval) # Avoid throttling... + else: + raise + +# Util class - allows access of dictionary keys as class members +class AttrDict(dict): + def __init__(self, *args, **kwargs): + super(AttrDict, self).__init__(*args, **kwargs) + self.__dict__ = self + +# Class for fetching tasks/users etc with a valid access token +class AuthorizedClient(): + def __init__(self, access_token): + self.access_token = access_token + + def fetch_all(self, url): + headers = {"Authorization": f"Bearer {self.access_token}"} + url = "https://graph.microsoft.com/v1.0"+url + result = [] + + def append(values): + result.extend([AttrDict(**x) for x in values]) + + make_paginated_api_request(url, headers, append) + return result + + def fetch_one(self, url): + headers = {"Authorization": f"Bearer {self.access_token}"} + url = "https://graph.microsoft.com/v1.0"+url + + return AttrDict(**make_api_request(url, headers)) + + def fetch_plans(self): + return self.fetch_all("/me/planner/plans") + + def fetch_plan_tasks(self, plan_id): + return self.fetch_all(f"/planner/plans/{plan_id}/tasks") + + def fetch_plan_buckets(self, plan_id): + return self.fetch_all(f"/planner/plans/{plan_id}/buckets") + + def fetch_plan(self, plan_id): + return self.fetch_one(f"/planner/plans/{plan_id}") + + def fetch_bucket(self, bucket_id): + return self.fetch_one(f"/planner/buckets/{bucket_id}") + + def fetch_task(self, task_id): + return self.fetch_one(f"/planner/tasks/{task_id}") + + def fetch_task_details(self, task_id): + return self.fetch_one(f"/planner/tasks/{task_id}/details") + + def fetch_user(self, user_id): + return self.fetch_one(f"/users/{user_id}") + +# ------------------------------------------------------- +#@title Initialize Global Caches +# ------------------------------------------------------- + +user_name_map = {} +bucket_name_map = {} +task_map = {} + +def brief_pause(): + time.sleep(1.0) + +def print_separator(): + print("-"*20) + +def print_title(title): + print() + print_separator() + print(title) + print_separator() + print() + brief_pause() + +# ------------------------------------------------------- +#@title Get MS Graph API Access Token! +# ------------------------------------------------------- + +print_title("Welcome to the MS Teams Planner Export Script!") + +CLIENT_ID = '2f7a887d-6fb2-45f8-b2bb-a42aea55e27d' +TENANT_ID = 'common' # Use 'common' for multi-tenant apps +access_token = get_access_token(CLIENT_ID, TENANT_ID, ['user.read', 'tasks.read', 'user.readbasic.all']) +print("Authorized!") + +# ------------------------------------------------------- +#@title Create Client Object +# ------------------------------------------------------- + +client = AuthorizedClient(access_token) + +# ------------------------------------------------------- +#@title Fetch the tasks! +# ------------------------------------------------------- + +while True: + print_title("Fetching accessible plans/boards") + plans = client.fetch_plans() + + print("Here are the list of plans you can choose from:") + + planIDs = [] + print("0) Reload options") + for i, plan in enumerate(plans): + print(str(i + 1)+")", plan.title) + planIDs.append(plan) + + print("") + + print("If you don't see the one you are expecting, make sure you have opened that plan at least once in Teams - then choose option 0 to reload.") + print("Please select a plan to fetch data from, by the number beside it.") + planIndex = input("> ") + while not planIndex.isdigit() or int(planIndex) < 0 or int(planIndex) > len(planIDs): + print("Invalid value") + planIndex = input("> ") + planIndex = int(planIndex) + + if planIndex != 0: + break + +planIndex -= 1 +print("You have selected '"+planIDs[planIndex].title+"', which has the ID "+planIDs[planIndex].id) +brief_pause() + +planID = planIDs[planIndex].id + +# Fetch the list of tasks +print_title("Fetching tasks...") + +tasks = client.fetch_plan_tasks(planID) + +print(str(len(tasks)) + " tasks fetched!") + +# ------------------------------------------------------- +#@title Chose what to export (which buckets/backlogs, and format) +# ------------------------------------------------------- + +print_title("Format Selection") + +while True: + print("Are we exporting the raw data, or the data needed for company documents/handovers? (raw, document)") + full_data_export = input("> ").strip().lower() + + if full_data_export != 'raw' and full_data_export != 'document': + print("Please enter 'raw', or 'document'") + continue + + full_data_export = full_data_export == 'raw' + break + +if full_data_export: + print("Full data export - all buckets will be exported.") + backlogs_of_interest_names = None +else: + buckets = client.fetch_plan_buckets(planID) + +print_title("Bucket Selection") + +while not full_data_export: + print("Please enter a comma delimited set of numbers for which buckets you would like to export data from (e.g 1,4,5).") + print("You may also use @ and then a word to select all buckets with that word (e.g 1,7,@Complete)") + print("Enter ALL to export all of them.") + + print_separator() + for i, bucket in enumerate(buckets): + print(str(i + 1)+")", bucket.name) + print_separator() + + while True: + chosen_buckets = input("> ") + if chosen_buckets.strip().lower() == "all": + backlogs_of_interest_names = None + break + + indexes = [x.strip() for x in chosen_buckets.split(",")] + if not all([x.isdigit() or (len(x)>0 and x[0]=='@') for x in indexes]): + print("Invalid input") + continue + + backlogs_of_interest_names = [] + for x in indexes: + if x[0] != '@': + index = int(x) - 1 + if index < 0 or index >= len(buckets): + print("Invalid index") + continue + + backlogs_of_interest_names.append(buckets[index].name) + else: + filter = x[1:].lower() + backlogs_of_interest_names += [x.name for x in buckets if filter in x.name.lower()] + break + + # remove any duplicates + if backlogs_of_interest_names != None: + backlogs_of_interest_names = list(dict.fromkeys(backlogs_of_interest_names)) + + print("You have selected the following buckets:") + print("") + print_separator() + if backlogs_of_interest_names == None: + print("All") + else: + print('\n'.join(backlogs_of_interest_names)) + print_separator() + print("Is this correct? (y/n)") + + all_good = input("> ").lower() + while all_good != 'n' and all_good != 'y': + print("Please enter y or n") + if all_good == 'y': + break + else: + print("Let's try again then!") + +print("Buckets selected - we can export the data now!") +brief_pause() + +print_title("Exporting...") + +# ------------------------------------------------------- +#@title Export the data! +# ------------------------------------------------------- + +import csv +from urllib.parse import unquote +from datetime import datetime + +tasks_list = [] + +# Loop through each task & contributor and append to tasks_list +for task in tasks: + + if task.bucketId not in bucket_name_map: + if task.bucketId == None: + bucket_name_map[task.bucketId] = "N/A (not on a list)" + else: + bucket_name_map[task.bucketId] = client.fetch_bucket(task.bucketId).name + bucket_name = bucket_name_map[task.bucketId] + + if backlogs_of_interest_names != None and bucket_name not in backlogs_of_interest_names: + continue + + # Fetch the task details + if task.id not in task_map: + task_map[task.id] = client.fetch_task_details(task.id) + + task_details = task_map[task.id] + + # Get the display name of the assigned user + # If no assigned users, output with a single one (0NONE) + users = task.assignments.keys() + if len(users) == 0: + users = ['0NONE'] + user_name_map['0NONE'] = '0NONE' + + for user_id in users: + + assigned_user_name = None + if user_id in user_name_map: + assigned_user_name = user_name_map[user_id] + else: + assigned_user = client.fetch_user(user_id) + assigned_user_name = assigned_user.displayName + user_name_map[user_id] = assigned_user_name + + # Get the links - filter to only github ones + is_contributor = False + links = [] + for url in task_details.references.keys(): + link = task_details.references[url] + + if 'alias' not in link: + print("Possible error: No alias key", link) + continue + + if 'github' not in url: + continue + + # Create nice URL links + if url.endswith('/'): + url = url[:-1] + if url.endswith('/files'): + url = url[:-6] + print (f"[{url[url.find("https://github.com/")+len("https://github.com/"):url.rfind("/pull/")]} - PR#{url[url.find("/pull/")+len("/pull/"):url.rfind("/files")]}]({url})") + + links.append(unquote(url)) + + if user_id == str(link['lastModifiedBy']['user']['id']): + is_contributor = True + + contribution_type = "" # start with unknown + if len(links) > 0: # if we have links, then anyone who added them is a "Main Contributor" + contribution_type = "Main Contributor" if is_contributor else "Reviewer" + elif len(users) == 1: # if we have no links, but only one assigned member, assume they are the "Main Contributor" + contribution_type = "Main Contributor" + + tasks_list.append([bucket_name, assigned_user_name, task.title, contribution_type, sorted(links)]) + +# Choose a nice name +timestamp = datetime.now().isoformat(timespec='seconds') +safe_timestamp = timestamp.replace(':', '-') +output_filename = f'{planIDs[planIndex].title}_Tasks_{safe_timestamp}.csv' + +# Open the CSV file and write out the results! +with open(output_filename, 'w', newline='') as csvfile: + writer = csv.writer(csvfile) + + if full_data_export: + sorted_tasks = sorted(tasks_list, key=lambda x: (x[0], x[2], x[3], x[1])) + writer.writerow(['List', 'Name', 'Contribution Type', 'Task Name', 'Task Attachment']) + for task in sorted_tasks: + writer.writerow([task[0], task[1], task[3], task[2], '\n'.join(task[4])]) + else: + sorted_tasks = sorted(tasks_list, key=lambda x: (x[1], x[3], x[0], x[2])) + writer.writerow(['Name', 'Type', 'Task Name', 'Task Attachment']) + for task in sorted_tasks: + if task[1] == '0NONE': + continue + writer.writerow([task[1].title(), "-" if len(task[3]) == 0 else task[3], task[2], '\n'.join(task[4])]) + +print_title("Finished! You can find the output at " + output_filename) diff --git a/public/section_1 copy.png b/public/section_1 copy.png new file mode 100644 index 00000000..9e11cac8 Binary files /dev/null and b/public/section_1 copy.png differ diff --git a/public/section_2 copy.png b/public/section_2 copy.png new file mode 100644 index 00000000..db508a11 Binary files /dev/null and b/public/section_2 copy.png differ diff --git a/public/section_3 copy.png b/public/section_3 copy.png new file mode 100644 index 00000000..073ca8c3 Binary files /dev/null and b/public/section_3 copy.png differ diff --git a/public/spike-cover-1.jpg b/public/spike-cover-1.jpg new file mode 100644 index 00000000..514e6592 Binary files /dev/null and b/public/spike-cover-1.jpg differ diff --git a/public/start_typescript.png b/public/start_typescript.png new file mode 100644 index 00000000..8d6bda19 Binary files /dev/null and b/public/start_typescript.png differ diff --git a/public/still-image-prototype.png b/public/still-image-prototype.png new file mode 100644 index 00000000..82a43d16 Binary files /dev/null and b/public/still-image-prototype.png differ diff --git a/public/submitsuccess.html b/public/submitsuccess.html new file mode 100644 index 00000000..90e069c5 --- /dev/null +++ b/public/submitsuccess.html @@ -0,0 +1,46 @@ + + + + + +Feedback Submitted + + + +
+

Feedback Submitted

+

We would love your feedback

+

Our goal is to make a platform that simplifies your workday. You’ve been using Thoth Tech Documentation Website for a while now, and we’d love to know what you think about it. We really appreciate your feedback!

+ +
+

Thanks for sharing your feedback with us

+

Your feedback has been submitted successfully.

+

Your input is valuable to us and will help us improve our services.

+
+
+ + diff --git a/public/teaching-period-breaks-migrated.png b/public/teaching-period-breaks-migrated.png new file mode 100644 index 00000000..f625b989 Binary files /dev/null and b/public/teaching-period-breaks-migrated.png differ diff --git a/public/teaching-period-breaks.png b/public/teaching-period-breaks.png new file mode 100644 index 00000000..f350dafc Binary files /dev/null and b/public/teaching-period-breaks.png differ diff --git a/public/teaching-period-details-editor-migrated.png b/public/teaching-period-details-editor-migrated.png new file mode 100644 index 00000000..86d70c00 Binary files /dev/null and b/public/teaching-period-details-editor-migrated.png differ diff --git a/public/teaching-period-details-editor.png b/public/teaching-period-details-editor.png new file mode 100644 index 00000000..b85dab70 Binary files /dev/null and b/public/teaching-period-details-editor.png differ diff --git a/public/teaching-period-units-migrated.png b/public/teaching-period-units-migrated.png new file mode 100644 index 00000000..4e63a48d Binary files /dev/null and b/public/teaching-period-units-migrated.png differ diff --git a/public/teaching-period-units.png b/public/teaching-period-units.png new file mode 100644 index 00000000..70681055 Binary files /dev/null and b/public/teaching-period-units.png differ diff --git a/public/ubuntu_desktop.png b/public/ubuntu_desktop.png new file mode 100644 index 00000000..9b4d807f Binary files /dev/null and b/public/ubuntu_desktop.png differ diff --git a/public/ubuntu_options.png b/public/ubuntu_options.png new file mode 100644 index 00000000..f6250942 Binary files /dev/null and b/public/ubuntu_options.png differ diff --git a/public/uml.png b/public/uml.png new file mode 100644 index 00000000..1e850668 Binary files /dev/null and b/public/uml.png differ diff --git a/public/unit-students-editor.png b/public/unit-students-editor.png new file mode 100644 index 00000000..353e9c5b Binary files /dev/null and b/public/unit-students-editor.png differ diff --git a/public/unit_test_terminal_output.png b/public/unit_test_terminal_output.png new file mode 100644 index 00000000..baea36ad Binary files /dev/null and b/public/unit_test_terminal_output.png differ diff --git a/public/use_case_diagram.png b/public/use_case_diagram.png new file mode 100644 index 00000000..56430c92 Binary files /dev/null and b/public/use_case_diagram.png differ diff --git a/public/vau-c-1.png b/public/vau-c-1.png new file mode 100644 index 00000000..9fbb943f Binary files /dev/null and b/public/vau-c-1.png differ diff --git a/public/vau-c-2.png b/public/vau-c-2.png new file mode 100644 index 00000000..10d56378 Binary files /dev/null and b/public/vau-c-2.png differ diff --git a/public/vscode_change_branch_1.png b/public/vscode_change_branch_1.png new file mode 100644 index 00000000..9a63e5a9 Binary files /dev/null and b/public/vscode_change_branch_1.png differ diff --git a/public/vscode_change_branch_2.png b/public/vscode_change_branch_2.png new file mode 100644 index 00000000..ef1fe032 Binary files /dev/null and b/public/vscode_change_branch_2.png differ diff --git a/src/assets/migration-unit-test/unit_test_terminal_output.png b/src/assets/migration-unit-test/unit_test_terminal_output.png new file mode 100644 index 00000000..baea36ad Binary files /dev/null and b/src/assets/migration-unit-test/unit_test_terminal_output.png differ diff --git a/src/assets/thoth-logo.png b/src/assets/thoth-logo.png new file mode 100644 index 00000000..a90655e8 Binary files /dev/null and b/src/assets/thoth-logo.png differ diff --git a/src/assets/thoth-tech-logo-glow.png b/src/assets/thoth-tech-logo-glow.png new file mode 100644 index 00000000..5f7584e8 Binary files /dev/null and b/src/assets/thoth-tech-logo-glow.png differ diff --git a/src/content/config.ts b/src/content/config.ts index 9df91b60..c00ca6b7 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -1,7 +1,10 @@ -import { defineCollection } from 'astro:content'; -import { docsSchema, i18nSchema } from '@astrojs/starlight/schema'; +import { defineCollection } from "astro:content"; +import { docsSchema, i18nSchema } from "@astrojs/starlight/schema"; +import { docsAndBlogSchema } from "starlight-blog/schema"; export const collections = { - docs: defineCollection({ schema: docsSchema() }), - i18n: defineCollection({ type: 'data', schema: i18nSchema() }), + //og schema replaced with blog support one + //docs: defineCollection({ schema: docsSchema() }), + docs: defineCollection({ schema: docsAndBlogSchema }), + i18n: defineCollection({ type: "data", schema: i18nSchema() }), }; diff --git a/src/content/docs/Feedback/feedback-form.md b/src/content/docs/Feedback/feedback-form.md new file mode 100644 index 00000000..6f3b4552 --- /dev/null +++ b/src/content/docs/Feedback/feedback-form.md @@ -0,0 +1,41 @@ +--- +title: Feedback Form +description: A way to provide feedback +--- + +# We Value Your Feedback + +Thank you for taking the time to share your thoughts with us. Your feedback is crucial for helping +us improve and ensuring we continue to provide the best possible experience. + +## How to Provide Feedback + +You have several convenient options for submitting your feedback. Please choose the one that best +suits your preference: + +### Option 1: Fill Out Our Online Form + +Open an issue in our +[GitHub repository](https://github.com/thoth-tech/ThothTech-Documentation-Website/issues). It only +takes a few minutes and helps us understand your perspective. + +### Option 2: Contact Your Team Leader or Senior Students + +For specific feedback or concerns that require direct communication, please reach out to your team +leader or senior students. This ensures your feedback is addressed promptly and personally. + +--- + +## What Happens Next? + +Once you submit your feedback: + +- **Review:** Our team will review your feedback to understand your needs and concerns. +- **Plan:** We will plan improvements based on the feedback received from you and other users. +- **Implement:** We will strive to implement changes and improvements continuously to enhance your + experience. + +Your input is incredibly valuable to us, and we appreciate the effort you put into helping us +improve. If you have any immediate concerns, please contact our company operations team. + +Thank you for your contribution! diff --git a/src/content/docs/Products/OnTrack/01-start-contributing.md b/src/content/docs/Products/OnTrack/01-start-contributing.md new file mode 100644 index 00000000..c8872dda --- /dev/null +++ b/src/content/docs/Products/OnTrack/01-start-contributing.md @@ -0,0 +1,175 @@ +--- +title: Getting Started Contributing +sidebar: + label: "- Start Contributing" + order: 1 +--- + +### Ontrack Libraries + +The OnTrack system consists of a [Ruby On Rails](https://rubyonrails.org/) backend using the +[Grape API framework](https://github.com/ruby-grape/grape), and an +[Angular 17](https://v17.angular.io/docs) and [TailWindCSS](https://tailwindcss.com/) frontend. +Currently, the frontend is in the process of a migration from a [AngularJS](https://angularjs.org/) +and [Bootstrap 3.4](https://getbootstrap.com/docs/3.4/) to this new structure. + +### Version Control + +At ThothTech, we use Git as our version control system, with our repositories being stored on +GitHub. This allows for easily collaboration and code storage for such a large and complex system. +The OnTrack system is stored within 3 repositories: + +- [doubtfire-web](https://github.com/thoth-tech/doubtfire-web) contains the frontend +- [doubtfire-api](https://github.com/thoth-tech/doubtfire-api) contains the backend +- [doubtfire-deploy](https://github.com/thoth-tech/doubtfire-deploy) is used to manage deployments + and releases + +While working on the OnTrack system, you will mainly be operating within the doubtfire-web and +doubtfire-api repositories. + +These 3 linked repositories are owned by ThothTech and are the ones that you will fork to make your +changes. When your changes are approved, they will be merged into these repositories and can later +be merged upstream into the [doubtfire-lms](https://github.com/doubtfire-lms) series of +repositories. The doubtfire-lms repositories contain all changes that have been accepted. + +### Development Container + +While working with the OnTrack system, we use a development container. This container includes all +the previously listed repositories under one download, and enables you to easily run the OnTrack +system. Details on how to set up and run the development container can be found in the +[Doubtfire contributing guide](https://github.com/thoth-tech/doubtfire-deploy/blob/development/CONTRIBUTING.md). + +#### Running the Dev Container + +To run the dev container, first you must get the **Docker Engine** running and open the +**doubtfire-deploy** folder in a dev container using VS Code's Command Palette (ctrl / cmd + shift + +p) command `Dev Containers: Open Folder in Container...` + +Make sure the branch is development and the git remotes are configured properly. It should look +something like this for all 3 repos (doubtfire-deploy, doubtfire-web, doubtfire-api): + +![Git Remotes](/ontrack/contributing-guide/gitremotes.png) + +**Origin** should point to the **fork that you have created** and **upstream** should point to the +**Thoth Tech** repo + +#### Common errors during dev container setup + +##### 1. MySQL error in the backend + +![MySQL Backend Error](/ontrack/contributing-guide/mysqlerror.png) + +###### Solution + +Dev container related files are only located in the **development** branch under +**_.devcontainer_**. This means if you are on the wrong branch or your container doesn't recognise +the git repository, it won't find the dev container files and your container won't be configured +properly (your Configuring... terminal would show an error like shown below e.g. post_start.sh was +not found.) + +![Post Start Error](/ontrack/contributing-guide/poststarterror.png) + +On Windows, your Docker workspace won't recognise the git repository if you don't configure git to +mark the workspace as a safe directory. If you do a `git fetch` like shown below, git will alert you +of this and tell you which command to run to fix it. Copy paste that command and run it. After that, +you'll see the branch name in parenthesis as shown below in red. Do this for all 3 repos to mark +each directory as safe for git operations. + +![Git Fetch Example](/ontrack/contributing-guide/gitfetchexample.png) + +**Red** means there is a problem with your branch. Ideally the branch name should be in **green**. +To fix this, run `git reset --hard upstream/development` for each repo. This is assuming you have +fetched the latest changes for each repo using `git fetch` and you are on the development branch. +Run `git status` to make sure everything's up to date and there are no pending changes. + +Then without closing the remote connection to the container, rebuild the container using the Command +Palette command (ctrl / cmd + shift + p) `Dev Containers: Rebuild Container`. + +##### 2. Docker container related errors + +Firstly, make sure to check for pending updates for Docker. + +Now, sometimes if you are having any weird Docker container related problems such as shown below, +you might need to delete all **Containers, Images, and Volumes** related to +**doubtfire-lms/formatif** from inside the **Docker app** and restart the **Docker Engine**. + +![Docker Error](/ontrack/contributing-guide/dockererror.png) + +After you have restarted the docker engine, you can then open the **doubtfire-deploy** folder in VS +Code using the Command Palette command Dev Containers: Open Folder in Container... + +##### 3. Frontend not starting + +Typically, if the frontend fails to start it means that you are missing the required packages. This +can be resolved by opening a new terminal in the **doubtfire-web** directory and running the command +`npm install -f`. Once this command has finished running, run the command `npm start` to start the +frontend, which can usually be accessed at . + +##### 4. Wrong sign in page / frontend errors + +Errors that are encountered in the frontend typically show up as alerts that appear at the top right +of the page. + +![Incorrect sign in page](/ontrack/contributing-guide/incorrectsigninpage.png) + +Most of the time these will occur due to the backend not working as a result of a migration error, +which an example of is shown below: + +![Backend migration error](/ontrack/contributing-guide/backendmigrationerror.png) + +To fix this, enter the backend terminal and press **ctrl + c** to end the backend process. Once this +process has ended, create a new terminal in the doubtfire-api directory. Run the following commands +to fix the migration error and relaunch the backend: + +1. `bundle exec rake db:migrate` +2. `bundle exec rake db:populate` +3. `rails s` + +Reload the frontend once the backend server is up and running. The correct sign-in page like shown +below should appear. + +![Correct sign in page](/ontrack/contributing-guide/correctsigninpage.png) + +Login with username **student_1** and password **password** and enter **1** as the Student ID/number +and sign-in. The dashboard should appear with the enrolled units. + +### Documentation and Templates + +#### Documentation Repositories + +Currently, ThothTech has 2 documentation repositories: + +- [ThothTech/documentation](https://github.com/thoth-tech/documentation): For internal docs such as + new features being worked on and spike reports etc. +- [ThothTech/ThothTech-Documentation-Website](https://github.com/thoth-tech/ThothTech-Documentation-Website): + For external docs to introduce the products and policies to new students and assist onboarding. + +#### Templates + +While working on the system, you will often be required to write documentation prior to making +changes, such as component reviews for a migration, a spike when performing research or even for +submitting a pull request. Templates for each of these can be found below: + +- [Component Review Template](https://github.com/thoth-tech/documentation/blob/main/docs/Templates/Project-Templates/Component-Review.md) +- [Spike Plan Template](https://github.com/thoth-tech/documentation/blob/main/docs/Templates/SpikePlan-Template.md) +- [Spike Outcome Template](https://github.com/thoth-tech/documentation/blob/main/docs/Templates/SpikeOutcome-Template.md) + +### Your First Task + +Currently, the most beginner friendly tasks within the OnTrack system are frontend migrations. These +tasks will involve converting an old component that uses [AngularJS](https://angularjs.org/) and +[Bootstrap 3.4](https://getbootstrap.com/docs/3.4/) to a new component that uses +[Angular 17](https://v17.angular.io/docs) and [TailWindCSS](https://tailwindcss.com/). The guide for +how to perform a frontend migration can be found +[here](https://github.com/thoth-tech/doubtfire-web/blob/development/MIGRATION-GUIDE.md). + +These migration tasks will give you a good understanding of how the OnTrack system is structured and +will provide a good introduction on how to make changes to the system. + +Here's some resources which might help while working on migration tasks: + +- [Flex layout to tailwind migrations](https://blogs.halodoc.io/flex-layout-to-tailwind-migration/) +- [Flex directive equivalents in Tailwind](https://github.com/angular/flex-layout/issues/1426#issuecomment-1302184078) + +As always, if you run into any issues while working on OnTrack, feel free to reach out to others in +the team. We're always happy to help! diff --git a/src/content/docs/Products/OnTrack/02-set-up-dev.mdx b/src/content/docs/Products/OnTrack/02-set-up-dev.mdx new file mode 100644 index 00000000..7ec4675e --- /dev/null +++ b/src/content/docs/Products/OnTrack/02-set-up-dev.mdx @@ -0,0 +1,480 @@ +--- +title: OnTrack Development Environment Setup +sidebar: + label: "- Environment Setup" + order: 2 +--- + +Welcome to the comprehensive guide for setting up the OnTrack (Doubtfire) Development Environment. +Follow these steps carefully to ensure a smooth configuration. + +## Step 1: Overview + +In this tutorial, we will set up the OnTrack (Doubtfire) Development Environment. Ensure you are +familiar with the repositories, as you’ll be working with the Thoth-Tech versions, not the original +Doubtfire LMS repositories. + +--- + +## Step 2: Pre-Requisites + +Before proceeding, ensure the following are installed and set up: + +- **Docker**: Installed and running in the background. +- **Visual Studio Code (VS Code)**: Your code editor. +- **Git**: Installed for version control. +- **GitHub Account**: Required to fork and access repositories. + +--- + +## Step 3: Restart if Needed + +If you have faced errors in previous setup attempts, start from scratch. Follow this tutorial +step-by-step to avoid missing any crucial details. + +--- + +## Step 4: Accessing the Thoth-Tech Repository + +Navigate to the Thoth-Tech GitHub organization and locate these repositories: + +- **doubtfire-deploy** +- **doubtfire-api** +- **doubtfire-web** + +Make sure you are using the Thoth-Tech versions of these repositories. + +--- + +## Step 5: Fork the `doubtfire-deploy` Repository + +1. Open the `doubtfire-deploy` repository under Thoth-Tech. +2. Click on the **Fork** button in the top-right corner. +3. **Important**: Untick the checkbox for "Copy the main branch only" to include the development + branch. +4. Click **Create Fork**. + +--- + +## Step 6: Repeat for `doubtfire-api` and `doubtfire-web` + +Repeat the forking process for these repositories: + +- **doubtfire-api** +- **doubtfire-web** + +Ensure the development branch is included by unticking "Copy the main branch only". + +--- + +![Step ](images/image-one.PNG) + +## Step 7: Open the Terminal and Navigate to Your Folder + +1. Open a terminal (Command Prompt, PowerShell, or Terminal). +2. Use the `cd` command to navigate to the folder where you want to store the repository. Example: + +```bash +cd dev +``` + +--- + +## Step 8: Clone the Repository + +Clone the `doubtfire-deploy` repository along with its submodules: + +```bash +git clone --recurse-submodules https://github.com//doubtfire-deploy.git +``` + +Replace `` with your GitHub username. Example: + +```bash +git clone --recurse-submodules https://github.com/aditya993388/doubtfire-deploy.git +``` + +--- + +## Step 9: Wait for the Cloning Process + +The terminal will display the cloning progress for the repository and its submodules (e.g., +`doubtfire-api`, `doubtfire-overseer`, `doubtfire-web`). Wait until the process completes. + +--- + +![Step ](images/image-two.PNG) + +## Step 10: Navigate into the Cloned Repository + +Navigate into the cloned repository: + +```bash +cd doubtfire-deploy +``` + +--- + +## Step 11: Check Current Remote Settings + +Verify the current remote settings: + +```bash +git remote -v +``` + +Ensure only the `origin` is set, pointing to your forked repository. + +--- + +## Step 12: Add the Upstream Remote + +Add the upstream remote to point to the Thoth-Tech repository: + +```bash +git remote add upstream https://github.com/thoth-tech/doubtfire-deploy.git +``` + +This ensures that upstream points to the Thoth-Tech version, not the original LMS repository. + +--- + +![Step ](images/image-three.PNG) + +## Step 13: Verify Remote Settings + +Verify the upstream remote setup: + +```bash +git remote -v +``` + +Ensure both `origin` and `upstream` are listed correctly: + +- **Origin**: Points to your forked repository. +- **Upstream**: Points to Thoth-Tech’s repository. + +--- + +![Step ](images/image-four.PNG) + +## Step 14: Switch to the Development Branch + +By default, the repository is on the `main` branch. Switch to the `development` branch: + +```bash +git switch development +``` + +Verify the switch by running: + +```bash +git branch +``` + +The `*` symbol next to `development` confirms you are on the correct branch. + +--- + +![Step 15](images/image-five.PNG) + +### Step 15: Navigate to the Front-End Repository + +- Change your directory to the `doubtfire-web` sub-repository: + ```bash + cd doubtfire-web + ``` + +--- + +### Step 16: Check Current Remote Settings + +- Use the following command to view the current remote settings: + + ```bash + git remote -v + ``` + + - You should see `origin` pointing to the forked repository. + +--- + +### Step 17: Add the Upstream Remote + +- Add the upstream remote to point to the Thoth-Tech repository: + ```bash + git remote add upstream https://github.com/thoth-tech/doubtfire-web.git + ``` + +--- + +### Step 18: Verify the Upstream Remote + +- Run the following command again to confirm the upstream remote is configured correctly: + + ```bash + git remote -v + ``` + + - Ensure both `origin` and `upstream` are set properly. + +--- + +![Step 16](images/image-six.PNG) + +### Step 19: Update the Origin Remote URL + +- Update the `origin` to point to your forked repository: + + ```bash + git remote set-url origin https://github.com/aditya993388/doubtfire-web.git + ``` + + - This ensures that all your changes and pushes will go to your forked repository. + +--- + +![Step 17](images/image-seven.PNG) + +### Step 20: Verify Updated Remote URLs + +- Run the following command to check the updated remote settings: + + ```bash + git remote -v + ``` + + - Verify the following: + - **Origin**: Points to your forked repository + (`https://github.com/aditya993388/doubtfire-web.git`). + - **Upstream**: Points to the Thoth-Tech repository + (`https://github.com/thoth-tech/doubtfire-web.git`). + +--- + +![Step 18](images/image-eight.PNG) + +### Step 21: Switch to the Development Branch for doubtfire-web + +- Ensure you are working on the correct branch by switching to the `development` branch: + ```bash + git switch development + ``` +- Verify the branch by using: + + ```bash + git branch + ``` + + - The `*` symbol next to `development` confirms you are on the correct branch. + +### Step 22: Pull the Latest Updates for `doubtfire-web` + +- After switching to the `development` branch, pull the latest updates from the repository to ensure + you have the most recent changes: + + ```bash + git pull + ``` + + - This fetches and merges all updates from the `origin/development` branch. + +--- + +![Step 32](images/image-ten.PNG) + +### Step 23: Update the Git Origin for `doubtfire-deploy` + +- Navigate back to the `doubtfire-deploy` directory using the command: + ```bash + cd .. + ``` +- Check the current remote URLs with: + ```bash + git remote -v + ``` +- Notice that the `origin` URL might be missing the `.git` extension. +- Update the `origin` to include the `.git` extension using: + ```bash + git remote set-url origin https://github.com/aditya993388/doubtfire-deploy.git + ``` +- Verify the changes by running: + + ```bash + git remote -v + ``` + + - Ensure the `origin` now points to the correct URL with the `.git` extension. + +--- + +![Step 24](images/image-eleven.PNG) + +### Step 24: Perform a Git Pull and Configure Remotes for `doubtfire-api` + +- Ensure the `doubtfire-deploy` repository is up-to-date by running: + + ```bash + git pull + ``` + + - If it is already up to date, proceed. + +- Navigate to the `doubtfire-api` sub-repository: + ```bash + cd doubtfire-api + ``` +- Check the current remote URLs with: + + ```bash + git remote -v + ``` + + - At this stage, only the `origin` remote is configured. + +- Update the `origin` to point to your version of the `doubtfire-api` repository: + ```bash + git remote set-url origin https://github.com/aditya993388/doubtfire-api.git + ``` +- Add the `upstream` remote to point to the Thoth-Tech version of the `doubtfire-api` repository: + ```bash + git remote add upstream https://github.com/thoth-tech/doubtfire-api.git + ``` +- Verify that both `origin` and `upstream` are correctly configured: + + ```bash + git remote -v + ``` + + - Ensure `origin` points to your repository and `upstream` points to Thoth-Tech's repository. + +--- + +![Step 25](images/image-13.PNG) + +### Step 25: Accessing Dev Containers via VS Code + +- Exit the terminal and open Visual Studio Code (VS Code). +- Press `Command + Shift + P` (on Mac) or `Ctrl + Shift + P` (on Windows/Linux) to open the VS Code + Command Panel. +- In the Command Panel, search for **Dev Containers**. +- Select the option **Dev Containers: Open Folder in Container...** from the list. +- Before proceeding, ensure that Docker is running in the background. + ![Step 26](images/image-14.PNG) + +--- + +![Step 27](images/image-15.PNG) + +### Step 26: Reading Dev Container Configuration + +- Once the folder opens in the container, look for the **Reading Dev Container Configuration (show + log)** message in the bottom-right corner of VS Code. +- Click on **(show log)** to view the progress and ensure everything is being set up correctly. +- If it’s your first time setting up the container, expect the process to take some time as it + configures all necessary components. + +--- + +![Step 27](images/image-17.PNG) + +### Step 27: Running the Front-End and Back-End Applications + +- At this stage, the front-end application is running on the left terminal, while the back-end + (server) is active on the right terminal. +- Note: It's common to encounter errors during the first run of the front-end. These may relate to + missing dependencies or configuration conflicts. +- Review the error messages carefully. For issues like dependency conflicts, try resolving them with + appropriate commands such as `npm install` or check the error log paths mentioned in the terminal + for further details. + +--- + +![Step 28](images/image-18.PNG) + +### Step 28: Navigating to `doubtfire-web` and Resolving Dependencies + +- Open a new terminal window in your development environment. +- Use the command `cd doubtfire-web` to navigate into the `doubtfire-web` directory. +- Run the command `npm install -f` to forcefully install and resolve any missing dependencies for + the front-end application. + - This command ensures that all required packages are installed and any conflicting dependencies + are resolved. + +--- + +![Step 29](images/image-20.PNG) + +### Step 29: Run the Frontend + +- Run the frontend with npm: Open a terminal in the `doubtfire-web` directory and run: + + ```bash + npm start + ``` + + - This will build and run the frontend application. If successful, it will host the application + locally on port `4200`. ![Step 29](images/confirmation.PNG) + +- Confirmation Notification: Once the frontend is running, you will see a notification in the + bottom-right corner of your Visual Studio Code window indicating that the application is available + on `localhost:4200`. + +--- + +![Step 30](images/image-22.PNG) + +### Step 30: Verify the Running Application + +- Open the **Ports Panel** in Visual Studio Code to see all forwarded ports and their statuses. +- Locate the forwarded address for port `4200`. +- Hover over the address and click on the globe icon to open the application in your default + browser. + +![Step 32](images/image-23.PNG) + +- If everything is configured correctly, the OnTrack application login page will open in your + browser. + +--- + +![Step 31](images/image-24.PNG) + +![Step 31](images/image-25.PNG) + +![Step 31](images/image-26.PNG) + +### Step 31: Log In to OnTrack + +- Use the default credentials provided in the `CONTRIBUTING.md` file. Example: + - **Username**: `student_1` + - **Password**: Type any placeholder password as this is just for testing. +- Enter the credentials on the login page and click **Sign In** to log in successfully. + +--- + +![Step 32](images/image-27.PNG) + +![Step 31](images/image-28.PNG) + +![Step 31](images/image-29.PNG) + +### Step 32: Exploring the Dashboard + +- After logging in, you’ll be directed to the dashboard showing **Enrolled Units**. Examples: + - Introduction to Programming + - Object-Oriented Programming + - Artificial Intelligence for Games + - Game Programming + +- Interact with the dashboard by: + - Clicking on any enrolled unit to view details such as assignments and grades. + - Using the "Select Unit" dropdown in the top-left corner to switch between units. + +- **Progress Dashboard**: + - Inside each unit, review individual assignments (e.g., Pass Tasks, Distinction Tasks). + - Analyze your performance using tools like the **Burndown Chart**. + +--- + +Reach out to your mentors or attend the Help-Hub for any queries. diff --git a/src/content/docs/Products/OnTrack/03-planner-board.md b/src/content/docs/Products/OnTrack/03-planner-board.md new file mode 100644 index 00000000..a1f25795 --- /dev/null +++ b/src/content/docs/Products/OnTrack/03-planner-board.md @@ -0,0 +1,86 @@ +--- +title: "OnTrack Planner Board" +sidebar: + label: Planner Board + order: 3 +--- + +After reviewing the components in the doubtfire-web repository, the next step is to access the +OnTrack Planner Board to begin working on ongoing tickets. The planner board is used to manage and +track development tasks, including the migration process, feature additions, bug fixes, and other +project-related work. + +## Steps to Access and Work on Tickets + +### 1. Access the Planner Board + +- Open the OnTrack Planner Board in your web browser. +- The board is typically hosted on a project management tool like Jira, Trello, or GitHub Projects. + The link to the board should be provided in the project documentation or by the team. + + + +![alt text](/image-10.png) + +### 2. Navigate to the "Ongoing Tickets" Section + +- On the planner board, locate the "Ongoing" or "In Progress" column, where all active tickets are + listed. + +### 3. Review Ticket Details + +- Select a ticket assigned to you or one that matches your skill set. +- Each ticket will have the following details: + - **Title**: Describes the task (e.g., "Migrate alignment-bar-chart component to TypeScript"). + - **Description**: Provides context, goals, and steps for the task. + - **Acceptance Criteria**: Lists what needs to be completed for the ticket to be considered done. + - **Priority**: Indicates the urgency (e.g., High, Medium, Low). + - **Status**: Current progress (e.g., To Do, In Progress, Code Review). + +### 4. Assign the Ticket + +- If a ticket isn’t already assigned, assign it to yourself or notify the team lead. + +### 5. Start Working on the Ticket + +- Clone or pull the latest version of the repository associated with the ticket (e.g., doubtfire-web + or doubtfire-api). +- Create a new branch for the ticket using a standard naming convention (e.g., + feature/migrate-alignment-bar-chart). +- Begin working on the task following the migration or development guidelines. + + + +![alt text](/image-11.png) + +## Best Practices for Ticket Workflow + +- **Document Your Progress**: Add notes or comments to the ticket detailing your approach, + challenges, and updates. +- **Collaborate with the Team**: If you encounter any blockers, reach out to your team via Slack, + Teams, or other communication tools. +- **Follow Git Workflow**: Ensure you follow proper Git practices, such as rebasing, resolving + conflicts, and submitting pull requests (PRs) for code review. +- **Submit for Review**: Once the task is complete, push your branch and create a pull request + linked to the ticket. Notify the reviewers for feedback. + + + +![alt text](/image-12.png) + + + +![alt text](/image-13.png) + +## To start work on a new feature + +1. Make your changes in locally +2. Create a draft Pull Request and document the change you are working on. Doing this early will + make sure that you get feedback on your work quickly. +3. Complete your work, pushing to your fork's feature branch. This will update your existing PR (no + need to create new PRs) +4. Update the status of your PR removing the draft status, and flag someone in the Core team to + review and incorporate your work. +5. Address any changes required. Pushing new commits to your branch to update the PR as needed. +6. Once your PR is merged you can delete your feature branch and repeat this process for new + features... diff --git a/src/content/docs/Products/OnTrack/04-planner-board-etiquette.mdx b/src/content/docs/Products/OnTrack/04-planner-board-etiquette.mdx new file mode 100644 index 00000000..26b54a7b --- /dev/null +++ b/src/content/docs/Products/OnTrack/04-planner-board-etiquette.mdx @@ -0,0 +1,69 @@ +--- +title: Planner Board Etiquette +description: Tips on planner board etiquette. +sidebar: + label: "- Etiquette" + order: 4 +--- + +import { Steps } from "@astrojs/starlight/components"; + +## Proper Planner Board Etiquete + +The planner board is where all tasks are tracked. You can find tasks to claim and work on, or add +your own tasks that you will complete. Here are some guidelines to ensure smooth teamwork and +efficient use of the planner board. + + + +1. ### Claiming a Task + - **Commit to work:** Only claim a task if you are ready to work on it. + - **Unclaim if needed:** If you are unable to proceed with a task you've claimed, unclaim it so + others can take over. + - **Update status:** Once you claim a task, move it to the "Doing" column to signal that it's + being actively worked on. + +2. ### Adding a Task + - **Be clear and concise:** When adding a task, provide a meaningful title and a detailed + description. + - **Add checklists:** If the task involves multiple steps, include a checklist to outline them + clearly. + - **Use appropriate tags:** Tag the task with relevant labels to categorise it properly, such as + `Tutorials` if it's tutorial based, or `usage examples` if it's a usage example. + +3. ### Moving Tasks + - **Include relevant links:** When completing a task, attach links to the pull request (PR) and + any other relevant information. + - **Add a completion comment:** Leave a comment on the task card with the date you completed the + task. + - **Move to Peer Review:** After completing a task, move it to the "First Peer Review" column so + a team member can review it. + + > **Need help with pull requests?** + > Follow the [How to Create a Pull Request](/products/splashkit/04-pull-request) guide for + > detailed instructions. + +4. ### First Peer Review + - **Follow the review process:** Adhere to the steps outlined in the + [Peer Review Guide](/products/splashkit/06-peer-review). + - **Request changes if needed:** Provide feedback and request changes if required. + - **Approval:** Once the task meets the standards, approve it and the PR, then move the task to + the "Second Peer Review" column. + - **Leave a comment:** Add a comment with the date and confirmation that you've approved the + task. + +5. ### Second Peer Review + - **Follow similar steps:** Conduct the second peer review following the same guidelines as the + first. + - **Mentor Review:** After approving the PR, move it to the appropriate "Mentor Review" column. + - **Comment on approval:** As before, leave a comment with the date and a note indicating you've + approved the task for mentor review. + +6. ### Mentor Review + - **Final review:** The mentor will review the task and provide feedback. + - **Request changes:** If changes are needed, the mentor will request them and move the task back + to the "doing" column. + - **Approval:** Once the mentor approves the task, they will merge the PR and move the task to + the "completed" column. + + diff --git a/src/content/docs/Products/OnTrack/05-planner-board-guidelines.mdx b/src/content/docs/Products/OnTrack/05-planner-board-guidelines.mdx new file mode 100644 index 00000000..008cfe57 --- /dev/null +++ b/src/content/docs/Products/OnTrack/05-planner-board-guidelines.mdx @@ -0,0 +1,159 @@ +--- +title: Planner Board Guidelines +description: A guide on how to effectively use Planner Boards and Agile Cards in OnTrack. +sidebar: + label: "- Guidelines" + order: 5 +--- + +import { Steps } from "@astrojs/starlight/components"; + +## Overview + +Planner Boards are a vital part of managing tasks and ensuring smooth workflow in OnTrack projects. +This guide will walk you through how to work with Planner Boards, understand sprints, update task +cards, and maintain clarity on the importance of upstream reviews. + +![Overview of Planner Boards](images/overvieww.png "Planner Board Overview") + +## Why Planner Boards Matter + +Planner Boards play a crucial role in: + +- Reducing confusion about task updates and deadlines. +- Helping teams organize and prioritize work during sprints. +- Creating a transparent and collaborative environment for Agile development. +- Addressing common struggles with understanding sprints and timelines. + +## How to Work with Planner Boards + +Planner Boards are used to visually track the status of tasks throughout a sprint. Here’s how you +can work with them effectively: + +- **Columns**: Typically, boards have columns like _To Do_, _In Progress_, _Review_, and _Done_. + Each task card moves from left to right as work progresses. +- **Task Cards**: Represent individual tasks or stories. Cards include details like task + description, deadlines, and assignees. +- **Agile Focus**: Use the Planner Board to reflect the Agile methodology by splitting larger + stories into smaller, actionable tasks. + + +
    +
  1. + Open the Planner Board for your sprint. Click on Add Task and provide a clear + title and description. Assign the task to a team member and set a due date. ![Overview of + Planner Boards](images/moving.png "Planner Board Overview") +
  2. +
  3. + Drag and drop task cards to the appropriate column (*To Do*, *In Progress*, *Review*, *Done*). + Update the card’s status whenever significant progress is made. ![Overview of Planner + Boards](images/labels.jpg "Planner Board Overview") +
  4. +
  5. + Use Agile Cards to split work into smaller tasks for better sprint management. Add clear + labels (e.g., *Bug Fix*, *Feature*, *Testing*) to indicate the nature of the task. +
  6. +
+
+ +--- + +## How Sprints Work and Their Timelines + +Sprints are short, time-boxed periods where a specific set of tasks is completed. OnTrack follows +Agile principles to organize work into sprints. + +![Sprint Workflow](images/sprint.png "Sprint Workflow Diagram") + +### Key Points About Sprints + +- **Sprint Duration**: Usually 1–2 weeks, depending on project complexity. +- **Sprint Planning**: Conduct a meeting before each sprint to assign tasks and prioritize work. +- **Sprint Review**: At the end of a sprint, review completed work and gather feedback. + +### Sprint Workflow on Planner Boards + +1. **Before the Sprint**: + - Plan tasks and create cards in the _To Do_ column. + - Prioritize tasks based on team capacity and project goals. + +2. **During the Sprint**: + - Move cards from _To Do_ β†’ _In Progress_ β†’ _Review_ as work progresses. + - Communicate regularly during daily stand-ups to ensure alignment. + +3. **After the Sprint**: + - Move completed cards to the _Done_ column. + - Archive old boards and set up a new board for the next sprint. + +--- + +## How to Update Task Cards + +Keeping task cards up-to-date is essential to ensure transparency and progress tracking. + +### Steps to Update a Task Card: + +1. Open the task card you want to update. +2. Edit the following fields if necessary: + - **Status**: Update to reflect the current phase (e.g., _In Progress_, _Review_). + - **Assignee**: Reassign the task if the original assignee changes. + - **Description**: Add additional details or changes made. + - **Attachments**: Upload relevant files, like designs, test cases, or documentation. +3. Save the changes and notify team members if updates require their attention. + +--- + +## Reducing Confusion: Why and How to Update the Planner Board + +Proper use of the Planner Board eliminates misunderstandings regarding task ownership, deadlines, +and sprint goals. Here's why updating is critical: + +- **Transparency**: Keeps everyone informed about task progress. +- **Accountability**: Ensures team members are responsible for their assigned tasks. +- **Efficiency**: Reduces the need for repeated clarifications during meetings. + +### Tips for Regular Updates: + +- Schedule a daily check-in to update task statuses. +- Encourage all team members to take responsibility for keeping their cards current. +- Use tags or labels like _Blocked_, _Urgent_, or _Critical_ to highlight important tasks. + +--- + +## Understanding Upstream Reviews + +Upstream reviews ensure that pull requests (PRs) are aligned with project standards before merging. +This is closely tied to task cards in the Planner Board. + +![Upstream Review Process](images/git-workflow.png "Forking and Pull Request Workflow") + +### Steps for Upstream Reviews: + +1. **Connect PR to Planner Board**: + - Link the PR to the corresponding task card for tracking. + - Use comments in the card to summarize key changes in the PR. + +2. **Review Process**: + - Conduct a thorough code review (refer to the Peer Review Guide). + - Move the task card to _Review_ after the PR is created. + +3. **Finalizing**: + - Once the PR is approved, move the card to _Done_. + - Reflect any new insights or follow-up tasks on the Planner Board. + +--- + +## Planner Boards Across Semesters + +As OnTrack evolves, you may work with different Planner Boards in various semesters. To ensure +consistency: + +- **Semester Boards**: Use separate boards for each semester to track progress and goals. +- **Agile Alignment**: Ensure that Agile Cards are utilized for consistency across all boards. +- **Archiving**: Archive old boards to declutter and maintain focus on current work. + +--- + +By following these guidelines, you can use Planner Boards and Agile Cards effectively to stay +organized, work better as a team, and keep your project running smoothly while keeping your mentor +updated. diff --git a/src/content/docs/Products/OnTrack/06-pull-request-template.md b/src/content/docs/Products/OnTrack/06-pull-request-template.md new file mode 100644 index 00000000..7aa80bac --- /dev/null +++ b/src/content/docs/Products/OnTrack/06-pull-request-template.md @@ -0,0 +1,72 @@ +--- +title: Pull Request Template +description: This is a template for creating a pull request for OnTrack. +sidebar: + label: Pull Request Template + order: 6 +--- + +## Template for making a pull request + +When making a pull request to the Ontrack repository, please use the following template to ensure +that your pull request covers all the required steps and can be reviewed by your peers. The template +includes a checklist of items that you need to complete before submitting your pull request, some of +which may not be relevant to your specific pull request. Please ensure that you complete all the +relevant items before submitting your pull request. + +```markdown +# Description + +Please include a summary of the changes and the related issue. Please also include relevant +motivation and context. List any dependencies that are required for this change. + +## Type of change + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as + expected) +- [ ] Documentation (update or new) + +## How Has This Been Tested? + +Please describe the tests that you ran to verify your changes. Provide instructions so we can +reproduce. Please also list any relevant details for your test configuration. + +- [ ] Tested in latest Chrome +- [ ] Tested in latest Firefox +- [ ] npm run build +- [ ] npm run preview + +## Checklist + +### If involving code + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings + +### If modified config files + +- [ ] I have checked the following files for changes: + - [ ] package.json + - [ ] astro.config.mjs + - [ ] netlify.toml + - [ ] docker-compose.yml + - [ ] custom.css + +## Folders and Files Added/Modified + +Please list the folders and files added/modified with this pull request. + +- Added: + - [ ] folder/folder + - [ ] folder/folder +- Modified: + - [ ] folder/file + - [ ] folder/file +``` + +Please refer to Pull Request Guide for more information on creating a pull request. diff --git a/src/content/docs/Products/OnTrack/07-peer-review-web.mdx b/src/content/docs/Products/OnTrack/07-peer-review-web.mdx new file mode 100644 index 00000000..c298c6b4 --- /dev/null +++ b/src/content/docs/Products/OnTrack/07-peer-review-web.mdx @@ -0,0 +1,179 @@ +--- +title: Peer Review Guide +sidebar: + label: Peer Review Guide for Web Dev + order: 7 +--- + +import { Aside } from "@astrojs/starlight/components"; + +## Introduction on how to do a peer review within the Ontrack Web Dev Team + + + +In Ontrack, peer reviews are a vital process to ensure code quality, maintainability, and +consistency across the website development project. Every pull request (PR) must follow the +Peer-Review Checklist, which checks for key factors like functionality, code readability, and +documentation. + +Additionally, the Peer-Review Prompts serve as a conversation starter for reviewers, encouraging +collaboration while allowing for a thorough and constructive review process. + + + +### Ontrack Peer-Review Checklist + +The following checklist is required to be completed for every review to ensure high-quality +contributions. + +```plaintext +## General Information + +- [ ] Type of Change: Clearly indicate the type of change (choose one): + - [ ] Bug fix + - [ ] New feature + - [ ] Breaking change + - [ ] Documentation update + +## Code Quality + +- [ ] Repository: Ensure the PR is made to the correct repository. +- [ ] Readability: Is the code easy to read and follow? Are comments included where necessary? +- [ ] Maintainability: Can this code be maintained or extended easily in the future? + +## Functionality + +- [ ] Correctness: Does the code meet the task requirements? +- [ ] Existing Functionality: Has the impact on existing functionality been considered and tested? + +## Testing + +- [ ] Test Coverage: Are unit tests provided for new or modified code? +- [ ] Test Results: Have all tests passed successfully? + +## Documentation + +- [ ] Documentation: Is the inline and external documentation updated and clear? + +## Pull Request Details + +- [ ] PR Description: Is the problem being solved clearly described? +- [ ] Checklist Completion: Have all relevant checklist items been reviewed and completed? +``` + +### Ontrack Peer-Review Prompts + +- **General Information**: + - [ ] Type of Change: Clearly indicate the type of change (choose one): + - [ ] Bug fix + - [ ] New feature + - [ ] Breaking change + - [ ] Documentation update + +- **Code Quality**: + - [ ] Repository: Ensure the PR is made to the correct repository. + - [ ] Readability: Is the code easy to read and follow? Are comments included where necessary? + - [ ] Maintainability: Can this code be maintained or extended easily in the future? + +- **Functionality**: + - [ ] Correctness: Does the code meet the task requirements? + - [ ] Existing Functionality: Has the impact on existing functionality been considered and tested? + +- **Testing**: + - [ ] Test Coverage: Are unit tests provided for new or modified code? + - [ ] Test Results: Have all tests passed successfully? + +- **Documentation**: + - [ ] Documentation: Is the inline and external documentation updated and clear? + +- **Pull Request Details**: + - [ ] PR Description: Is the problem being solved clearly described? + - [ ] Checklist Completion: Have all relevant checklist items been reviewed and completed? + +--- + +## OnTrack Peer-Review Prompts + +Use these prompts to guide discussions and ensure high-quality code contributions: + +- **Type of Change**: Is the PR correctly identifying the type of change (bug fix, new feature, + etc.)? +- **Code Readability**: Is the code well-structured and easy to follow? Could better comments, + names, or organization improve it? +- **Maintainability**: Is the code modular and easy to maintain? Does it introduce any technical + debt? +- **Code Simplicity**: Are there redundant or overly complex parts of the code that could be + simplified? +- **Edge Cases**: Does the code account for edge cases? What scenarios might cause it to break? +- **Test Thoroughness**: Does the testing cover all edge cases and failure paths? Are there enough + tests to ensure code reliability? +- **Backward Compatibility**: Does the change break any existing functionality? If so, is backward + compatibility handled or documented? +- **Performance Considerations**: Could this code impact performance negatively? Can it be optimized + while maintaining readability? +- **Security Concerns**: Does this change introduce any security risks? Is input validation handled + properly? +- **Dependencies**: Are new dependencies necessary? Could they conflict with existing libraries? + Could this functionality be achieved without new dependencies? +- **Documentation**: Is the documentation clear and thorough enough for new developers to + understand? Does it cover API or external interface changes? + +--- + +## Review Guidelines for Specific File Types + +### `.mdx` Files + +- **Content Accuracy**: Ensure that the content is clear and accurate. Double-check for any errors + in documentation or guides. +- **Frontmatter**: Ensure the frontmatter (`title`, `description`, etc.) is correctly filled out. +- **Component Usage**: Verify that components like `LinkCard` or `CardGrid` are used appropriately + within `.mdx` files. + +### `.css` Files + +- **Consistency**: Check alignment with the **Styling Guide** and consistent use of variables (e.g., + colors, fonts, spacing). +- **Accessibility**: Ensure animations respect user preferences, and contrast ratios meet **WCAG 2.1 + AA** standards. +- **Naming Conventions**: Verify CSS class names follow consistent patterns. + +### `.jsx`/`.tsx` Files + +- **Functionality**: Validate that interactive components (e.g., forms, sliders) work as expected + and meet task requirements. +- **Performance**: Identify unnecessary re-renders or performance concerns. +- **Code Style**: Ensure compliance with **React/JSX** best practices and linting rules. + +### `.astro` Files + +- **Structure**: Verify page/component structure aligns with **Astro standards**. +- **Reusability**: Look for repetitive code that could be refactored into reusable components. + +--- + +## Useful Resources for Reviewers + +- **Starlight Documentation**: [Starlight Docs](https://starlight.astro.build/getting-started/) +- **Astro Documentation**: [Astro Docs](https://docs.astro.build/en/getting-started/) +- **WCAG 2.1 AA Guidelines**: [W3C Accessibility Standards](https://www.w3.org/WAI/WCAG21/quickref/) +- **MDN CSS Documentation**: [MDN CSS Guide](https://developer.mozilla.org/en-US/docs/Web/CSS) +- **React Documentation**: [React Official Docs](https://reactjs.org/docs/getting-started.html) + +--- + +By following these guidelines, you’ll help maintain high standards of code quality, performance, and +accessibility in the OnTrack project. Peer reviews not only ensure the quality of the code but also +foster collaboration and shared learning among the team. diff --git a/src/content/docs/Products/OnTrack/Documentation/Deployment/Enhanced_Authentication/LDAP-and-devise-research-documentation.md b/src/content/docs/Products/OnTrack/Documentation/Deployment/Enhanced_Authentication/LDAP-and-devise-research-documentation.md new file mode 100644 index 00000000..c48696fa --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Deployment/Enhanced_Authentication/LDAP-and-devise-research-documentation.md @@ -0,0 +1,270 @@ +--- +title: Research Documentation:LDAP Server & Devise +--- + +[Introduction](#introduction) + +[Research Aims](#research-aims) + +[Research Findings](#research-findings) + +- [LDAP Servers](#ldap-servers) +- [Devise](#devise) +- [Devise LDAP Authentication](#devise-ldap-authentication) +- [Angular (TypeScript) UI & Devise Integration](#angular-typescript-ui--devise-integration) +- [Devise LDAP Server Setup & Integration](#devise-ldap-server-setup--integration) + +[Research Outcomes](#research-outcomes) + +[Reference List](#reference-list) + +[Links to Relevant Resources](#links-to-relevant-resources) + +--- + +## Introduction + +The current distribution of OnTrack supports numerous authentication methods, but all such methods +use external resources to provide the authentication services. As such, it has been proposed that a +**Lightweight Directory Access Protocol (LDAP) server** be created and added to the current Docker +container mix used for OnTrack. This would allow hosting and testing of the LDAP server’s +authentication capabilities. How to implement an LDAP server to suit these needs, however, is +uncertain. + +Within this, it has been suggested that **Devise**, an authentication solution that can be +integrated with LDAP server, could be used as part of achieving this goal of creating an in-house +authentication methodology. There are also Devise modules that are already configured to work +seamlessly with an LDAP server setup. However, it is uncertain whether Devise is needed to achieve +the full goals of the Enhance Authentication team (as outlined on the team Trello Card) and whether +Devise can be used without its Ruby on Rails-based UI (as OnTrack makes use of Angular on the +frontend to communicate with the backend). + +Hence, it is clear that there needs to be some research conducted into the LDAP servers and Devise +to determine the best course of action when integrating these features into the pre-established +OnTrack architecture. + +--- + +## Research Aims + +The aims of this research and its concurrent documentation are as follows: + +1. Gain a better understanding of what an LDAP server is; +2. Understand how an LDAP server could be used to reach our in-house authentication goals; +3. Gain a better understanding of what Devise is and what services it provides; +4. Gain insight into how a Devise LDAP server would be set up and integrated into the current + OnTrack architecture, including adding it to the Docker container mix; +5. Determine whether Devise’s use of a Ruby on Rails UI will impede the ability to utilise it, given + that OnTrack’s frontend uses Angular and communicates with the backend via the Application + Programming Interface (API); +6. If (from _Research Aim 5_) it is determined that Devise **_can_** be used with the current + OnTrack frontend and backend setup, investigate how it will be set up and integrated. + +--- + +## Research Findings + +### LDAP Servers + +A Lightweight Directory Access Protocol server facilitates client-server queries of directories over +the TCP/IP Internet protocol [1]. Similar to a database, the directories stored by the LDAP database +contain attribute-based information which can be queried by clients and responded to by the server +to achieve information-checking goals [1]. In the case of the OnTrack system, the LDAP server would +store relevant user details which would be queried by clients in order to approve or deny the +specific user access to the OnTrack systems – providing an authentication system. + +The LDAP protocol allows for the following operations to be conducted within the database/directory +accessed by the LDAP server [2]: + +- Add: Adds new files and/or entries; +- Delete: Removes files and/or entries; +- Search: Query the files and entries; +- Compare: Determine the similarities and differences between files; and +- Modify: alter an existing file/entry. + +All of these operations are essential to adding the appropriate user details which are used during +the OnTrack authentication process. Additionally, the lightweight nature of LDAP and directories +results in the ability to handle high volumes of traffic and quick response times to client-server +queries [1] [2]. These two elements of LDAP servers make it ideal for the OnTrack authentication +process, especially due to the high number of users of the service. + +Hence, an LDAP server could be utilised to achieve our in-house authentication goals through: + +- Utilising the current user information database or creating a new database purely for + authentication queries. +- Coding the LDAP server to respond to client requests for access to the systems by accessing the + user information database and cross-referencing the details provided by the client and those + stored in the database, giving appropriate responses based on whether the data matches (success – + the user has been authenticated and access can be provided) or whether the data is mismatched + (failure – the user is unable to be authenticated and access is denied). +- The creation and use of the LDAP server results in the OnTrack authentication process becoming + fully independent – meeting the primary authentication goal of in-house authentication. + +### Devise + +Devise is a module-based authentication solution created in the Ruby on Rails programming language +[3]. Taken directly from the [Devise GitHub Repo] (), the 10 +modules within Devise are outlined by the creators as follows: + +> - Database Authenticatable: hashes and stores a password in the database to validate the +> authenticity of a user while signing in. The authentication can be done both through POST +> requests or HTTP Basic Authentication. +> - Omniauthable: adds OmniAuth () support. +> - Confirmable: sends emails with confirmation instructions and verifies whether an account is +> already confirmed during sign in. +> - Recoverable: resets the user password and sends reset instructions. +> - Registerable: handles signing up users through a registration process, also allowing them to +> edit and destroy their account. +> - Rememberable: manages generating and clearing a token for remembering the user from a saved +> cookie. +> - Trackable: tracks sign in count, timestamps and IP address. +> - Timeoutable: expires sessions that have not been active in a specified period of time. +> - Validatable: provides validations of email and password. It's optional and can be customized, so +> you're able to define your own validations. +> - Lockable: locks an account after a specified number of failed sign-in attempts. Can unlock via +> email or after a specified time period. (Source: +> [Devise GitHub Repo](https://github.com/heartcombo/devise)) + +Hence, the Devise authentication solution provides a wholistic authentication service, one which +would be highly suitable to meet the OnTrack authentication goals. + +### Devise LDAP Authentication + +Devise can be used concurrently with LDAP servers to provide complete authentication solutions. In +fact, GitHub user Curtis Schiewek has already created an integrated Devise LDAP authentication +solution called [Devise LDAP Authenticatable] +(). Devise LDAP Authenticatable is a +plugin which allows for the services of Devise to be used with a pre-existing LDAP server (which we +aim to create) and in line with the Devise framework [4]. However, due to this plugin making use of +the Ruby on Rails programming within Devise, it must first be determined if Devise (and, hence, the +Devise LDAP Authenticatable) can be used as part of the OnTrack architecture. + +Devise utilises Ruby on Rails (shortened to β€œRails”) as the language framework for the web +applications user interface (UI) that use its authentication services [4]. As such, the credentials +entered into the Rails UI would be those which are authenticated by the Devise back-end +authentication service; the communication is Rails-to-Rails [4]. However, the OnTrack architecture +currently utilises the AngularJS programming language as the framework for the web application +front-end UI, making use of a Rails-based API to communicate with the backend. Additionally, there +is a current migration underway within the OnTrack architecture which will result in the change from +utilising AngularJS to having the UI programmed using Angular (TypesScript). + +As such, a solution to the UI/backend communication based on AngularJS would be redundant due to +this language migration occuring, especially as the Devise LDAP server would likely not be ready to +implement until after the conclusion of this migration. Hence, the research conducted needs to +determine the following: whether it is possible to utilise the Rails-based authentication services +of Devise within an Angular (TypeScript) UI and Rails API architecture. + +### Angular (TypeScript) UI & Devise Integration + +From extensive research regarding _if_ and, if it can, _how_ Devise can be used in an application +architecture which has an Angular (TypeScript) UI, it was found that **there are solutions available +to facilitate this**. + +There are numerous token-based authentication solutions available through GitHub which enable Devise +to communicate with a variety of programming languages which may be used within the architecture of +applications. Of relevance to our proposed implementation are the +[Devise Token Auth](https://github.com/lynndylanhurley/devise_token_auth) and +[Angular Token](https://github.com/neroniaky/angular-token) GitHub repositories. Devise Token Auth +implements a token-based method of authentication for use with Devise, its functionalities being +able to be harnessed through referencing the solution within the appropriate Gemfile [5]. This type +of token-based authentication can be implemented as part of our solution to meet the authentication +goals. More importantly, Angular Token works to facilitate communication between Angular +(TypeScript) solutions and the Rail-based services of Devise [6]. It seamlessly works in conjunction +with the Devise Token Auth service, with the Devise Token Auth repository even providing a demo of +these two solutions successfully integrated [5] [6]. + +Hence, to facilitate the communication between OnTrack’s Angular (TypeScript) UI and the Rails-based +services of Devise, it is suggested that these two token-based authentication solutions be +integrated within the application architecture as demonstrated in the β€˜Setup’ sections of their +respective repositories. + +### Devise LDAP Server Setup & Integration + +The following briefly outline the steps that will be involved in setting up and implementing the +Devise LDAP server authentication solution as part of the OnTrack architecture: + +- Run the [OpenLDAP Docker image](https://github.com/osixia/docker-openldap) and follow the + instructions for setting up a new LDAP server. OpenLDAP has been selected due to it being + open-source, reliable, and also its being used as part of the Devise LDAP Authenticatable solution + which we will also be using. Additionally, using a Docker image of an OpenLDAP server which allows + for the creation of new LDAP servers suited to the needs of the company will allow for development + to begin with a solid base and make adding the authentication server solution to the Docker + container mix easier; +- Setup and perform an initial configuration of [Devise](https://github.com/heartcombo/devise) + through adding it to the appropriate Gemfile and following the instructions detailed in the + [Devise README.md] () file; +- Setup and perform an initial configuration of [Devise LDAP Authenticatable] + () through following the processes + outlined in the + [Devise LDAP Authenticatable README.md](https://github.com/cschiewek/devise_ldap_authenticatable/blob/default/README.md) + file; +- Initially configure and integrate both the + [Devise Token Auth](https://github.com/lynndylanhurley/devise_token_auth) and + [Angular Token](https://github.com/neroniaky/angular-token) token-based solutions by following the + installation and configuration information detailed in their respective README.md files: + found[here]( \_token_auth/blob/ master/README.md) and + [here](https://github.com/neroniaky/angular-token/blob/master/README.md); +- Finish the configuration of these elements by populating them with real data and integrating the + elements into the OnTrack architecture, ensuring that they all communicate correctly and respond + as expected. + +As the OpenLDAP server created is drawn from a Docker Image, it is thought that this will simplify +the process of adding the finished server to the Docker container mix used for the OnTrack +deployment. + +Again, this is a very high-level view of the expected setup and integration flow of how the Devise +LDAP server will be developed. As upskilling surrounding these technologies and their respective +code/languages is conducted, this methodology may be made redundant or be found to have missing +items. However, this will be the current basis of how development will occur for now. + +--- + +## Research Outcomes + +Through an examination of the Research Findings documented, understandings of what LDAP servers are +and how they work; what Devise is and what services it offers; and how LDAP and Devise can be +harnessed to provide an authentication solution have been vastly improved. + +Most importantly, from this conducted research, it has been found that **Devise can be used as part +of the OnTrack in-house authentication solution**. As previously detailed, two token-based services +work to facilitate communication between OnTrack’s Angular UI and Devise’s Rails-based and, as such, +integrating these services will allow for the use of Devise within our authentication solution. + +A high-level overview of how the Devise LDAP server solution will be developed has also been given. +However, as mentioned, future upskilling into the practical elements of these technologies may +result in the actual implementation methodologies being found to be much different. However, as +determining whether Devise can be used _at all_ was deemed to be the most important aspect of this +research (as it impacts all other aspects of developing the in-house authentication solution), such +a broad overview will be sufficient for now. + +--- + +## Reference List + +[1] L.E.P. MalΓ¨re (2007, Mar. 18). What's LDAP? [Webpage]. Available: + + +[2] Okta (n.d.). What Is LDAP & How Does It Work? [Webpage]. Available: + + +[3] heartcombo (n.d.) Devise [GitHub repository]. Available: + +[4] C. Schiewek (2020, Jul. 24). Devise LDAP Authenticatable [GitHub repository]. Available: + + +[5] L. D. Hurley (n.d.). Devise Token Auth [GitHub repository]. Available: + + +[6] J. P. Riethmacher (n.d). Angular Token [GitHub repository]. Available: + + +--- + +## Links to Relevant Resources + +- [Trello card containing aims for the Enhance Authentication team](https://trello.com/c/WeElomXn/6-enhance-authentication) +- [GitHub repo for Devise](https://github.com/heartcombo/devise) +- [GitHub repo for a Devise LDAP authentication module](https://github.com/cschiewek/devise_ldap_authenticatable) +- [GitHub repo for Devise Token authentication solution](https://github.com/lynndylanhurley/devise_token_auth) +- [GitHub repo for Angular UI token integration with Devise (to be used in conjunction with Devise Token Auth)](https://github.com/neroniaky/angular-token) +- [GitHub version of Docker image which can be used to create an OpenLDAP server](https://github.com/osixia/docker-openldap) diff --git a/src/content/docs/Products/OnTrack/Documentation/Deployment/Enhanced_Authentication/current-and-proposed-authentication-evaluation-5.1.md b/src/content/docs/Products/OnTrack/Documentation/Deployment/Enhanced_Authentication/current-and-proposed-authentication-evaluation-5.1.md new file mode 100644 index 00000000..030efeeb --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Deployment/Enhanced_Authentication/current-and-proposed-authentication-evaluation-5.1.md @@ -0,0 +1,162 @@ +--- +title: Review of Current and Proposed Authentication Solutions +--- + +[Overview](#overview) + +[The State of the Current Authentication Mechanisms](#the-state-of-the-current-authentication-mechanisms) + +- [The Current Authentication Setup](#the-current-authentication-setup) +- [Risks and Issues](#risks-and-issues) + +[Proposed Authentication Enhancements](#proposed-authentication-enhancements) + +- [The Proposed Authentication Mechanism](#the-proposed-authentication-mechanism) +- [Advancements of the Previous Authentication Mechanisms and how it Addresses Issues of the Old + Method] + (#advancements-of-the-previous-authentication-mechanisms-and-how-it-addresses-issues-of-the-old-method) +- [Potential Issues and Concerns that must be Considered](#potential-issues-and-concerns-that-must-be-considered) + +## Overview + +The purpose of this documentation is to formally review the current authentication mechanisms which +are in place within the OnTrack architecture and compare this to the proposed authentication +solution in development by the Deployment project team (Enhance Authentication). Within this +evaluation, the current authentication setup and mechanisms will be described, and then analysed in +terms of the risks and issues encompassed within such a setup. The new authentication solution which +is proposed to be developed and implemented will then be described, analysing how this new system +aims to advance the authentication capabilities of its predecessor and how it will work to mitigate +the risks and issues of the current system which it will replace. Additionally, the issues and +concerns which may develop as a result of the implementation of the proposed authentication system +will be examined, including the regulatory and compliance considerations which must be addressed +during the development of the new system. + +## The State of the Current Authentication Mechanisms + +### The Current Authentication Setup + +Currently, the OnTrack system relies upon the authentication provided by its client, Deakin +University. The authentication mechanism utilised by Deakin University is a Single Sign On (SSO) +system which utilises Multi-Factor Authentication (MFA) technology through _Duo Security_. As part +of the SSO process, the user is prompted to enter their username and password to log in to the +Deakin SSO system and, as such, to allow access to OnTrack. Once the username and password have been +verified, the MFA system requires the user to confirm that they are the rightful owner of the +account through responding to a β€œlogin request” sent to their allocated personal device. Once this +test is passed, access is granted to the OnTrack system. In the case where the user is already +logged in to Deakin SSO, has been accessing other Deakin services and then chooses to visit the +OnTrack site, they are automatically logged in through the SSO functionality. Hence, the current +authentication system is reliant upon third-party authentication, whose MFA capabilities have been +outsourced (to Duo Security). + +### Risks and Issues + +An analysis of the current authentication system presented the following issues and risks: + +As OnTrack relies upon Deakin SSO services, it is assumed that both the login and logout +functionalities would be handled by this service. However, even after a user has logged out Deakin +SSO and (supposedly) all concurrent accounts accessed through the single login, a user’s OnTrack +account remains logged in and accessible for a period of days (perhaps weeks). This security flaw +means that the token used to access the OnTrack account first through the Deakin SSO technology +continues to be stored within the user’s browser for an extended time period, allowing the OnTrack +account to be repeatedly accessed even when the user is not currently signed in to Deakin SSO. For +cases where the user is on a shared computer, this is a high risk for unfiltered access into the +user’s account by other actors. Currently, the only method to properly sign out of the OnTrack +system is for a user to select their avatar icon and, from the displayed drop-down menu, to choose +β€œsign out” from there. This is often overlooked, especially as it would be assumed that the logout +process would be handled by Deakin SSO services. Even when the user does follow the OnTrack process +to sign out of the account, the user is redirected to a broken link where the page cannot be +displayed – the token is cleared from the browser. Although this does solve the issue at hand, it is +not an ideal user experience + +A second risk is that this current method of authentication relies on third-party and outsourced +authentication technologies. Deakin SSO and MFA is facilitated by Duo Security, although these +technologies may be highly efficient, secure and reliable, such a reliance on third-party software +means that the backend workings of this software is not able to be accessed and understood by the +OnTrack team. Additionally, use of third-party software requires additional sharing, transmission, +and storage of user information on systems which are not able to be managed by the OnTrack team. In +the case of a security breach, the OnTrack team are also forced to rely upon the providers of these +technologies to: + +- Report that the breach happened +- Report which details and systems have been compromised +- Fix the issues which lead to the breach +- Secure the system and continue normal business operations + +Having to rely upon other vendors for these processes removes the control and information +transparency OnTrack has regarding the scale and nature of security breaches. This leaves the +company β€œin the dark” about what has occurred and is frustrating, especially when there are capable +members within the company who would be able to respond to such events, perhaps more efficiently +than these vendors. + +Hence, from these risks and issues associated with the current OnTrack authentication mechanisms, it +is clear why new technologies and methods of authentication have been proposed to be developed and +implemented. + +## Proposed Authentication Enhancements + +This section will detail the proposed authentication elements to be added to the OnTrack +architecture in order to improve the state of the authentication mechanisms and to alleviate some of +the risks and errors in the described current setup. + +### The Proposed Authentication Mechanism + +The proposed solution to be implemented by the Enhance Authentication team has several elements, as +follows: + +- An extension of the current OnTrack API, adding functionality to facilitate user management +- Password management features, for users and admin manipulation. Users can either send a request to + the admin to authorise the password or do so themselves. It is important that, as part of this + feature, the admin is able to manipulate the password (i.e. send the request for a password + change). The password is never transferred in plaintext at any time during this process. +- A Devise LDAP server option which handles the authentication processes for OnTrack, allowing the + authentication to be performed fully β€œin-house” rather than outsourced to other authentication + mechanisms. + +### Advancements of the Previous Authentication Mechanisms and how it Addresses + +### Issues of the Old Method + +From the proposed elements to be added to the authentication mechanisms, the following advancements +and addressing of issues relevant to the current system are achieved: + +| Element | Advancement | +| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| User Password Management | Allows for users to change passwords themselves to something more secure and/or easier to remember (though it is important that proper password policies, practices and recommendations are followed), rather than being forced to use the same password set for their Deakin account. By changing the password for OnTrack, this follows recommended password procedures which suggests that passwords should not be reused across various accounts | +| User Password Management | Allows users to request a password change from the administrator in the event that they have forgotten their password and cannot gain access to their account. This is a useful feature for account management and access, ensuring that users are able to regain access to their account swiftly and easily | +| Additional API User Management Functions | Improves upon the current authentication setup through allowing more user qualities to be managed independently by the admins and, for some features, by the users themselves. Overall, this adds additional flexibility and ease of change for certain parameters or information | +| LDAP Devise Server | Allows the OnTrack system to have its own in-house authentication mechanisms with complete control over how it is set up, integrated, and deployed. As the current authentication mechanism relies on third-party β€œSingle Sign On” (SSO) authentication protocols provided by Deakin University, OnTrack is limited to utilising the mechanisms provided by this third-party system. Developing an in-house authentication solution using LDAP and Devise results in the OnTrack architecture being fully independent, and allows for additional sign-in options to be added in future (for example, using a Google Account to sign in) | +| LDAP Devise Server | Allows for the authentication systems to be fully managed by the OnTrack team, allowing for complete control over the code and features included as part of the authentication processes. This is an improvement as reliance on third-party software or processes in any circumstance increase the difficulty in understanding how the systems operate and what has occurred in the instance of an error or breach. Having an independent authentication solution streamlines the control and medication of the services provided by it, allowing for access and control to be granted solely to the OnTrack team on the backend of the project. In this way, the LDAP and Devise features used can be customised to suit the specific (and changing) needs of the OnTrack system, using only features that are necessary and relevant to the OnTrack system and user authentication needs, rather than accepting all services provided by third-party authentication mechanisms | +| LDAP Devise Server | As stated, the OnTrack team will be granted full control over the authentication systems and elements of the OnTrack software. This will solve the issue of the redirection to the broken Deakin SSO link as explored in previous sections, as the team will be able to control the flow towards other pages after the successful signing out of a user | + +### Potential Issues and Concerns that must be Considered + +Within the development and deployment phases related to implementing these proposed authentication +mechanisms, the following must be closely considered and addressed: + +- It must be ensured that, while system admins have the ability to grant access to change the + passwords, that they cannot directly access the passwords themselves. There must be a clear + separation of information, and passwords must have secure encryption applied to them. +- Password change requests must be validated to ensure that they are coming from the user, and not + someone pretending to be the user in order to gain control over the account. A security mechanism + such as requiring the requestee’s date of birth, or an answer to a security question set by the + user, is suggested. Additionally, sending an automatic email or text to inform the user of the + request for a change of password is also recommended +- The developed authentication system, including how user information is stored, transmitted, and + later deleted (which includes considerations of retention laws) must adhere to the appropriate + laws and guidelines set out by the Australian Federal Government (including the _Privacy Act + 1988_), as well as other specifications mandated within each of the Australian states and + territories. +- Additionally, as OnTrack provides its services to international users (both in terms of + international students studying online at Deakin and through providing its services to + international clients), OnTrack’s authentication and information storage processes must also + adhere to the laws enacted within the relevant international jurisdictions. For example, the data + protection laws enacted within the GDPR must be adhered to by companies who provide services to + citizens protected under the GDPR, regardless of where the company is situated (see + )。 +- Finally, as all code used within the OnTrack architecture is open-source and publicly available + through the Thoth Tech company site, how this effects the security of the proposed authentication + system once developed and added to the site must be considered. Specifically, it must be examined + whether public access to the internal workings of the authentication system increases the threat + of a data breach as anyone can view the code, find vulnerabilities, and then create exploits to + leverage such vulnerabilities. Hence, it is recommended that thorough vulnerability analysis is + conducted on the code and systems to be included within the proposed authentication solutions。 diff --git a/src/content/docs/Products/OnTrack/Documentation/Deployment/Enhanced_Authentication/testing-strategy-enhance-authentication.md b/src/content/docs/Products/OnTrack/Documentation/Deployment/Enhanced_Authentication/testing-strategy-enhance-authentication.md new file mode 100644 index 00000000..a3af5afe --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Deployment/Enhanced_Authentication/testing-strategy-enhance-authentication.md @@ -0,0 +1,127 @@ +--- +title: Testing Strategy for Enhance Authentication +--- + +[Introduction](#introduction) + +[Overview of Deliverables to be Tested](#overview-of-deliverables-to-be-tested) + +[References](#references) + +[Test Management](#test-management) + +[Scope of Testing](#scope-of-testing) + +--- + +## Introduction + +This testing strategy describes the features and artifacts that the Enhance Authentication team will +be contributing to the OnTrack architecture, particularly focusing on the specifics regarding the +testing of these elements once developed. Conducting testing according to this Testing Strategy is +paramount to ensure that the created elements are functioning as expected before they are added to +the main OnTrack GitHub repository and associated Docker containers for deployment. + +## Overview of Deliverables to be Tested + +As part of the development of elements conducted by the Enhance Authentication team, the following +features will be created and will require testing: + +- Extend the current features within the OnTrack API to allow for user management to be achieved +- Add a feature to allow users and admins to change user passwords, facilitating users being able to + request admin to change the user’s password due to it being forgotten +- Add a Devise LDAP server option to facilitate in-house authentication of users of the OnTrack + system + +These features, once functioning, will be the deliverables of the Enhance Authentication team. +Additionally, this testing strategy will also be a deliverable, as will any research documentation +conducted in the process of implementing these features. + +## References + +The following resources are relevant to the work that is to be done by the Enhance Authentication +team. + +Links to resources used for as part of development and testing: + +- GitHub: +- Visual Studio Code: +- Docker: + +Links to the relevant OnTrack repositories which will be accessed and altered by the team to +implement the new authentication features: + +- Doubtfire-Web: +- Doubtfire-Deploy: +- Doubtfire-API: + +Links to resources describing the coding languages used: + +- Ruby-on-Rails for updating of the API to add new features: +- Angular/Typescript for front-end development: + +Links to resources relevant to the Devise LDAP server: + +- GitHub repo for Devise: +- GitHub repo for a Devise LDAP authentication module: + +- Research documentation regarding how to implement the server solution: + + Deployment/Enhanced%20Authentication/Research%20%26%20Findings/LDAP-and-devise-research-documentation.md + +## QA Deliverables + +As part of the processes to provide Quality Assurance within our deliverables, the following +artifacts will be produced in line with our development processes: + +- Testing Plan: This is official recording and documentation of the processes undertaken as part of + the testing phase. Included within the testing plan is details of each specific test undertaken on + a developed feature, and documents the test number, scenario, inputs, and the expected versus + actual results. This allows for our team to ensure that the final testing outcomes meet all + requirements and expectations of the deliverables, and allows the testing processes and outcomes + to be viewed and understood by others, both within the team and wider company. A template of the + Thoth Tech Testing Plan can be found here: + +- Test Case documentation: This is an official recording of the details regarding a specific testing + scenario and will be different depending on the feature to be tested ( for example, the Test Case + for the extension of the API management features will be different from that of the LDAP Devise + Server). The Test Case includes further details regarding the environment which the testing was + conducted (including details regarding operating systems and versions of software) and the + sequence of steps which were performed to create the test and implement it. Overall, this + documentation provides detail into the specifics of each test on the developed features, including + suffice detail for others to understand the conditions of the testing process and, if applicable, + to replicate the test themselves. It is closely linked to the information recorded within the + Testing Plan. + +## Test Management + +This section outlines the resources that will be used during the testing processes for the API user +management extension and the integration of a Devise LDAP server into the OnTrack architecture: + +- GitHub will be used to facilitate version control of the tests developed +- Visual Studio code will be used to create tests relevant to both the user management/API extension + and the Devise LDAP server integration, ensuring that all components of the expected functionality + are tested +- Ruby-on-Rails will be used to create tests for functionality of features integrated within the API +- The data used within the testing will be users and data that have been created specifically for + the testing processes. The functionality of the users and their data simulate the real users and + data of the OnTrack system to facilitate realistic testing without effecting the actual users + during the testing phase +- Docker will be used to build the OnTrack environment to allow for testing to be conducted within + it, and to view the effects of the added features on how the environment runs + +## Scope of Testing + +This section outlines the type of tests which exist within the OnTrack project. + +- There are API test files and processes written in Rails which already exist which are relevant to + testing other processes within the OnTrack system. While these tests are not able to be used for + our testing purposes, they do provide examples of how to write the testing processes and provide + sample user accounts and data which can be utilised within the testing of our features +- New testing processes will be written by the Enhance Authentication developers as part of the + development and testing phases, based on pre-existing test files within the OnTrack architecture + and using some of the testing processes that have already been developed +- Regarding the Devise LDAP server, the respective GitHub pages for these technologies (referenced + above) also include processes for testing their implementation. These guidelines may also be + consulted within the testing phases, especially in the earlier parts of interacting with these new + technologies diff --git a/src/content/docs/Products/OnTrack/Documentation/Deployment/Google Cloud/google-cloud-research.md b/src/content/docs/Products/OnTrack/Documentation/Deployment/Google Cloud/google-cloud-research.md new file mode 100644 index 00000000..3d783ded --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Deployment/Google Cloud/google-cloud-research.md @@ -0,0 +1,154 @@ +--- +title: Google Cloud - Research Documentation +--- + +[Introduction](#introduction) + +[Aims](#aims) + +[Findings](#findings) + +- [Google Cloud](#google-cloud) +- [CI/CD Deployments](#cicd-deployments) +- [Docker containers](#docker-containers) +- [Artifact Registry](#artifact-registry) +- [OnTrack/Doubtfire deployment and components](#ontrackdoubtfire-deployment-and-components) + +[Learnings](#learnings) + +[Outcomes](#outcomes) + +[References](#references) + +[Links](#links) + +--- + +## Introduction + +The Deployment project aim is to create an employee-run deployment of OnTrack separated from the +existing Deakin version and hosted on Google Cloud. + +## Aims + +1. Understanding of Google Cloud services, Deployments; +2. Understanding of Docker containers; +3. Understanding of the overall OnTrack deployment and components; + +## Findings + +### Google Cloud + +**Google Cloud Platform (GCP)** is a cloud service platform that allows you to build cloud resources +and platforms, leveraging cloud native services and features. + +Google Compute Engine (GCE) is the Infrastructure as a Service (IaaS) component of Google CLoud +Platform (GCP) [1]. It is the service that provides virtual machines (VMs) as server resources in +the cloud. + +Cloud Build and Cloud Run are services offered by Google Cloud to achieve part of the CI/CD +deployment. Cloud Build is designed to help you execute your builds on Google Cloud from your source +code in your git repositories. Cloud Run is designed to run containers as a serverless, compute +platform. + +Once your Google Cloud account and project is setup, there are IAM users & roles which will need to +be setup to access Google Cloud services. The account administrator would also need to enable the +desired Google Cloud services, such as Cloud Build and Cloud Run, as they are not enabled by +default. IAM users & roles will then need to be assigned to the enabled services. + +### CI/CD Deployments + +Once you are setup with a Google Cloud account and project, you can setup a CI/CD pipeline to +perform the steps of build, test, and deploy to Google Cloud. The source code will need to be in a +git repository and Google Cloud will need access to monitor the actions of the git repository. For +example, you can setup either commits or pull requests to be monitored which will trigger a build +within Cloud Build. + +### Docker containers + +**Docker** allows you to package and run an application in a loosely isolated environment [2] +referred to as a container. The container is a portable and lightweight image that contains +everything needed to run an application without any reliance of installed apps or components on the +host server. + +Docker compose is the tool to define and run Docker applications. A `Dockerfile` defines the app's +environment. A `docker-compose.yaml` file defines the services that make up your app in YAML. And +`docker compose up` starts and runs your entire app [3]. + +### Artifact Registry + +Initially, we reviewed the use of Google Container Registry (GCR) service in Google Cloud as a +repository for container images. However upon reading Google Cloud's documentation, it highlighted +that Artifact Registry is the recommended service for managing container images [4] artifacts for +Google Cloud projects. Private images can be pushed to a GCR repository and pulled for use within +GCP. + +### OnTrack/Doubtfire deployment and components + +The **Doubtfire** (commonly known as **OnTrack**) deployment guide we referred to outlines that +Doubtfire is deployed using Docker containers described in a docker compose [5]. The application +involves the following components: + +> - a proxy, based on nginx, that handles HTTPS and routes traffic to the webserver or apiserver +> containers. +> - a webserver, based on nginx, that serves the static html/css/javascript/etc files. +> - an apiserver, based on rails, that serves the restful API used by the application. +> - an application server (pdfgen), based on rails, that uses cron jobs to periodically generate +> PDFs from student submissions, and send status emails. +> - a database server, based on Maria DB or MySql used by the api and application servers to persist +> data +> - file storage connected to the apiserver and application server for storing student work +> - an external mail server to send emails +> - an external authentication server to authenticate users. (Source: +> [doubtfire-deploy GitHub repo](https://github.com/thoth-tech/doubtfire-deploy/blob/main/DEPLOYING.md)) + +There are quite a few steps that will need to be performed to configure the above components. The +team will require a high-level understanding of the components, services, and frameworks used for +the setup and changes required. + +### Learnings + +- After a couple of discussions with the Pipelines team and Andrew Cain, it was determined that + Cloud Build and Cloud Run had some limitations and may not be ideal to be able to cater for the + wider team at Thoth-Tech. As a result, the Google Cloud and Pipelines teams have moved on to + consider other options that would be more viable and aligned to the goals of the project. +- In order to use Artifact Registry, the service will need to be enabled in your Google Cloud + Platform (GCP) project. +- In order to push or pull a container image, Docker will need to be installed and configured. +- The team will need a high-level understanding of components such as nginx, rails, pdfgen, database + servers (MariaDB or MySql), Action Mailer, Dockerfile, and `docker-compose.yaml`. + +## Outcomes + +Following the team's research of Google Cloud and its services, deployments, and Docker +containers,the team have determined the following outcomes: + +1. Provide a high-level design and document architecture overview of how Google Cloud Platform (GCP) + will be used to support overall deployment and CI/CD pipelines to run resources for this project; +2. Organise the team's access to GCP and GCP project; +3. Create user stories / Trello cards for configuration of components required for the Doubtfire + deployment; +4. Plan to build the platform requirements to deploy an instance of Doubtfire within GCP; + +## References + +[1] Wikipedia (n.d.). Google Compute Engine [Webpage]. Available: + + +[2] Docker (n.d.). Docker overview [Webpage]. Available: + + +[3] Docker (n.d.). Overview of Docker Compose [Webpage]. Available: + + +[4] Google Cloud (n.d.). Container Registry [Webpage]. Available: + + +[5] Thoth-Tech (n.d.). Doubtfire-deploy [Webpage]. Available: + + +## Links + +- [GitHub repo for Thoth-Tech/Doubtfire-deploy](https://github.com/thoth-tech/doubtfire-deploy) +- [GitHub repo for Thoth-Tech/Doubtfire-deploy/DEPLOYING.md](https://github.com/thoth-tech/doubtfire-deploy/blob/main/DEPLOYING.md) +- [Trello board for Deployment - Google Cloud epic](https://trello.com/b/dI1yx9A1/deployment) diff --git a/src/content/docs/Products/OnTrack/Documentation/Deployment/Index.md b/src/content/docs/Products/OnTrack/Documentation/Deployment/Index.md new file mode 100644 index 00000000..214d0722 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Deployment/Index.md @@ -0,0 +1,27 @@ +--- +title: Google Cloud - Documentation Index +--- + +## [Overview](/products/ontrack/documentation/deployment/overview) + +Google Cloud team's overview and high-level documentation. + +## [Research & Findings](/products/ontrack/documentation/deployment/google-cloud/google-cloud-research) + +Google Cloud team's research and findings - + +- Aims +- Findings +- Learnings +- Outcomes +- References +- Links + +## Links + +- [GitHub repo for Thoth-Tech/Doubtfire-deploy](https://github.com/thoth-tech/doubtfire-deploy) +- [GitHub repo for Thoth-Tech/Doubtfire-deploy/DEPLOYING.md](https://github.com/thoth-tech/doubtfire-deploy/blob/main/DEPLOYING.md) +- [Trello board for Deployment - Google Cloud epic](https://trello.com/b/dI1yx9A1/deployment) +- [GitHub repo for Thoth-Tech/Doubtfir-deploy-GCP](https://github.com/thoth-tech/doubtfire-deploy-GCP) +- [Miro for Google Cloud - Doubtfire](https://miro.com/app/board/uXjVO0h8ZSE=/?share_link_id=62396987373) +- [Miro for Google Cloud - CI/CD](https://miro.com/app/board/uXjVO64xoQw=/?share_link_id=57734801709) diff --git a/src/content/docs/Products/OnTrack/Documentation/Deployment/deployment-epic.md b/src/content/docs/Products/OnTrack/Documentation/Deployment/deployment-epic.md new file mode 100644 index 00000000..cc593f10 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Deployment/deployment-epic.md @@ -0,0 +1,77 @@ +--- +title: Deployment Epic +--- + +## Background + +A live implementation of the OnTrack platform is accessible through Deakin University and other +organisations around the world. Currently, there is no separately hosted platform for Thoth Tech's +code implementation to operate on. + +## Business Value + +Now that Thoth Tech has been established and development work on OnTrack will start to increase, we +need a Thoth Tech hosted deployment of OnTrack. This will provide greater freedom to develop OnTrack +to the evolving vision of the company. + +## In scope + +- Thoth Tech Ontrack deployment to Google Cloud +- Documentation of deployment +- CI/CD Pipeline +- Documentation of pipeline +- Authentication +- Documentation of authentication + +## Out of scope + +New features + +## What needs to happen + +The deployment team will need to create an employee-run/hosted version of OnTrack to Google Cloud, +which will be separate to the Deakin version. This will be completed by three teams, which will all +be working together to migrate to google cloud, build a CI/CD pipeline, and create the +authentication for the platform for students. + +- Thoth Tech Ontrack deployment to Google Cloud +- CI/CD Pipeline built +- Add LDAP server option +- Extend API with user management +- Provide password management for LDAP and database implementations. + +## Assumptions / Dependencies + +- All functions will be working when OnTrack is migrated to student version +- The deployment won’t create any additional security risks + +## Analytics Considerations + +N/A + +## Reg & Compliance Considerations + +- Storage and privacy of user’s data +- Security +- Retention policy + +## Operations/Support + +Team members may need training/upskilling in technologies such as Google Cloud, Ruby on Rails, +Docker, etc. Members will also need testing skills to make sure all the new functionality works and +to be able to fix any bugs/problems. + +## What are the challenges? + +Team members have no existing code to work off, as this is new project that is being implemented +however they may be able to use the OnTrack deployment architecture as a guide. Team members may +have also not had the opportunity to work with the technologies they will be using for the +deployment of OnTrack to Google Cloud. + +## Acceptance criteria + +- Validate architecture and planning documentation with leadership +- CI/CD pipeline has testing, linting and security built into it +- Documentation is accurate to current version of products +- Thoth Tech deployment is successfully hosted on Google Cloud and functions as expected +- Allow for admins to change passwords (but cannot access passwords) diff --git a/src/content/docs/Products/OnTrack/Documentation/Deployment/overview.md b/src/content/docs/Products/OnTrack/Documentation/Deployment/overview.md new file mode 100644 index 00000000..1190c8d6 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Deployment/overview.md @@ -0,0 +1,144 @@ +--- +title: Google Cloud - Overview +--- + +[Overview](#overview) + +[Initial stages](#initial-stages) + +- [Tests via localhost](#tests-via-localhost) +- [Google Compute Engine instance](#google-compute-engine-instance) +- [Deploying OnTrack](#deploying-ontrack) + +[Next stages](#next-stages) + +[Links] (#links) + +[Assets] (#assets) + +## Overview + +The Google Cloud team's main deliverable for the project is to deploy a student- run version of +OnTrack which is hosted on Google Cloud Platform (GCP). The goal is for Thoth Tech to have their own +deployment to develop OnTrack that is separate to Deakin's deployment. + +![Google Cloud - Doubtfire](/GoogleCloud_Doubtfire.jpg "Google Cloud - Doubtfire") + +The Google cloud team have deployed a functional instance of Doubtfire (also known as OnTrack) +hosted on GCP. + +Our GCP project is centrally managed by Deakin IT where the team have been granted access using our +Deakin Google Workspace accounts. + +- GCP Project Name: sit-22t1-ontrack-deplo-d026375 +- GCP Project ID: sit-22t1-ontrack-deplo-d026375 + +In Google Compute Engine, we have created server instance running Linux (Centos 7.x). The instance +is a small, initial footprint that has a publicly facing network and accessible over the internet +via HTTPS (port 443). + +We have used the source code from the Thoth Tech repository for the deployment into GCP, where we +used docker compose to deploy the images for the components required to run Doubtfire (api server, +app server, doubtfire-web, mariadb, nginx). + +## Initial stages + +Initially, the Google Cloud team had spent time understanding GCP, Docker, and the Doubtfire +deployment. + +### Tests via localhost + +Prior to deploying to GCP, we ran several tests locally (localhost) on our own workstations to +determine the configuration changes required deploy Doubtfire successfully. On our individual +workstations, we cloned the [Doubtfire-deploy-GCP repository] + and modified the necessary files. We then used +docker compose and Docker to run and deploy containers. + +![doubtfire-localhost-compose](/doubtfire-localhost-compose.png "docker compose output") + +Success! We have Docker containers running locally. + +![doubtfire-localhost-docker](/doubtfire-localhost-docker.png "Docker containers running") + +Success again! We have OnTrack being hosted locally and is accessible via . + +![doubtfire-localhost](/doubtfire-localhost.png "Doubtfire running on localhost") + +### Google Compute Engine instance + +Once we determined the configuration changes required to be able to run locally (localhost), we then +needed to determine how to create and deploy a Compute Engine server instance in GCP that we could +use to deploy Doubtfire. + +We started with a small, initial footprint and deployed a basic virtual machine (VM) instance with +following details; + +- Name: instance-1 +- Zone: australia-southeast2-a +- Machine type: e2-micro +- CPU platform: Intel Broadwell +- OS Image: Centos 7 (Image name centos-7-v20220406) +- Boot disk: 20GB SCSI (Balanced persistent disk, Google-managed encryption) +- Network interfaces: nic0 (with internal & external IP addresses) +- Firewalls: HTTP, HTTPS enabled +- GPUs/Display device: None, disabled + +Once we had the instance up and running, we connected to the instance using command-line shell via +SSH. In the Google Cloud console, you can view the options to connect by clicking the drop-down menu +beside _Connect SSH_ on the instance view. + +![gcp-instance-connect](/gcp-instance-connect.png "Instance connection options") + +Alternatively, you can SSH to the instance via gcloud CLI - + +```shell +gcloud compute ssh --zone "australia-southeast2-a" "instance-1" --project "sit-22t1-ontrack-deplo-d026375" +``` + +There were a few packages that needed to be installed on the host, such as - + +- yum-utils +- yum-config-manager (required to setup docker-ce repo, see + [Docker docs](https://docs.docker.com/engine/install/centos/) for Centos) +- docker-ce, docker-ce-cli, containerd.io, docker-complose-plugin +- git +- openssl +- nano (optional) + +Once installed using `yum`, we had the minimum requirements to get started on the Doubtfire +deployment. + +### Deploying OnTrack + +From here, we pulled down the doubtfire-deploy repository, generated a new certificate and private +key for the host, and ran docker compose to deploy the containers for the OnTrack deployment. + +![gcp-instance-docker](/gcp-instance-docker.png "Instance running docker containers") + +And we can browse to OnTrack over the internet using our public IP address via HTTPS (port 443). + +![ontrack-login](/ontrack-login.png "OnTrack Login") + +## Next stages + +Since we have a functional and publicly accessible instance of Doubtfire running in GCP, the next +stages would be to focus on the Deployment team project objectives, such as - + +- Create a CI/CD pipeline that automates the building, deployment, and validation of the Thoth Tech + OnTrack deployment onto GCP. +- LDAP authentication for OnTrack. +- Email notifications configured with an SMTP server. +- Review security posture and instance sizing of the Thoth Tech OnTrack deployment in GCP. + +Here's a high-level diagram of using CI/CD pipeline to automate the deployment of OnTrack onto GCP - + +![Google Cloud - CI/CD](/GoogleCloud_CICD.jpg "Google Cloud - CICD") + +## Links + +- [GitHub repo for Thoth-Tech/Doubtfire-deploy-GCP](https://github.com/thoth-tech/doubtfire-deploy-GCP) +- [GitHub repo for Thoth-Tech/Doubtfire-deploy/DEPLOYING.md](https://github.com/thoth-tech/doubtfire-deploy/blob/main/DEPLOYING.md) +- [Trello board for Deployment - Google Cloud epic](https://trello.com/b/dI1yx9A1/deployment) +- [Miro for Google Cloud - Doubtfire](https://miro.com/app/board/uXjVO0h8ZSE=/?share_link_id=62396987373) +- [Miro for Google Cloud - CI/CD](https://miro.com/app/board/uXjVO64xoQw=/?share_link_id=57734801709) +- [Pull Request - OnTrack deployment on GCP](https://github.com/thoth-tech/doubtfire-deploy-GCP/pull/5) diff --git a/src/content/docs/Products/OnTrack/Documentation/Deployment/software-requirements-specifications-document.md b/src/content/docs/Products/OnTrack/Documentation/Deployment/software-requirements-specifications-document.md new file mode 100644 index 00000000..b50b74dd --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Deployment/software-requirements-specifications-document.md @@ -0,0 +1,101 @@ +--- +title: Software Requirements Specifications Document +--- + +## 1.Introduction + +1.1 Product purpose + +Currently, there are three different product purposes within the deployment deliverable. The first +of which is the google cloud team, and their focus is creating a student-run / student-hosted +deployment of Ontrack separate from the Deakin Version. The second team is working on developing a +pipeline between the two versions of the OnTrack system, that will streamline development and +functionality. Lastly, the Enhance authentication team is working on creating new authentication +systems for students to access their OnTrack account. + +1.2 & 1.3 Intended audience / use + +The intended audience is both system admins and users of OnTrack. Both the google cloud and pipeline +team will focus on a product that intended for the use of product owners only, but the enhance +authentication team will focus on a product that both system admins and users can use, as system +admins will be able to reset students' passwords and Provide password management for LDAP and +database implementations. The product users will also have enhanced functionality with +authentication, as they will have new features which will allow them to create a new or obtain their +old password. + +1.4 Scope + +The scope of the project is to create an upgraded deployment of the OnTrack system, in which, the +system will be student-run/ hosted via google cloud, A pipeline build that will focus on version +control, acceptance testing, independent deployment and production deployment. Lastly, the inclusion +of a refreshed authentication system that will assist both product users and system admins of the +OnTrack system. + +## 2.Description of overall System + +2.1 User requirements + +The requirements below are what is needed for both system admins and product users. + +users + +- Ability to access and check my passwords, including previously used ones, and change + currentlyusing +- Assurance that the authentication solution is secure, so that my passwords and other information + is not publicly disclosed. +- An authentication solution to be reliable and respond swiftly, so that I can access my account as + needed and on-demand. +- Ability to reset my Ontrack password myself, so I don't need to contact a system administrator +- up-to-date version of OnTrack hosted on GCP so that I won't have to wait for the service to be + manually updated. + +System admin + +- Have user's passwords stored in a secure +- have a database that is easy and low costing to maintenance and easy to be consistent with future + add-ons +- in-house authentication solution developed that meets all our authentication needs +- Ability for students to reset their Ontrack password themself, so they don't need to contact a + system administrator +- access the OnTrack via a link to see what different developers have done. +- student hosted version of OnTrack, as it will make it easier to complete more tasks +- pipeline to be as simple and maintainable as possible +- generic deployment pipeline that can be changed in future + + 2.2 Assumptions and dependencies + +Assumptions and dependencies of the product user include: + +students will forget their password to OnTrack, students' passwords will be secure, students +will need to change their passwords, students will need a copy of their current password, system +will be able to deal with multiple password requests at once + +Assumptions and dependencies of the system admin include: + +Students will have the skillset to maintain a student deployed version of OnTrack, future iterations +will be made to the current system, system admins will need acceptance testing, students will have +the skillset to develop future iterations, system will handle multiple iteration updates at once + +## 3.System Requirements + +Google cloud + +- Allow dev ops engineer to deploy the docker container on Google cloud Platform. +- Allow access to OnTrack users via URL from anywhere. +- Allow OnTrack developers to package Doubtfire api and Doubtfire Web into the standalone + applications. + +Pipeline build + +- Allow for version control +- Allow for system admins to use acceptance testing +- independent deployment +- production deployment + +Enhance Authentication + +- Allow users to simply access and reset their passwords +- Allow administrator to send request to reset other users' passwords +- Securely manage user information and passwords +- Securely and accurately authenticate users +- Operates fully in-house and without third-party usage or dependencies diff --git a/src/content/docs/products/ontrack/documentation/deployment/User Stories.md b/src/content/docs/Products/OnTrack/Documentation/Deployment/user-stories.md similarity index 100% rename from src/content/docs/products/ontrack/documentation/deployment/User Stories.md rename to src/content/docs/Products/OnTrack/Documentation/Deployment/user-stories.md diff --git a/src/content/docs/Products/OnTrack/Documentation/Documentation/Proposed_Google_Auth_feature.md b/src/content/docs/Products/OnTrack/Documentation/Documentation/Proposed_Google_Auth_feature.md new file mode 100644 index 00000000..fa58fa58 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Documentation/Proposed_Google_Auth_feature.md @@ -0,0 +1,129 @@ +ο»Ώ--- +title: Google Authentication Implementation in Ruby on Rails Introduction +--- + +This report details the attempted implementation of Google authentication using the +google-api-client gem, challenges encountered, and a proposal for a new approach using the +google-authenticator library available here the goal is to establish a secure, robust, and efficient +authentication system within a Ruby on Rails application. + +## What Was Tried and Why It Didn't Work + +### Previous Implementation Steps + +1. **Setup Using google-api-client:** + - Integrated the gem to handle Google OAuth 2.0. + - Created an endpoint in authentication_api.rb for Google authentication (/auth/google). + - Configured token verification using Google::Apis::Oauth2V2::Oauth2Service. + - Generated temporary tokens for authenticated users. + +2. **Challenges Identified:** + - **Token Validation Failures:** Issues with API key configuration and scope validation caused + intermittent failures. + - **Complexity in Library Usage:** The google-api-client gem required extensive configuration and + debugging for basic functionality. + - **Session Management:** Temporary tokens generated lacked proper integration with the + application's session flow. + +## Proposed Approach: Using google-authenticator + +The [Google-authenticator](https://github.com/jaredonline/google-authenticator) library offers a +simplified and efficient way to implement Google OAuth 2.0. It abstracts much of the complexity of +token validation and user data retrieval. + +### Key Benefits + +- Simplified integration of Google authentication. +- Minimal configuration with a focus on token validation and secure user onboarding. +- Lightweight and developer-friendly, reducing overhead. + +### Implementation Plan Using google-authenticator + +1. **Gem Installation** + + Add the google-authenticator gem to the Gemfile: + + ```plaintext + gem 'google-authenticator' + ``` + + Run bundle install to install the gem. + +2. **Environment Setup** + + Set up environment variables for secure management of credentials: + + ```shell + export GOOGLE_CLIENT_ID="your-client-id" + export GOOGLE_CLIENT_SECRET="your-client -secret" + ``` + +3. **Refactor authentication_api.rb** + + Update the authentication_api.rb file to use the new library: + + ```ruby + desc 'Google authentication' + + params do + requires :id_token, type: String, desc: 'Google ID token' + end + + post '/auth/google' do + + # Initialize the GoogleAuthenticator + authenticator = GoogleAuthenticator.new( + client_id: ENV['GOOGLE_CLIENT_ID'], + client_secret: ENV['GOOGLE_CLIENT_SECRET'] + ) + + idinfo = authenticator.verify(params[:id\_token]) + error!({ error: 'Invalid Google ID token.' }, 401) unless idinfo + + email = idinfo['email'] + logger.info "Authenticate #{email} from #{request.ip}" + user = User.find_or_create_by(email: email) do |new_user| + new_user.first_name = idinfo['given_name'] || 'First' + new_user.last_name = idinfo['family_name'] || 'Last' + new_user.username = email.split('@').first + new_user.role_id = Role.student.id + + end + + onetime_token = user.generate_temporary_authentication_token! + present :user, user, with: Entities::UserEntity + present :auth_token, onetime_token.authentication_token + end + + ``` + +4. **Testing** + + Conduct functional and security testing for the updated implementation: + - Validate token-based authentication using Google accounts. + - Test various scenarios such as invalid tokens and token expiration. + - Simulate edge cases like incorrect client credentials. + +5. **Deployment and Documentation** + - Deploy the changes to a staging environment for compatibility testing. + - Update API documentation to reflect the new authentication endpoint. + +## Next Steps and Recommendations + +### Short-Term Actions + +- Finalize the integration with google-authenticator. +- Conduct comprehensive testing, focusing on security and performance. +- Roll out the updated authentication mechanism during non-peak hours. + +### Long-Term Improvements + +- Implement refresh token functionality for long-lived sessions. +- Expand support for additional authentication providers, ensuring scalability. + +## Conclusion + +The switch to the google-authenticator library addresses the shortcomings of the previous approach +while simplifying the integration process. This plan provides a clear path toward a reliable and +secure Google authentication mechanism in the application. By leveraging this lightweight library, +we can reduce complexity and improve user experience. diff --git a/src/content/docs/Products/OnTrack/Documentation/Documentation/architecture-doc.md b/src/content/docs/Products/OnTrack/Documentation/Documentation/architecture-doc.md new file mode 100644 index 00000000..119249bd --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Documentation/architecture-doc.md @@ -0,0 +1,80 @@ +--- +title: Architecture Document +--- + +![Tooth_Tech](https://user-images.githubusercontent.com/110685225/191164124-c9e36722-378e-496c-8984-59b4ff6fd1db.png) + +--- + +## Author Information + +### Author(s): Jasdeep Singh(Jassingh27), Adrienne Gelbhauer(agelb21) + +### Team: OnTrack Documentation + +### Team (Delivery and/or Product) Lead: Shaine Christmas + +### Date of Writing: 20/09/2022 + +--- + +## Document Summary + +### Documentation Title: \*\*Architecture Document + +### Documentation Type + +[Informative/Technical] + +### Documentation Information Summary + +This document is visual report for architecture for OnTrack consist of context and container diagram +which explains its working. + +--- + +## Introduction + +### Purpose This document provides a high-level overview of the OnTrack system + +it intends tocommunicate the project structure and architecture to varying levels of complexity +appropriate for various stakeholders withing the organisation and varying levels of technical +literacy. + +### Scope This Architecture document uses a context diagram + +and container diagram to provide ahigh-level overview of the system,both are highly visual and aim +to be easy to comprehend, the context diagram aims to be non-technical, and the container diagram +provides further information to understand system structures. + +--- + +## Context diagram + +![Context_Diagram](https://user-images.githubusercontent.com/110685225/191164865-672927d8-7f16-47f4-865f-4a413bd249ab.png) + +--- + +## Container Diagram + +![OnTrack Container Diagram](https://user-images.githubusercontent.com/110685225/191168107-472c363d-2007-4409-81d5-6bd5800639c4.png) + +## Architectural Goals and Constraints + +- Maintaining a base system that supports future work towards developing new or enhancing + currentfeatures that improve the teaching and learning experience. +- front-end components are clear to understand, user friendly, and straightforward to use. +- System allows tutors to upload assessment tasks, resources, and assign learning outcomes to each + task. +- Students can set a learning outcome goal and filter tasks required for this goal, they can then + view each task and download the related task resources. +- Through the same task view, students can check deadlines, submit extension requests, send query's + to tutors, and make task submissions. +- Tutors can view and download submissions, manage extension requests, respond to queries and leave + feedback. +- System generates progress reports that are sent through email system, users can also track + progress relating to each unit and their set learning outcome goals. + +## Use-Case View + +![Use case view](https://user-images.githubusercontent.com/110685225/192712777-1d306d7d-380a-48a6-be08-8dbbc14ab492.jpeg) diff --git a/src/content/docs/Products/OnTrack/Documentation/Documentation/ontrack-documentation-template-guide.md b/src/content/docs/Products/OnTrack/Documentation/Documentation/ontrack-documentation-template-guide.md new file mode 100644 index 00000000..396e2b7a --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Documentation/ontrack-documentation-template-guide.md @@ -0,0 +1,217 @@ +--- +title: OnTrack Documentation Template Guide +--- + +## Purpose of this Guide + +--- + +The purpose of this guide is to explain how to properly use the +[OnTrack Documentation Template](https://github.com/thoth-tech/documentation/blob/main/docs/OnTrack/Documentation/OnTrack%20Documentation%20Template.md). + +Documentation is all about informing others. By using the documentation template, you will be able +to provide all the information needed for others to understand your work. This guide will show you +why each line of data in the template is included. That way, you can better understand the template +in general. + +Let's get started! + +## The Sections of the Template + +--- + +There are seven sections to the template: + +- Author Information +- Document Summary +- Document Review Information +- Key Terms +- Key Links/Resources +- Contacts for further information +- Related Documents + +Each of these sections have been included because they give your reader important information about +your documentation. Therefore, having this important information at the very start of your +documentation will help the reader to better understand what you have to say. + +Let's look at each section more closely. + +### Author Information + +--- + +The Author Information section is all about the author, or authors, of the documentation. When +reading something that has been written, it's often very helpful to know who wrote it. That way, if +the reader has more questions about it, or has some suggestions on the documentation itself, they +know who to talk to. + +This section contains the following information: + +- Author(s) +- Team +- Team (Delivery and/or Product) Lead + +An **Author**, or **Authors** when there is more than one, should be included to let the reader know +who wrote the document. This also gives the reader someone to contact about the documentation if +they need/want more information. Conversely, they can contact the author if the document ever needs +to be edited, altered or updated. + +The **Team** responsible for the document should also be included. This informs the reader about +which team/project the document relates to. Hence, it would also give the reader more understanding +about how the documentation relates to the company as a whole. + +The **Team (Delivery and/or Product) Lead** should be listed. This gives the reader an understanding +of who is responsible for the team that the documentation relates to. Similar to the **authors**, +this gives the reader a second point of contact. They could be contacted to get more information on +the topic, or if the document needs to be edited, altered or updated. + +### Document Summary + +--- + +The Document Summary section contains information about the content of the document. In other words, +it's all about what the documentation is trying to inform the reader about. In this section, the +reader will be able to understand the general purpose of your documentation, and what it is about. + +This section contains the following information: + +- Documentation Title +- Documentation Type +- Documentation Information Summary + +A **Documentation Title** should be included within any documentation to let readers know what the +document is about. Similar to the title of a book, this will let readers know what the information +contained within relates to. + +The **Documentation Type** denotes to the reader what type of documentation your document is. An +**Informative** document would explain a topic to your reader, similar to this guide. A +**Technical** document however, would require or assume in-depth knowledge of the documentation's +subject. This might be used for explaining specific pieces of code. + +Lastly, the **Documentation Information Summary** section is included to give the reader a general +understanding of the document itself. Here, you can write some text about what information is +contained within the document. This gives the reader more of an idea of what your document is about +before they start reading, helping them to better understand. + +In the template, using this guide as an example, this section could look like this: + +- **Documentation Title**: OnTrack Documentation Template Guide +- **Documentation Type**: Informative +- **Documentation Information Summary**: + - This document outlines how to use the OnTrack Documentation Template. It explains each data + point and each section of the template, giving readers a better understanding of how to utilise + the template. + +### Document Review Information + +--- + +This section of the template is included to inform your reader about how up-to-date a document is. +Any documentation, regardless of what it is about, should always be as up-to-date as possible. This +ensures the information your document conveys to the reader is useful and understandable to them. + +This section contains the following information: + +- Date of Original Document Submission to GitHub +- Documentation Version +- Date of Previous Documentation Review +- Date of Next Documentation Review + +All documentation for Thoth Tech is housed within an online website called GitHub. Thoth Tech has +numerous file structures in GitHub to which documents are uploaded to. The **Date of Original +Document Submission to GitHub** should therefore be supplied. This gives the reader an understanding +of when the document was first uploaded to GitHub. This knowledge will inform the reader of how old +the document is, regardless of how many versions or iterations there are. + +A **Documentation Version** (i.e. Version 1.0 or V1.0) should also be included where there have been +multiple versions or iterations of a particular document. A Version Number would help readers in +working out which version of the documentation they are reading. This could come in handy if the +reader needed to review a long-ago written (legacy) version, or if two versions needed to be +compared. + +The **Date of Previous Documentation Review** should be included to show when the last review of the +document was done. This would inform readers as to how long ago the documentation was last confirmed +as up-to-date. Therefore, the reader gains a better understanding of whether the information is +still current. + +A **Date of Next Documentation Review** should be included to give readers the date when the +document will/could/should next be reviewed. This could be recorded either by the author(s), or an +authorised company member. Including this data ensures that the document can be reviewed +periodically to ensure continuing accuracy. Depending on how often the data in the document may +change or become obsolete, this could be altered. + +An example could look like this: + +- **Date of Original Document Submission to GitHub**: 23rd March 2023 +- **Documentation Version**: v1.0 +- **Date of Previous Documentation Review**: N/A (first version) +- **Date of Next Documentation Review**: 1st June 2023 + +### Key Terms + +--- + +A **Key Terms** section could be included within your document to give the definitions of terms or +phrases important to your documentation. This list could provide your reader with the background +knowledge they need to gain the best understanding of what you are trying to say. This might be +particularly helpful in technical documents, where a number of terms might need to be defined. + +### Key Links/Resources + +--- + +Similarly, a list of **Key Links or Resources** could also help your reader in understanding your +documentation better. In this section you could include hyperlinks to webpages or even other Thoth +Tech documents in GitHub to give your reader necessary background information. Having these links at +the start of your documentation also saves the reader looking for them throughout the entire +document. With this background information and links, this list will assist your reader in +understanding what you have to say. + +### Contacts for further information + +--- + +Including a list of **Contacts for further information** could be beneficial to your reader. This +list would include people who can be contacted if the reader would like more information about: + +- your documentation +- the information within your documentation +- the subject of your documentation. + +Given Thoth Tech's teams come and go each trimester, it might be a good idea to list more constant +contacts, like Deakin staff. Listing staff, or other company members not within the Capstone +unit(s), would ensure new teams have a point of contact for more information each trimester. The +list of contacts would ensure the new teams have an idea of who would best help them understand your +documentation. Also, it shows the most suitable people they can ask questions to regarding the +document. + +### Related Documents + +--- + +Listing **Related Documents** to your documentation could also help the reader better understand +what you are trying to say. This section could list other documents that might aid the reader in +understanding your work. This could include documents that: + +- are related to the subject of your documentation +- would provide the reader with necessary background information +- could otherwise help your reader in understanding your document. + +For example, the beginning of this guide contains a link to the Documentation template, as it +relates to this document. Supplying a link to the template itself will aid readers with +understanding this guide. + +## Helpful Information + +--- + +When writing your documentation, the following links may be useful: + +- Thoth Tech has some general rules on how we would like documentation to be written. These can be + found + [here](https://github.com/thoth-tech/handbook/blob/main/docs/processes/documentation/writing-style-guide.md) +- Thoth Tech also uses a markup language called Markdown to write documentation in. Thoth Tech has a + document outlining what Markdown is, and how to write it, which can be found + [here](https://github.com/thoth-tech/handbook/blob/main/docs/learning/training/markdown-guide.md). +- Thoth Tech's Documentation Template can be found + [here](https://github.com/thoth-tech/documentation/blob/main/docs/OnTrack/Documentation/OnTrack%20Documentation%20Template.md). diff --git a/src/content/docs/Products/OnTrack/Documentation/Documentation/ontrack-documentation-template.md b/src/content/docs/Products/OnTrack/Documentation/Documentation/ontrack-documentation-template.md new file mode 100644 index 00000000..ea202ba0 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Documentation/ontrack-documentation-template.md @@ -0,0 +1,52 @@ +--- +title: Thoth Tech Documentation Template +--- + +## Author Information + +--- + +- Author(s): +- Team: +- Team (Delivery and/or Product) Lead: + +## Document Summary + +--- + +- Documentation Title: +- Documentation Type: { Informative/Technical } +- Documentation Information Summary: + +## Document Review Information + +--- + +- Date of Original Document Submission to GitHub: +- Documentation Version: +- Date of Previous Documentation Review: +- Date of Next Documentation Review + +## Key Terms + +--- + +Enter Key Terms here + +## Key Links/Resources + +--- + +Enter Key Links/Resources here + +## Contacts for further information + +--- + +Enter Contacts here + +## Related Documents + +--- + +Enter Related Documents here diff --git a/src/content/docs/Products/OnTrack/Documentation/Documentation/privacy-policies.md b/src/content/docs/Products/OnTrack/Documentation/Documentation/privacy-policies.md new file mode 100644 index 00000000..22270301 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Documentation/privacy-policies.md @@ -0,0 +1,123 @@ +--- +title: Privacy Policies +--- + +### **(A) This Policy** + +This Policy is issued by each of the Controller entities listed in Section P below (" **we**", " +**us**" or " **our**"). This Policy is addressed to individuals outside our organisation with whom +we interact, including students, staff (together, " **you** ) + +This Policy may be amended or updated from time to time to reflect changes in our practices with +respect to the Processing of Personal Data, or changes in applicable law. We encourage you to read +this Policy carefully, and to regularly check this page to review any changes we might make in +accordance with the terms of this Policy. + +### **(B) Processing your Personal Data** + +Collection of Personal Data: We collect or obtain Personal Data about you from the following +sources: + +Data provided to us: University login credentials + +Relationship data: In the ordinary course of our relationship with you. + +Website data: required personal information is collected while signup/sign in procedures. + +Creation of Personal Data: \*\* \*\* In providing our Services, we may also create Personal Data +about you, such as records of your interactions with host organisation and details of your +interaction on our website and we may record your track on tasks given to you. + +Categories of Personal Data: The categories of Personal Data about you that we Process include: + +Personal details: names; gender; date of birth / Domestic or International, course details etc. + +Contact details: Deakin email address. + +Course Assessment: Your Assessment task details, your progress on tasks and results of tasks. + +#### **Sensitive Personal Data** + +We do collect your personal details, course details to provide you with the assessment tasks. In +Processing your Sensitive Personal Data in connection with the purposes set out in this Policy, we +may rely on one or more of the following legal bases, depending on the circumstances: + +we have obtained your prior express consent to the Processing (this legal basis is only used in +relation to Process that is entirely voluntary – it is not used for Processing that is necessary or +obligatory in any way); + +the Processing is required or permitted by applicable law + +the Processing is necessary to protect the vital interests of any individual; or + +we have a legitimate interest in carrying out the Processing for the purpose of managing, operating. + +### **(C) Data Security** + +We have implemented appropriate technical and organisational security measures designed to protect +your Personal Data against accidental or unlawful destruction, loss, alteration, unauthorised +disclosure, unauthorised access, and other unlawful, or unauthorised forms of Processing, in +accordance with applicable law. + +Because the internet is an open system, the transmission of information via the internet is not +completely secure. Although we implement all reasonable measures to protect your Personal Data, we +cannot guarantee the security of your data transmitted to us using the internet – any such +transmission is at your own risk, and you are responsible for ensuring that any Personal Data that +you send to us are sent securely. + +### **(D) Data Accuracy** + +We take every reasonable step to ensure that: + +your Personal Data that we Process are accurate and, where necessary, kept up to date; and + +Any of your Personal Data that we Process that are inaccurate (having regard to the purposes for +which they are Processed) are erased or rectified without delay. + +### **(E) Data Minimisation** + +We take every reasonable step to ensure that your Personal Data that we Process are limited to the +Personal Data reasonably required in connection with the purposes set out in this Policy (including +the provision of Services to you). + +### **(F) Data Retention** + +We take every reasonable step to ensure that your Personal Data is only Processed for the minimum +period necessary for the purposes set out in this Policy. We retain copies of your Personal Data in +a form that permits identification only for as long as: + +We maintain an ongoing relationship with (for example, when you are using the site for your tasks) +your Personal Data are necessary in connection with the lawful purposes set out in this Policy + +We receive your consent to store the data for a longer period of time (for example, in the case of +application documents for your assessment records.). + +### **(G) Your Legal rights** + +Subject to applicable law, you may have several rights regarding the Processing of your Personal + +Data, including: + +The right not to provide your Personal Data to us (however, we are unable to provide you with your +course assessment tasks until you provide us with your personal and course details) + +The right to request access to, or copies of, your Personal Data that we Process, or control, +together with information regarding the source, purpose and nature of processing and disclosure of +those Personal Data; + +the right to request rectification of any inaccuracies in your Personal Data that we Process or +control; + +the right to request, on legitimate grounds: + +erasure of your Personal Data that we Process or control; or + +restriction of Processing of your Personal Data that we Process or control; + +the right to object, on legitimate grounds, to the Processing of your Personal Data by us, or on our +behalf; + +The right to withdraw your consent to Processing, where the lawfulness of processing is based on +consent (noting that such withdrawal does not affect the lawfulness of any Processing performed +prior to the date on which we receive notice of such withdrawal, and does not prevent the Processing +of your Personal Data in reliance upon any other available legal bases); diff --git a/src/content/docs/Products/OnTrack/Documentation/Documentation/report-on-data-analytics-tools.md b/src/content/docs/Products/OnTrack/Documentation/Documentation/report-on-data-analytics-tools.md new file mode 100644 index 00000000..a4884924 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Documentation/report-on-data-analytics-tools.md @@ -0,0 +1,117 @@ +--- +title: Research Spike - Report on Data Analytics Tools +--- + +## Introduction + +In today's data-driven educational landscape, schools and universities rely on advanced analytics +tools to gain insights, make informed decisions, and optimize operations. This report offers an +in-depth comparison of three prominent analytics tools: OctopusBI, Tableau, and Track One. The focus +is on their features, potential integration with the OnTrack platform, and alignment with the +specific needs of educational institutions. + +## OctopusBI + +OctopusBI is a robust business intelligence platform with a range of features designed to facilitate +data exploration, visualization, and reporting. It offers the following key features: + +- Customizable Dashboards and Reports: OctopusBI provides a user-friendly interface for creating and + customizing dashboards and reports, allowing educational institutions to tailor their data + representations to specific requirements. +- Data Integration: OctopusBI supports integration with various data sources, enabling seamless + connectivity to student information systems, learning management systems, and other relevant + databases. +- Interactive Data Visualization: The platform offers interactive charting tools and visualizations, + enabling stakeholders to explore data trends and insights more effectively. +- Collaboration and Sharing: OctopusBI facilitates collaboration through commenting and sharing + functionalities, enhancing communication among faculty and staff members. + +## Tableau + +Tableau is a renowned data visualization and analytics tool known for its user-friendly interface +and comprehensive capabilities. Key features include: + +- Advanced Data Visualization: Tableau's drag-and-drop interface empowers users to create + sophisticated visualizations, aiding educational institutions in presenting complex data in an + easily understandable manner. +- Wide Range of Connectors: Tableau offers an extensive library of connectors, enabling seamless + data integration from various sources, including cloud platforms, databases, and spreadsheets. +- Predictive Analytics and Forecasting: Educational institutions can leverage Tableau's advanced + analytics and forecasting tools to identify trends, patterns, and future scenarios, enhancing + proactive decision-making. +- Scalability and Performance: Tableau's scalable architecture ensures that as data volumes grow, + the system remains efficient and capable of handling increasing demands. + +## Track One Studio + +Track One Studio appears to be a comprehensive data analytics and business intelligence platform +designed to help organizations transform their data into actionable insights. It offers a range of +features that can benefit educational institutions and other sectors: + +- Data Integration: Track One Studio supports data integration from various sources, allowing + educational institutions to consolidate and analyse data from student information systems, + academic records, financial databases, and more. +- Visualization and Dashboards: The platform offers tools for creating interactive dashboards and + visualizations, enabling users to explore data trends and patterns visually. Customizable + dashboards can provide insights into student performance, enrolment data, resource allocation, and + more. +- Advanced Analytics: Track One Studio may provide advanced analytics capabilities, such as + predictive modelling, forecasting, and statistical analysis. These features can help educational + institutions make data-driven decisions to improve student outcomes and optimize operations. +- Collaboration and Sharing: The platform seems to facilitate collaboration among stakeholders by + allowing users to share reports, dashboards, and insights. This can enhance communication and + decision-making across departments. +- User-Friendly Interface: Track One Studio's user-friendly interface aims to make data analysis + accessible to users with varying levels of technical expertise, empowering educators and + administrators to harness the power of data. +- Security: Data security is crucial for educational institutions. Track One Studio might offer + security features to protect sensitive student information and comply with data privacy + regulations. +- Customization: Educational institutions often have unique data requirements. Track One Studio may + provide customization options to tailor the platform to the specific needs of schools and + universities. + +## Integration with OnTrack + +The successful integration of an analytics tool with the OnTrack platform is crucial for maximizing +data utilization in educational institutions. Integration considerations include data compatibility, +API availability, and seamless workflow alignment. Each tool's integration potential with OnTrack +needs to be assessed based on the platform's requirements and APIs provided by the analytics tools. + +## What Schools and Universities Seek + +Educational institutions commonly seek the following attributes in a data analytics system: + +- Data Consolidation: The ability to integrate data from disparate sources to provide a + comprehensive view. +- Customization: Tailoring dashboards and reports to meet the unique needs of different departments + and stakeholders. +- User-Friendly Interface: Intuitive tools that empower non-technical users to explore data and + generate insights. +- Predictive Capabilities: Tools for predictive modelling and forecasting to support data-driven + decision-making. +- Security: Robust security measures to protect sensitive student and institutional data. + +## Comparison Table: OctopusBI vs. Tableau vs. Track One Studio + +| **Feature** | **OctopusBI** | **Tableau** | **Track One Studio** | +| ----------------------- | -------------------------- | ------------------------ | ------------------------ | +| Data Integration | Multiple sources | Wide range of connectors | Data integration support | +| Visualization | Customizable dashboards | Advanced visualizations | Interactive dashboards | +| Analytics | Basic capabilities | Advanced analytics | Predictive modelling | +| User-Friendly Interface | User-friendly | Intuitive UI | User-friendly | +| Collaboration | Sharing & commenting | Collaboration features | Collaboration features | +| Data Customization | Customizable reports | Tailored dashboards | Customizable | +| Predictive Analytics | Limited capabilities | Advanced forecasting | Predictive capabilities | +| Scalability | Suitable for growth | Scalable architecture | Scalable solution | +| Security | Standard security measures | Robust security measures | Data security | + +## Conclusion + +After analyzing the features and capabilities of OctopusBI, Tableau, and Track One Studio, it's +evident that each tool offers distinct advantages that can benefit educational institutions seeking +to leverage data analytics for better decision-making. + +When considering integration with the OnTrack platform, it's essential to assess the compatibility +and integration options provided by each tool. Additionally, budget, user preferences, and specific +institutional requirements should be taken into account when making a decision. diff --git a/src/content/docs/Products/OnTrack/Documentation/Documentation/spelling-and-grammar-template.md b/src/content/docs/Products/OnTrack/Documentation/Documentation/spelling-and-grammar-template.md new file mode 100644 index 00000000..f0950a48 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Documentation/spelling-and-grammar-template.md @@ -0,0 +1,244 @@ +--- +title: Spelling and Grammar Errors Template +--- + +## Document Information + +--- + +### Author Information + +--- + +- Author: Matt Clark +- Team: OnTrack Documentation +- Team (Delivery and/or Product) Lead: Shaine Christmas + +### Document Summary + +--- + +- Documentation Title: Spelling and Grammar Errors Template +- Documentation Type: Informative +- Documentation Information Summary: + - This document is a template teams can use to both identify and fix spelling and grammar issues + in documentation related to or handled by their respective team. + +### Document Review Information + +--- + +- Date of Original Document Submission to GitHub: 2nd October 2022 +- Documentation Version: v1.0 +- Date of Previous Documentation Review: N/A, first version. +- Date of Next Documentation Review: To Be Determined + +### Key Terms + +--- + +- Markdown: markup language used by Thoth Tech in documentation creation. +- GitHub: online repository system where Thoth Tech keeps their data and information, including + documentation. +- Prettier, Vale: tools used to ensure documentation written meets required standards. The + installation guide in the Key Links/Resources section below explains more about these + technologies. + +### Key Links/Resources + +--- + +Information on writing documentation for Thoth Tech: + +- [Thoth Tech Markdown Guide](https://github.com/thoth-tech/handbook/blob/main/docs/learning/training/markdown-guide.md). +- [Thoth Tech Writing Style Guide](https://github.com/thoth-tech/handbook/blob/main/docs/processes/documentation/writing-style-guide.md) +- [Thoth Tech Installation Guide for Prettier and Vale](https://github.com/thoth-tech/handbook/blob/main/docs/learning/useful-resources/setup-prettier-and-vale.md) + +OnTrack Documentation Template: + +- [Thoth Tech OnTrack Documentation Template](https://github.com/thoth-tech/documentation/blob/main/docs/OnTrack/Documentation/OnTrack%20Documentation%20Template.md) +- [Thoth Tech OnTrack Documentation Template Guide](https://github.com/thoth-tech/documentation/blob/main/docs/OnTrack/Documentation/OnTrack-Documentation-Template-Guide.md) + +### Contacts for further information + +--- + +- Documentation Team + +### Related Documents + +--- + +See Key Links/Resources section above. + +## How To Use This Template + +--- + +This template has been provided as a way for your team to both log and fix spelling and grammar +errors. These errors are those which you and your team find in documentation that your team is +either responsible for, or which relates to your team. For example, let's say a particular team's +document has an error. The error should be added to that team's version of this template. This way, +the team responsible for the document can be made aware of the error. The team which the document +relates to can then evaluate whether it must be fixed or not. + +### How To Create Your New Spelling And Grammar File + +--- + +The following steps outline how this document can be set up for your team. + +**NOTE:** As this is a template, when **_{Insert Team Here}_** appears, replace it with your team +name/area. For example, a team named "Critical Issues" or whose area is "Critical Issues" would +replace "**_{Insert Team Here}_**" with "Critical Issues". + +1. Create an empty Markdown file in a space your team can access. This should be named something + like "**_{Insert Team Here}_** Spelling and Grammar Errors." +2. Copy this template into the new file, _starting from the_ "**_{Insert Team Here}_** Spelling and + Grammar Errors List" _heading below this section._ Information on how to contribute to the + template is also included below as well. +3. Certain sections below contain the text "**_{Insert Team Here}_**". Ensure these are replaced + with your team's name and/or section. +4. That's all. You now have a document in which your team can add errors to. + +### Further Steps **_ONLY For Teams Working With OnTrack_** + +--- + +For teams **working with OnTrack**, Thoth Tech has a special template for OnTrack Documentation. +This template helps your reader understand your work by concentrating all of the important +information of your document in one place. This allows your reader to get the most important +information out of your documentation as quickly as possible. + +To incorporate the OnTrack Documentation Template into your new Spelling and Grammar file, follow +these steps. + +1. After copying the below sections of the Spelling and Grammar template into your new file, open + the + [OnTrack Documentation Template](https://github.com/thoth-tech/documentation/blob/main/docs/OnTrack/Documentation/OnTrack%20Documentation%20Template.md). +2. Copy the contents of the OnTrack Documentation Template into your new Spelling and Grammar file. + The contents of the OnTrack Documentation Template should come before (precede) the contents of + the Spelling and Grammar Template in your new file. +3. Fill out the relevant sections of the OnTrack Documentation Template in your new Spelling and + Grammar file. + - Thoth Tech has an + [OnTrack Documentation Template Guide](https://github.com/thoth-tech/documentation/blob/main/docs/OnTrack/Documentation/OnTrack-Documentation-Template-Guide.md), + which explains how to do this. It also explains in more detail why the template is used, and + contains some links on writing documentation for Thoth Tech. + +## **_{Insert Team Here}_** Spelling and Grammar Errors List + +## Document Purpose + +--- + +The purpose of this document is to form a list wherein spelling and grammar issues in current +**_{Insert Team Here}_** documentation can be identified. They can then be subsequently assessed, +and if need be, fixed. + +Fixing these spelling and grammar mistakes increases the effectiveness and efficiency of the +documentation in question. This erases the potential for confusion as a result of any erroneous +words or phrases. + +## Data Required For Each Entry + +--- + +The following data points are recorded for each entry: + +- Document Name + - The document name allows the reader to understand in which file you have found an error, or + something that must be checked over. +- Document File Path (in GitHub) + - Most all of Thoth Tech's documentation can be found in it's GitHub repositories. Including the + document file path helps the reader find the document quickly, instead of searching through all + of Thoth Tech's GitHub repositories for it. The reader could instead follow this file path to + identify where the document is that you are referring to. For example, the file path of the + OnTrack Documentation is: _documentation/docs/OnTrack/Documentation_. +- Erroneous Words/Phrases + - Listing the erroneous words or phrases your entry refers to informs the reader as to where the + problems are in the document. +- Corrective Suggestions + - Listing these indicates to your reader why you think the mentioned words and/or phrases must be + changed. They can then take these suggestions into consideration when proofreading the document. + +## How This Document Is Formatted + +--- + +Entries into this document are made through the use of tables written in Markdown. The table appears +as shown below: + +| Document Name | Document File Path (in GitHub) | Erroneous Words/Phrases | Corrective Suggestions | +| ------------- | ------------------------------ | ----------------------------------- | ----------------------------------------------------------- | +| "Example-1" | documents/Example-1 | "...their is a document called..." | In this context, "there" should be used instead of "their". | +| "Example-2" | documents/Example-2 | "... When's the meeting today> ..." | ">" should be replaced with "?". | + +For further information on Markdown, what it is and how to use it, Thoth Tech has a +[Markdown Guide](https://github.com/thoth-tech/handbook/blob/main/docs/learning/training/markdown-guide.md). + +### Adding A New Entry + +--- + +To add an entry to an existing table, each bit of data you enter should be separated by a '|'. For +example, the first entry of the above table, in Markdown, is therefore written like this: + +> | "Example-1" | documents/Example-1 | "...their is a document called..." | In this context, +> "there" should be used instead of "their". | + +As you can see, each column's data in the entry is separated by a "|". A "|" is also needed on each +end of the table as well. In the above example, this is before "Example-1" and after "Meeting is +spelt incorrectly". + +## Found Spelling and Grammar Instances In GitHub + +--- + +### Important Considerations When **_Making New Additions_** To This Document + +--- + +- To save readers having to go in between many different files when looking through this list, + _order entries by document_. +- Tables written in Markdown do not allow dot points in their data. Therefore, if more than one + corrective suggestion is written, these must be numbered to help the reader differentiate them. + For example: 1. First suggestion. 2. Second suggestion. +- Where corrective suggestions are small changes, for example, the changing of one letter/character, + highlighting the changes in your suggestions may better help readers understand them. This can be + done through the use of italics or bold text. + - _Italics_ can be written by including one asterisk ("\*") on either side of the text you wish to + be in italics. + - **Bold** text can be written by including two asterisks ("\*\*") on either side of the text you + wish to be in bold. +- Ensure entries are written so that any reader, regardless of their level of contextual knowledge, + could understand what your suggestions mean. +- Thoth Tech uses a **set of rules** when **writing documentation**. The + [Writing Style Guide](https://github.com/thoth-tech/handbook/blob/main/docs/processes/documentation/writing-style-guide.md) + outlines these. +- Thoth Tech also uses the tools "Prettier" and "Vale" for **writing documentation**. Thoth Tech has + an + [Installation Guide](https://github.com/thoth-tech/handbook/blob/main/docs/learning/useful-resources/setup-prettier-and-vale.md) + for both of these technologies. + +### Important Considerations When **_Fixing Items_** In This List + +--- + +- If you are not a member of the team to which this list belongs to, ensure you have their + permission **_before_** editing documentation. + - You may not understand their workings and could hinder their progress if you make unannounced + and/or unverified changes. Changing their work without their knowledge could have unforesee + consequences. + - What you perceive as spelling and/or grammar errors in a document may be correct in the context + of that document. It would be beneficial to ask whether something is an error, instead of + assuming it is and editing the document. +- Once an error is fixed and verified as correct, delete it from this list. + +### List of Known Instances + +--- + +| Document Name | Document File Path (in GitHub) | Erroneous Words/Phrases | Corrective Suggestions | +| ------------- | ------------------------------ | ----------------------- | ---------------------- | +| Document 1 | File Path | Words and Phrases | Suggestions | diff --git a/src/content/docs/Products/OnTrack/Documentation/Documentation/spike-frontend-documentation-investigation.md b/src/content/docs/Products/OnTrack/Documentation/Documentation/spike-frontend-documentation-investigation.md new file mode 100644 index 00000000..3c75fa82 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Documentation/spike-frontend-documentation-investigation.md @@ -0,0 +1,71 @@ +--- +title: Spike Outcomes +--- + +**Spike:** 1 + +**Title:** Frontend Documentation Investigation + +**Author:** Devanshi Patel, + +## Goal / Deliverables + +- The goal is to create a document which outlines desire tools and format of document that can be + used to document angular component and service, which can be used for improving developer + efficiency. + +- Add any documentation tasks in the Frontend Documentation Backlog. + +## Technologies, Tools, and Resources used + +- Internet Browser; Google Chrome, Firefox, Safari + +- Programming Language: TypeScript, Ruby + +- Code Editor: VsCode + +- Supporting Application: Docker + +- Technologies: JSDoc Comments, Compodoc + +## Tasks undertaken + +- Have basic knowledge of Angular and what its main elements are and how they interact with other + applications within the system. + +- Learn how to use JSDoc comment in angular application. Know that JSDoc comment is a standard way + to document code in TypeScript. + +- Install Compodoc into VsCode application. Installation guide can be found on google. + +## What we found out + +- We found many ways that angular can be documented to improve developer experience and efficiency. + However, we ended up picking only two applications that can help us document the whole system. + +- JSDoc Comments can be used into TypeScript code to provide better understanding to developers on + how to use components that are already in place or even how to extend them. If we want to create + JSDoc comment we can use β€˜/\*\*’ and press entry, which indicated the opening delimiter for the + comment. β€˜\*’ indicates that the comment is part of the documentation. The actual documentation + + happens by using some of the common JSDoc tags like '@returns', '@private' and many more. Lastly, + we will close and mark the end of comment by using β€˜\*’ symbol. + +1. Download compodoc in your system by running this command: npm install -g @compodoc/compodoc into + VsCode terminal. + +1. Configure compodoc by making tsconfig.docs.json file into the root directory. + +1. In order to generate a document, we are going to use β€˜compodoc -p sconfig.docs.json -s’ command. + +1. After the installation is done, it would generate a URL where we can access the documentation. + +1. After we are doing with installing the application, we can view the documentation by visiting + + or what the URL was generated in the terminal. + +- If we were to implement compodoc into our project, it would help us to generate documentation for + modules, component, routes, any directives, pips, interface and many more. + +- So, the main idea behind is that we would first write JSDoc comment in our TypeScript code and + later create a document using compodoc which can be shared very easily among teams and developers. diff --git a/src/content/docs/Products/OnTrack/Documentation/File Submission Enhancements/project-summary-document.md b/src/content/docs/Products/OnTrack/Documentation/File Submission Enhancements/project-summary-document.md new file mode 100644 index 00000000..26c7a94f --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/File Submission Enhancements/project-summary-document.md @@ -0,0 +1,176 @@ +--- +title: OnTrack Word Document Submission Tea +--- + +## Author Information + +- Authors: Matt Kinnia and Simon Agahi +- Team: OnTrack - Word Document Submission +- Team (Delivery and/or Product) Lead: Simon Agahi and Nelson Lai + +## Document Summary + +- Documentation Title: OnTrack Word Document Submission Team +- Documentation Type: Technical +- Documentation Information Summary: Document detailing the original project aim, new project aim + for our trimester, information on the two containers researched, performance KPI's and evaluating + results, and a future students section for important information. + +## Document Review Information + +- Date of Original Document Submission to GitHub: 18/12/2022 +- Documentation Version: 1.0 +- Date of Previous Documentation Review: 18/12/2022 +- Date of Next Documentation Review: to be decided + +## Key Links/Resources + +- +- +- +- +- + +## Contacts for further information + +See . + +## Project Aim + +\ +Overall, the aim of this project is to extend the Doubtfire (OnTrack) Learning Management System by +allowing students to upload word documents against a task submission. \ +\ +Word documents must be converted to the Portable Document Format (PDF) so it can be made accessible +to the tutors and unit convenors for assessment. \ +\ +Currently, Doubtfire only supports code, PDF and image task submissions. + +## Project Aim for Trimester 3, 2022 + +\ +This trimester, our aim is to research, compare and decide on the technology implementation that +will be used to convert the word document submissions to PDF. \ +As a number of the team members are new to the capstone program, and/or new to the Doubtfire +architecture, a significant amount of time is dedicated to research and upskilling. + +## Introduction + +This trimester, we have focused on researching and comparing two Docker images which can be used for +converting word documents to PDFs; Pandoc and LibreOffice Writer. Specifically, these images are: \ +\ + +- pandoc/latex:2.17 +- instructure/libreoffice:6.3 + +## Pandoc + +\ + is a Command Line Interface (CLI) document converter which supports an +impressive number of conversion input and output permutations, including word processing file +extensions such as .docx, .rtf and .odt. Pandoc is well documented and easy to use. Pandoc CLI is +available as a Docker image, so it can be executed in isolation or installed natively within an +existing container. + +## LibreOffice + +\ + is an open source productivity suite which contains a number of +standalone applications which are used to author documents, spreadsheets and presentations. While +working with LibreOffice typically involves a graphical user interface, headless interactions are +possible via the CLI. Being an open sourced software, many implementations or flavours are available +on the internet. Because of this, we found it challenging to navigate and find documentation that +best fit our use case. LibreOffice CLI is also available in a Docker image. + +## Performance + +\ +In an effort to make an informed decision on which technology we should utilise going forward, we +had established three Key Performance Indicators (KPIs) in which we evaluated each technology +against. \ +\ + +- Speed; the time it took for a conversion to occur. +- Quality; the condition of the conversion output in comparison to the input. +- Footprint; the size of the technology implementation. \ + \ + In order to measure the technologies against the KPIs mentioned above, we had created a + benchmarking tool in Python/Jupyter Notebook which allowed us to perform the evaluation. \ + \ + As a base case (it can be easily extended), the benchmarking tool converts three different sized + ".docx" files, being 100kb, 500kb and 1MB, to ".pdf" and compares the time it took for each of the + technologies. Whereby each file is converted three times so we can report on the best, worst and + average cases. \ + \ The benchmarking tool and its outputs are available at β€œ./Performance + Benchmarking/runner.ipynb”. + +## Performance Conclusions + +\ +More detail is available in the benchmarking tool itself, a summary is provided below. \ +\ +![figure 1](/figure1.PNG) \ +\ + +- \*An average of three conversions of a 1MB .docx file. Speed should be used as an indicator only, + this largely depends on the available resources on the executing machine. \ + \ + Notes on Quality \ + \ + Quality is a subjective KPI, and can’t be effectively measured using a discrete value. In this + case, we are using quality as a measurement of likeness between the input and the output. \ + \ + See below for comments regarding conversion quality. \ + \ + ![figure 2](/figure2.PNG) + +## Future Students + +\ +For future students, reflect on the overall project aim, and start thinking in which creative ways +you can help to contribute to this project team. Ultimately by integrating the chosen container into +OnTrack successfully, the original project aim will be complete. \ +\ +A project which was new to the whole team during trimester 3 2022, as well as being condensed into a +very short period of time, was ultimately what allowed us to achieve what we could and overcoming +challenges. With these resources being created with the intention to serve great future reference to +future students and try help them get a head start as much as possible, it is important to take some +time and read/understand all the information provided and available. \ +\ +So have a read of some of the important project information below, and hopefully clears up a lot of +questions you would’ve had, to give a head start into the Capstone unit. \ +\ +**First Steps:** understand the structure of OnTrack, what it is, and how it works. \ +\ +In brief, Doubtfire (OnTrack) can be described as a β€œmodern, lightweight LMS” (Learning Management +System) that helps students submit work and receive feedback on it. \ +\ +![figure 3](/figure3.PNG) \ +\ +When looking at the OnTrack Architecture diagram, the red box, representing the API, is where most +of our work will be in, as it is mainly backend work that needs to be done. \ +\ +Doubtfire’s API is done in an open-source framework known as Ruby on Rails. Rails is written in Ruby +and provides default structures for a database and a web page. \ +\ +If you’re not familiar with the language or framework, learning and upskilling in these areas can be +included in the hours dedicated to upskilling. \ +\ +**NOTE:** minimum 30 hours of upskilling required, as explained by the directors of the capstone +unit. Could be subject to change for future trimesters, so please check with unit team first. \ +\ +**Deploy OnTrack Locally:** should be your priority if you are not a returning student to the +project. The link below will include three markdown files explaining everything you need to do to +successfully set Doubtfire up on your local computer, and so that you can get started working on it. +\ +\ +**Link:** +\ +\ +**Direction Moving Forwards & Deliverables:** now that you have Doubtfire setup and working locally, +you can start thinking about solutions and ways in which to contribute. \ +\ +I would recommend now that you have understood a bit of the structure of OnTrack, to then understand +how the API works, and finding the related code for the API to be able to start working on that. The +two kind of go hand in hand, understanding the backend of OnTrack’s API, alongside the overall +structure. diff --git a/src/content/docs/products/ontrack/documentation/front-end-migration/deploy-ontrack-using-docker/docker-compose-with-wsl2.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Deploy OnTrack/docker-compose-with-wsl2.md similarity index 93% rename from src/content/docs/products/ontrack/documentation/front-end-migration/deploy-ontrack-using-docker/docker-compose-with-wsl2.md rename to src/content/docs/Products/OnTrack/Documentation/Front End Migration/Deploy OnTrack/docker-compose-with-wsl2.md index d64e3c1c..07e5a277 100644 --- a/src/content/docs/products/ontrack/documentation/front-end-migration/deploy-ontrack-using-docker/docker-compose-with-wsl2.md +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Deploy OnTrack/docker-compose-with-wsl2.md @@ -73,9 +73,10 @@ sudo apt-get install net-tools (windows/linux installation) ## Converting WSL 1 Operating Systems to WSL 2 on Windows If you are using WSL1 You will need Windows 10 build 18917 or higher to be able to use WSL 2. Please -note, you will need to have the Powershell Administrator window up. If you are converting WSL 1 to -WSL 2 I’d assume you have Linux Subsystem for Windows installed. If not, the following command will -install it for you. +note, you will need to have the Powershell + +Administrator window up. If you are converting WSL 1 to WSL 2 I’d assume you have Linux Subsystem +for Windows installed. If not, the following command will install it for you. ```console Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux diff --git a/src/content/docs/products/ontrack/documentation/front-end-migration/deploy-ontrack-using-docker/docker-setup-tutorial.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Deploy OnTrack/docker-setup-tutorial.md similarity index 93% rename from src/content/docs/products/ontrack/documentation/front-end-migration/deploy-ontrack-using-docker/docker-setup-tutorial.md rename to src/content/docs/Products/OnTrack/Documentation/Front End Migration/Deploy OnTrack/docker-setup-tutorial.md index c6f44c8c..8ce3fd35 100644 --- a/src/content/docs/products/ontrack/documentation/front-end-migration/deploy-ontrack-using-docker/docker-setup-tutorial.md +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Deploy OnTrack/docker-setup-tutorial.md @@ -33,7 +33,8 @@ title: Docker Setup Tutorial ```console cd development docker compose up -d - docker compose run --rm doubtfire-api bash -c "bundle exec rails db:environment:set RAILS_ENV=development && bundle exec rake db:populate" + docker compose run --rm doubtfire-api bash -c "bundle exec rails db: + environment:set RAILS_ENV=development && bundle exec rake db:populate" ``` 5. Change into the development directory and use Docker Compose to setup the database. Run in the diff --git a/src/content/docs/products/ontrack/documentation/front-end-migration/deploy-ontrack-using-docker/setting-up-doubtfire.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Deploy OnTrack/setting-up-doubtfire.md similarity index 100% rename from src/content/docs/products/ontrack/documentation/front-end-migration/deploy-ontrack-using-docker/setting-up-doubtfire.md rename to src/content/docs/Products/OnTrack/Documentation/Front End Migration/Deploy OnTrack/setting-up-doubtfire.md diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Deploy OnTrack/troubleshooting-docker-backup-for-ontrack.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Deploy OnTrack/troubleshooting-docker-backup-for-ontrack.md new file mode 100644 index 00000000..697ac491 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Deploy OnTrack/troubleshooting-docker-backup-for-ontrack.md @@ -0,0 +1,59 @@ +--- +title: Guide For Environment setting of Doubtfire +--- + +## 1. Before setting up Doubtfire + +You need to set up a Kali Linux virtual machine and clone the Doubtfire. Any management tool(Virtual +box, VM ware and so on) to manage these virtual machines will work. + +Here is a nice YouTube tutorial: + +> \*Note: Set the Network mode to **NAT\*** + +## 2. Clone DoubtFire + +Here is the GitHub link to the project that we going to exploit: + + +What you guys need to do is + +1. read this: +2. And watch this video of MANJIANG YU: +3. Install docker-compose. Command: sudo apt install docker-compose Success deploy: + +// photo + +## 3. Trouble shooting + +1. docker: 'compose' is not a docker command. See 'docker --help' + + > You need to change β€œdocker compose” of file run-full.sh in doubtfire-deploy/development + +2. doubtfire-web doesn’t compile successfully: + - Open terminal + - Head to folder doubtfire-deploy/development by cd + - Run this in 1 line: + + ```console + doubtfire-web: docker-compose run -u 0 -p 4200:4200 doubtfire-web bash -c + "npm install; npm start" + ``` + +3. doubtfire-api don’t run and exit with code 0/1. + - Open terminal + - Head to folder doubtfire-deploy/development by cd + - Run this in 1 line: + + ```console + docker-compose run -p 3000:3000 doubtfire-api bash -c "bundle install; + bundle exec rails db:environment:set RAILS_ENV=development; + bundle exec rake db:populate; + bundle exec rake db:migrate && bundle exec rails s -b 0.0.0.0" + ``` + +## 4. Give Up + +Still cannot deploy it? Maybe it’s time to give up, you can just use Burp Suite and pentest online +on my VPS: **IMPORTANT**: don’t scan with BurpSuite you guys won’t find +anything anyway because of the anchor tag. diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Framework/angular-and-angularjs.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Framework/angular-and-angularjs.md new file mode 100644 index 00000000..39062c85 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Framework/angular-and-angularjs.md @@ -0,0 +1,55 @@ +--- +title: Different between Angular and AngularJS +--- + +## Definition + +**AngularJS** is an open-source, JavaScript-based, front-end web application framework for dynamic +web app development. It utilizes HTML as a template language. By extending HTML attributes with +directives and binding data to HTML with expressions, AngularJS creates an environment that is +readable, extraordinarily expressive, and quick to develop. + +**Angular 2** is the blanket term used to refer to Angular 2, Angular 4 and all other versions that +come after AngularJS. Both Angular 2 and 4 are open-source, TypeScript-based front-end web +application platforms. + +**Angular 4** is the latest version of Angular. Although Angular 2 was a complete rewrite of +AngularJS, there are no major differences between Angular 2 and Angular 4. Angular 4 is only an +improvement and is backward compatible with Angular 2. + +## Angular JS vs Angular + +Angular uses TypeScript and has components as its main building blocks. It is component-based, +whereas AngularJS uses directives. + +Angular's operation employs a hierarchy of components, while AngularJS has directives that allow +code reusability. So, The AngularJS framework provides reusable components for its users. + +**Why Angular?** + +- It has a mobile support framework. +- The latest Angular version supports TypeScript and enables code optimization and modularity by + employing the OOPS concept. +- It supports the changes for an increased hierarchical dependencies system. +- A developer can use various features such as syntax for type checking, Dart, TypeScript, ES5, + iterators, Angular CLI, ES6, and lambda operators. +- Angular opts for semantic versioning that has a major-minor-patch arrangement. +- Amongst its best benefits is its provision for the event of simplest routing. +- Are you new to Angular? Check out the Angular tutorial here. + +**Why AngularJS?** + +- It's secure MVC (Model-View-Controller) data binding makes application performance dynamic. +- A developer can easily perform unit testing or change detection at any point. +- It provides several helpful features for web developers, like declarative template language with + HTML to allow them to make it more intuitive. +- The open-source framework allows well-structured front-end development. It doesn't require any + plugin or other platforms to work. +- The AngularJS application runs on Android and iOS phones and tablets. + +## Reference + +Simplilearn.com. (2018). AngularJS Vs. Angular 2 Vs. Angular 4: Understanding the Differences. +[online] Available at: + [Accessed 20 +Sep. 2022]. diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/INBOX_FULL_MIGRATION_PLAN.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/INBOX_FULL_MIGRATION_PLAN.md new file mode 100644 index 00000000..12b802e0 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/INBOX_FULL_MIGRATION_PLAN.md @@ -0,0 +1,140 @@ +--- +title: Full Angular Migration Plan - Inbox Component +description: Complete migration plan for inbox component including parent dependency chain +--- + +# Full Angular Migration Plan: Inbox Component + +**Date:** January 14, 2026 +**By:** Husainuddin Mohammed, 223380186 +**Task:** Complete full Angular migration for units/tasks/inbox + +--- + +## Component Dependency Chain + +``` +units/index.coffee (Parent 1) + ↓ + Provides: unit, unitRole + ↓ +units/tasks/tasks.coffee (Parent 2) + ↓ + Provides: taskData object + ↓ +units/tasks/inbox/inbox.coffee (Child) + ↓ + Uses: unit, unitRole, taskData +``` + +**The problem:** Inbox component needs data from two AngularJS parent states. Can't fully migrate +inbox until parents are migrated. + +--- + +## What Each Parent Provides + +**Parent 1 (units/index.coffee):** + +- Loads unit object from API +- Resolves user's role for this unit +- Handles permissions and redirects + +**Parent 2 (units/tasks/tasks.coffee):** + +- Creates taskData object structure +- Manages task selection logic +- Syncs URL with selected task + +**Child (inbox.coffee):** + +- Sets task source function +- Renders Angular InboxComponent +- Already migrated to Angular - just needs parent cleanup + +--- + +## Migration Order: 3 PRs + +### PR 1: Migrate units/index (START HERE) + +**Status:** Already started - https://github.com/thoth-tech/doubtfire-web/pull/435 + +Migrate the root parent first. Replace AngularJS state with Angular resolvers that provide unit and +unitRole data. + +**Files to change:** + +- Create Angular state in `doubtfire.states.ts` +- Add resolvers for unit and unitRole +- Delete `units/states/index/index.coffee` + +**Why first:** Foundation for everything below it + +--- + +### PR 2: Migrate units/tasks + +Replace AngularJS state with Angular equivalent that manages taskData object. + +**Files to change:** + +- Create state or service for taskData management +- Update `doubtfire.states.ts` +- Delete `units/states/tasks/tasks.coffee` + +**Why second:** Depends on PR 1 providing unit/unitRole + +--- + +### PR 3: Complete inbox migration + +Remove remaining AngularJS files now that parents provide data through Angular. + +**Files to delete:** + +- `units/states/tasks/inbox/inbox.coffee` +- `units/states/tasks/inbox/inbox.tpl.html` + +**Why last:** Depends on both parent PRs + +--- + +## Visual Flow + +``` +Current State: + AngularJS State β†’ AngularJS State β†’ AngularJS wrapper β†’ Angular Component + (units/index) (units/tasks) (inbox.coffee) (InboxComponent) + +After PR 1: + Angular State β†’ AngularJS State β†’ AngularJS wrapper β†’ Angular Component + βœ“ + +After PR 2: + Angular State β†’ Angular State β†’ AngularJS wrapper β†’ Angular Component + βœ“ βœ“ + +After PR 3: + Angular State β†’ Angular State β†’ Angular Component + βœ“ βœ“ βœ“ (fully migrated) +``` + +--- + +## Testing Strategy + +Each PR needs to verify: + +- Unit loads correctly with proper permissions +- Task selection and navigation works +- URL syncing functions properly +- Inbox displays tasks and allows interaction +- No console errors + +--- + +## Key Principle + +**Bottom-up migration:** Start at the root (units/index), work down to the child (inbox). Each PR is +independently testable and valuable even if later ones are delayed. diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/INBOX_MIGRATION_INVESTIGATION.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/INBOX_MIGRATION_INVESTIGATION.md new file mode 100644 index 00000000..7f9a9e3b --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/INBOX_MIGRATION_INVESTIGATION.md @@ -0,0 +1,117 @@ +--- +title: Inbox Migration Investigation Report +description: Investigation report for the inbox component migration from AngularJS to Angular +--- + +# Inbox Migration Investigation Report + +**Date:** January 08, 2026 +**By:** Husainuddin Mohammed, 223380186 +**Task:** Investigate inbox component migration from AngularJS to Angular + +--- + +## What I Found + +The inbox component has already been migrated to Angular (`InboxComponent`), but it can't work +standalone because it depends on data from two AngularJS parent states. + +**Component dependency diagram:** + +``` +units/index (AngularJS parent) + ↓ provides: unit, unitRole +units/tasks (AngularJS parent) + ↓ provides: taskData +inbox (Angular component - already exists) + ↓ needs all the above data +``` + +The Angular component exists, but the parents feeding it data are still AngularJS. + +--- + +## Current State + +**What works:** + +- Angular InboxComponent exists (`.component.ts`, `.html`, `.scss`) +- Old AngularJS files still present (`.coffee`, `.tpl.html`) +- App loads via AngularJS route β†’ renders Angular component with scope data + +**What doesn't work:** + +- Can't create standalone Angular route +- Component expects `@Input()` data that comes from AngularJS parent scopes +- Creating Angular state without parents causes component to break + +--- + +## The Problem + +InboxComponent requires these inputs: + +- `unit: Unit` (from units/index parent) +- `unitRole: UnitRole` (from units/index parent) +- `taskData` object (from units/tasks parent) + +Without the parent data, the component has nothing to display. + +--- + +## Two Approaches + +### Approach 1: Keep Parents (Partial Migration) + +**What:** Keep AngularJS parents, only migrate inbox routing **Pros:** Quick, minimal changes +**Cons:** Still dependent on AngularJS, need to revisit later **Files to remove:** Just +`inbox.coffee` and `.tpl.html` + +### Approach 2: Migrate Everything (Complete Migration) + +**What:** Migrate both parent states first, then inbox **Pros:** Clean, fully Angular, no AngularJS +dependencies **Cons:** More work, needs parent migration first **Files to remove:** All inbox +AngularJS files after parents done + +--- + +## Recommended Path + +**Approach 2** is the right solution. Here's why: + +Both parent states (`units/index` and `units/tasks`) need migration anyway. If we do partial +migration now, we'll have to come back and redo work later when parents are migrated. + +**Migration order:** + +1. Migrate units/index parent +2. Migrate units/tasks parent +3. Clean up inbox (just delete old files) + +This is detailed in the full migration plan document. + +--- + +## Current Files + +**Angular (keep):** + +- `inbox.component.ts` +- `inbox.component.html` +- `inbox.component.scss` +- `inbox.component.spec.ts` + +**AngularJS (delete after parent migration):** + +- `inbox.coffee` +- `inbox.tpl.html` +- `inbox.scss` (old version) + +--- + +## Key Insight + +The inbox isn't really blocked by its own complexity - it's blocked by parent dependencies. Once +parents are migrated to Angular, finishing inbox is just cleanup (delete old files). + +The real work is in the parent migrations, which is covered in the full migration plan. diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/create-branch-and-initial-migration.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/create-branch-and-initial-migration.md new file mode 100644 index 00000000..3d1a97d8 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/create-branch-and-initial-migration.md @@ -0,0 +1,120 @@ +--- +title: Create Brance and Initial Migration +--- + +> Trimester 3 2022 + +**IMPORTANT!!! Make sure you already deploy OnTrack locally following +[Docker Setup Tutorial](/products/ontrack/documentation/front-end-migration/deploy-ontrack/docker-setup-tutorial).** + +--- + +## Create Branch in your Repo + +--- + +```console +git checkout development # make sure you are on develop +git pull --rebase upstream development # sync your local develop with upstream's +develop +``` + +```console +git fetch origin +``` + +![fetch thoth](/fetch_thoth.png) + +```console +cd doubtfire-web +git checkout -b migrate/not-found +``` + +![create branch](/create_branch.png) + +When click into the branch, you should see the newly created branch. + +![vscode_change_branch_1](/vscode_change_branch_1.png) +![vscode_change_branch_1](/vscode_change_branch_2.png) + +```console +git remote -v +``` + +![git remote](/git_remote.png) + +## Initial Migration + +--- + +### **1. Create a typescript, scss (if exists), and html file** + +For the Task Description Card we had the files: + +- not-found.coffee +- not-found.tpl.html +- not-found.scss + +**In the same folder we can start by creating the following files:** + +- not-found.component.ts +- not-found.component.html +- not-found.component.scss + +Notice the naming convention. When migrating a component we use the format name.component.extension. +Add the start of the TypeScript using something based on the following: + +![Start of the TypeScript](/start_typescript.png) + +We can’t see any of these changes yet, but it is a good clean start so let’s commit this before we +move on. + +```console +git add . +git commit -m "build: create initial files for migration” +git push --set-upstream origin touth/migrate/not-found +``` + +Then we should make sure to push this back to GitHub so others can see our progress. As this is a +new branch you will need to set the upstram branch, but if you forget the `git push` will remind you +anyway. + +![Push to origin](/push_to_origin.png) + +Run checkout to see the change. + +```console +git checkout +``` + +![git checkout](/git_checkout.png) + +### **2. Linking New and Unlink Old Module** + +In the ./src/app you should see + +![Dependency Injection](/Dependency_Injection.png) + +Because we want to migrate AngularJS to Angular, therefore we need to unlink the module from +AngularJS and link to Angular. + +1. Delete the import from related module from (doubtfire-web/src/app.doubtfire-angularjs.module.ts) + - ![delete import](/delete_import.png) +2. Import the newly created TypeScript component + - ![import new TS](/Import_TS_component.png) +3. Downgrade the TypeScript Component from (doubtfire-web/src/app.doubtfire-angularjs.module.ts) + - ![Downgrade](/downgrade.png) +4. Import the new Component to Angular + - ![Import new component to Angular](/import_to_angular.png) +5. Add to the Ng Module + - ![Inject to Ng module](/import_to_ng_module.png) +6. Delete module injection if neccessary (parent_folder_name/parent_folder_name.coffee) + - ![Delete injection](/delete_injection.png) + +--- + +## **Congratulations** + +It is **DONE** for the initial migration. At this stage, you will need to upskill yourself about +TypeScript, Angular and AngularJS and working in the code base and read the document about Regular +Migration. Good Luck! diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/readme.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/readme.md new file mode 100644 index 00000000..a9c97474 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/readme.md @@ -0,0 +1,10 @@ +--- +title: Steps For Migration +--- + +We have **two steps** for migration a component. + +## Steps + +1. [Create Branch](/products/ontrack/documentation/front-end-migration/migration/create-branch-and-initial-migration) +2. [Regular Commit](/products/ontrack/documentation/front-end-migration/migration/regular-migration-step) diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/regular-migration-step.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/regular-migration-step.md new file mode 100644 index 00000000..2e893379 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/regular-migration-step.md @@ -0,0 +1,43 @@ +--- +title: You should do this after Create the Branch and Finish the Initial Migration +--- + +> Trimester 2 2022 – SIT374 + +## Ensure you have your author credentials set up + +You should ensure your git user config details are set to the email address you use with GitHub: + +```shell +git config --global user.email "my-github-email@gmail.com" +git config --global user.name "Freddy Smith" +``` + +## Workflow Summary + +**Step 1.** Set up for new feature branch: + +````shell +git checkout development # make sure you are on develop +git pull --rebase upstream development # sync your local develop with + upstream's develop +git fetch thoth +git checkout -b my-new-branch # create your new feature branch``` +```` + +**Step 2.** Make changes, and repeat until you are done: + +````shell +git add ... +git commit +git push # make changes, commit, and push to origin``` +```` + +**Step 3.** Submit a pull request and if unable to merge: + +```shell +git pull --ff upstream development # merge upstream's develop in your feature branch +git add ... +git commit # resolve merge conflicts and commit +git push origin # push your merge conflict resolution to origin +``` diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/task-dashboard-investigation.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/task-dashboard-investigation.md new file mode 100644 index 00000000..36b0954f --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/task-dashboard-investigation.md @@ -0,0 +1,158 @@ +--- +title: Task-Dashboard Migration Investigation +description: + Investigation report for completing the task-dashboard migration from AngularJS to Angular +--- + +# Task-Dashboard Migration Investigation + +**Date:** January 19, 2026 +**Investigator:** Husainuddin Mohammed, 223380186 +**Branch:** `investigate/task-dashboard-migration` + +--- + +## What I Found + +The task-dashboard migration is about 80% done. The Angular components exist and work (I can see +them running in `inbox.component.html`), but the main dashboard view still loads the old AngularJS +directives. We have two parallel systems running. + +--- + +## The Actual Components + +I went through the code and found these 7 card components that got migrated: + +1. TaskDescriptionCardComponent +2. TaskDueDateCardComponent +3. TaskResourcesCardComponent +4. TaskSubmissionCardComponent +5. TaskCommentsCardComponent +6. TaskStatusCardComponent +7. TaskAssessmentCardComponent + +All work fine - just need to finish switching the main dashboard over to use them. + +--- + +## What Needs to Change + +**Template update:** + +- `dashboard.tpl.html` still uses `` +- Needs to change to `` + +**State registration:** + +- Old AngularJS state in `doubtfire.states.ts` needs updating +- Should register Angular component route instead + +**Module cleanup:** + +- `doubtfire-angularjs.module.ts` still imports 9 old .coffee files +- Can remove these imports and delete the files + +**Files to delete (9 total):** + +- task-dashboard: `.coffee`, `.tpl.html`, `.scss` +- student-task-list: `.coffee`, `.tpl.html`, `.scss` +- dashboard: `.coffee`, `.tpl.html` +- `directives.coffee` + +--- + +## Why It's Tricky + +These changes need to happen together. If I update the template but not the state registration, +routing breaks. If I delete files before updating the template, the dashboard stops loading. Can't +split this into many small PRs - it's one atomic change. + +--- + +## Current vs Target State + +**Right now:** + +``` +dashboard.tpl.html β†’ β†’ AngularJS system (old) +inbox.component.html β†’ β†’ Angular system (new) + ↓ + Both render same 7 cards +``` + +**After migration:** + +``` +dashboard.tpl.html β†’ β†˜ + Angular system (unified) +inbox.component.html β†’ β†— + ↓ + 7 card components + +Old AngularJS files deleted βœ“ +``` + +--- + +## Migration Steps + +``` +Step 1: Update template tags + ↓ +Step 2: Update state registration } These 3 steps + ↓ } must happen +Step 3: Remove old file imports } together + ↓ +Step 4: Delete old files +``` + +**Can't do Step 4 before Steps 1-3** β†’ Dashboard won't load +**Can't do Step 2 before Step 1** β†’ Router looks for wrong component + +--- + +## Risk Level: Low + +The Angular components already work. This is just switching which template system renders them. If +something breaks, we can revert quickly since the old files are still in git history. + +Main risk: making sure no other files reference `` besides the main dashboard +template. + +--- + +## Testing Needed + +- Direct URL navigation to dashboard +- Click navigation from project list +- Task selection and switching +- Browser refresh while on dashboard +- Back/forward buttons +- Check all 7 cards render +- Console should be clean + +--- + +## What Could Go Wrong + +**Scenario 1:** Another file uses old tags we missed + +- Fix: Search codebase for `` before starting + +**Scenario 2:** Delete files before updating imports + +- Fix: Remove imports first, then delete files + +**Scenario 3:** Update state before template + +- Fix: Always update template first + +--- + +## Time Estimate + +4-6 hours for someone who knows the codebase. +8-12 hours if you're new to it. + +Most of the time will be testing different navigation paths. diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/task-dashboard-pr-plan.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/task-dashboard-pr-plan.md new file mode 100644 index 00000000..cf623987 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Migration/task-dashboard-pr-plan.md @@ -0,0 +1,152 @@ +--- +title: Task-Dashboard Migration PR Plan +description: Plan for completing the task-dashboard migration +--- + +# Task-Dashboard Migration - PR Plan + +**Created:** January 19, 2026 +**Created by:** Husainuddin Mohammed, 223380186 + +--- + +## Approach: 2 PRs + +After analyzing the code dependencies, I'm proposing 2 PRs instead of splitting this into many small +ones. + +--- + +## PR 1: Investigation & Documentation + +**Branch:** `investigate/task-dashboard-migration` (CURRENT) +**Status:** Complete + +Documents the current state and migration plan for next cohort. + +**Files:** + +- `task-dashboard-investigation.md` +- `task-dashboard-pr-plan.md` + +--- + +## PR 2: Complete Migration + +**Branch:** `migrate/complete-task-dashboard` +**Status:** Not Started + +**Changes needed:** + +1. **Update template** (`dashboard.tpl.html`): + + ```diff + - + + + ``` + +2. **Update state** (`doubtfire.states.ts`): + - Register Angular component route + - Remove old AngularJS state + +3. **Clean up module** (`doubtfire-angularjs.module.ts`): + - Remove imports for 9 old files + +4. **Delete old files** (9 total): + - task-dashboard: `.coffee`, `.tpl.html`, `.scss` + - student-task-list: `.coffee`, `.tpl.html`, `.scss` + - dashboard: `.coffee`, `.tpl.html` + - `directives.coffee` + +5. **Update docs** (`README.md`): + - Mark completed: dashboard.coffee, directives.coffee, task-dashboard.coffee + +--- + +## Why These Changes Must Be Together + +``` +Change 1: Update template to + ↓ + └─→ If we stop here, state registration still points to old directive + Result: Routing fails βœ— + +Change 2: Update state registration + ↓ + └─→ If we stop here, module still imports old files + Result: Build warnings βœ— + +Change 3: Remove old imports + ↓ + └─→ If we stop here, old files still exist but aren't used + Result: Confusing codebase βœ— + +Change 4: Delete old files + βœ“ Complete migration +``` + +**These are interdependent, not independent tasks.** Splitting them creates broken intermediate +states that don't work or make sense. + +--- + +## Dependency Flow + +``` +Current State: + dashboard.tpl.html β†’ β†’ AngularJS directive + ↓ + Old .coffee files + ↓ + Works but outdated + +Target State: + dashboard.tpl.html β†’ β†’ Angular component + ↓ + 7 card components + ↓ + Old files deleted βœ“ +``` + +**Risk if split:** Each intermediate step leaves the codebase in a half-migrated state. + +--- + +## Testing Plan + +**Navigation testing:** + +- Direct URL: `/projects/123/dashboard` +- From project list β†’ dashboard +- Dashboard β†’ select task β†’ back to dashboard +- Browser refresh while on dashboard +- Back/forward buttons + +**Functionality testing:** + +- All 7 card components render +- Task switching works +- Data loads correctly +- Console has no errors + +**Build testing:** + +- Build succeeds +- No import errors +- No missing file errors + +--- + +## Rollback Strategy + +If issues arise, revert the single PR. Old files remain in git history and can be restored quickly. + +**Why atomic changes matter:** One revert fixes everything vs. figuring out which of 5 PRs to +revert. + +--- + +## Key Insight for Next Cohort + +Search the codebase for `` before starting - make sure dashboard.tpl.html is the +only place using the old tag. Update module imports before deleting files to avoid build failures. diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Research & Findings/spike-outcome-data-analytics.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Research & Findings/spike-outcome-data-analytics.md new file mode 100644 index 00000000..83a13a9a --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Research & Findings/spike-outcome-data-analytics.md @@ -0,0 +1,46 @@ +--- +title: Spike Outcomes +--- + +================== + +**Spike:** Spike_No + +**Title:** Data Analytics Spike + +**Author:** Dylan Sutherland, + +## Goals / Deliverables + +Summarise from the spike plan goal*Besides this report, what else was created ie UML, code, reports* + +- Data Analytics backlog on Trello + +## Technologies, Tools, and Resources used + +List of information needed by someone trying to reproduce this work\ + +- Internet Browser; Google Chrome, FireFox, Safari + +## Tasks undertaken + +List key tasks likely to help another developer + +- Engaged in Discussion with Andrew Cain +- Created a Trello backlog for the continued development of Data Analytics + +## What we found out + +The Data Analytics feature as it currently exists in OnTrack provides a limited set of +visualisations given the data available. The current visualisations are: Target Grade Pie Chart, +Task Status Pie Chart & Task Completion Box Plot. For the future development of Data Analytics, +although integrated visualisations will continue to play a key role in providing a quick overview of +the data, the ability to export the data to a third party tool such as Tableau or PowerBI will be a +key feature. This will allow for more complex visualisations to be created and for the data to be +analysed in more depth. The current visualisations will need to be migrated to the latest version of +Angular and maintained as they provide a quick overview of the data. One particular area where the +current visualisations are lacking is the ability to track interaction time such as tutor time to +provide task feedback, this is a key visualisation which could be added to the existing +visualisations. In parallel to extending the current visualisations, the requirements of the export +feature will be investigated including a questionnaire to understand the needs of Unit chairs and +tutors, before designing UML diagrams and implementing the feature. diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Research & Findings/testing-decision.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Research & Findings/testing-decision.md new file mode 100644 index 00000000..2c9a053c --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Research & Findings/testing-decision.md @@ -0,0 +1,101 @@ +--- +title: What is the current state of testing? +--- + +In this issue, we will discuss the current state of testing and what tools are we proposing. While +there are some existing unit tests for components written in TypeScript, there are no existing unit +tests for the CoffeeScript components. Existing tests use Karma test runner integrated with Jasmine. +Currently, the ng test command (Runs unit tests in a project) and npm install are not working due to +dependencies issues, which are getting fixed. + +## Comparing different alternatives + +## Cypress + +## Pros + +-Selenium involves implementing browser drivers for the script to communicate with the web elements +on the page. -Cypress is used by both developers and QA engineers -In Cypress, there is no +additional IDE overhead. When you launch Cypress, it asks you to select an IDE to modify the test +script. -The Cypress framework produces more accurate results. It’s because Cypress has greater +control over the entire automation process. -Cypress instances respond in real-time to application +events and commands. -Cypress does not utilize WebDriver for testing or doesn't send the command to +the browser using a specific driver. If your language can someway be transpiled to JS, it can use +DOM events to send the click command to the button or such. This results in a much faster execution +of test results + +## Cons + +-Cypress is a test runner mainly focused on end-to-end tests. For unit testing, there are better, +faster alternatives. -Cypress is currently only supported for the Chrome, Firefox, Edge, Brave, and +Electron browsers. -As a result, Cypress is a less favoured option for cross-browser testing. -For +the building of test cases, it only supports the JavaScript framework. -Cypress doesn’t support +remote execution. + +## Selenium + +### \*Pros + +-Selenium is an Open Source Software. -Selenium supports various programming languages to write +programs (Test scripts) -Selenium supports various operating systems (MS Windows, Linux, Macintosh +etc...) -Selenium supports various Browsers (Mozilla Firefox, Google Chrome, IE, Opera, Safari +etc...) -Selenium supports Parallel Test Execution. -Selenium uses fewer Hardware resources. -Good +choice for ongoing regression testing and end to end testing. + +### \*Cons + +-No reliable Technical Support from anybody. -It supports Web-based applications only. -Difficult to +use, and takes more time to create Test cases. Takes more time to learn. -Difficult to set up Test +Environment when it compares to Vendor Tools like UFT, RFT, SilkTest etc... -Limited support for +Image Testing. -No Built-in Reporting facility. -Slow -Better choice for end-to-end testing than +unit testing. + +## Jest + +### -Pros + +-The biggest advantage of using Jest is minimal setup or configuration. -It comes with an assertion +library and mocking support -The tests are written in BDD style -You can put your tests inside of a +directory called tests or name them with a .spec.js or .test.js - extension, then run jest and it +works -Jest also supports snapshot testing + +### -Cons + +-Jest’s biggest weaknesses stem from being newer and less widely used among JavaScript developers. +-It has less tooling and library support available compared to more mature libraries (like Mocha). +-WebStorm didn’t even support running Jest tests. -Due to its young age, it may also be more +difficult to use Jest across the board for larger projects that utilize different types of testing. +-Slower due to auto mocking -Poor documentation + +## Karma + Jasmine + +### `Pros + +-When creating Angular projects using the Angular CLI, Jasmine and Karma are used to create and run +unit tests by default. -Karma is a test runner built by the angularJS to make TDD easy in Angular +Project Testing. -Karma is a JavaScript test runner that fits the needs of an AngularJS developer. +-Jasmine is compatible with almost every framework or library of your choice - The Jasmine BDD +library makes it easy to define tests, run them, and integrate them -Jasmine does not rely on any +JavaScript framework, DOM, or browsers. -We can run Jasmine tests in a browser ourselves by setting +up and loading an HTML file, but more commonly we use a command-line tool called Karma. -Karma +handles the process of creating HTML files, opening browsers and running tests and returning the +results of those tests to the command line. -If you use the Angular CLI to manage projects it +automatically creates stub Jasmine spec files for you when generating code. -It also handles the +Karma configuration, transpilation and bundling of your files -It offers clean and polished syntax. +-Jasmine provides a rich set of built-in matchers that can match expectations and add asserts to the +test cases + +## `Cons + +-Asynchronous testing can be a bit of a headache -js is required for running Karma -Expects a +specific suffix to all test files (\*spec.js by default) + +## Proposal + +Karma handles the process of creating HTML files, opening browsers and running tests and returning +the results of those tests to the command line. When using Angular CLI to manage projects it +automatically creates stub Jasmine spec files for you when generating code. On top of that, it is +already implemented in our code base. It goes well with our TDD approach. It will also be efficient +for unit testing and requires minimal configurations so that we can spend more time on coding and +quality testing itself. Additionally, there is also good online documentation and resources +available for training. diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Testing/unit-test.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Testing/unit-test.md new file mode 100644 index 00000000..a44f29af --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/Testing/unit-test.md @@ -0,0 +1,45 @@ +--- +title: Unit Test +--- + +```javascript +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NotFoundComponent } from './not-found.component'; + +describe('NotFoundComponent', () => { + let component: NotFoundComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [NotFoundComponent], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(NotFoundComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); +``` + +_Replace the (NotFoundComponent) component name with your choosen compoent name._ + +```shell +npm install +npm test +``` + +![unit test terminal output](/src/assets/migration-unit-test/unit_test_terminal_output.png) + +```shell +git add . +git commit -m β€œMigrate: Add unit test” +git push +``` diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/component-review-create-unit-modal.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/component-review-create-unit-modal.md new file mode 100644 index 00000000..50e10e4e --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/component-review-create-unit-modal.md @@ -0,0 +1,54 @@ +--- +title: Component Review - Create unit Modal +--- + +## Student Name: Gaganjeet Singh + +## Student ID: 220032936 + +First select a component to review from the list below: + +[https://deakin365.sharepoint.com/:x:/r/sites/ThothTech2/Shared%20Documents/OnTrack%20-%20UI%20Enhancement/T3_2022/Management%20%5BT3_2022%5D/selected_task(revised).xlsx?d=wac02013da5224c958ac60fd96fac7b20&csf=1&web=1&e=UfCmZ5]() + +## Component Name + +\*\*\*\*./src/app/admin/modals/create-unit-modal/create-unit-modal.coffee + +File Name: create-unit-modal.coffee + +## Component purpose + +It is used to create a new unit + +## Component outcomes/interactions + +It creates a new unit. + +![existing modal](/Image/ComponentReviewCreateUnitModal.png) + +Currently, the modal had 2 text input fields unit code and unit name. In the new modal a 3rd dorp +down field is to be added, teaching period. + +So, in the updated modal the user provides the following: + +1. Unit Code +2. Unit Name +3. Teaching period + +New design sketch: Existing UI components are to be used for the input fields and button etc. + +![new modal sketch](/Image/ComponentReviewCreateUnitModal.png) + +Link to figma: +[here]() + +**Component migration Check list** – What is needs to be checked for this component to work once +migrated? + +[ ] ability to collect details from the user + +[ ] succeeds when data is valid + +[ ] handles errors - duplicate unit code in the teaching period, or invalid dates + +[ ] created unit is shown on success diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/local-storage.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/local-storage.md new file mode 100644 index 00000000..1abd3c74 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/local-storage.md @@ -0,0 +1,46 @@ +--- +title: Ontrack Component review +--- + +## Student Name: Aryan Bagoria + +## Student ID: 22107150 + +First select a component to review from the list below: + +[https://deakin365.sharepoint.com/:x:/r/sites/ThothTech2/Shared%20Documents/OnTrack%20-%20UI%20Enhancement/T3_2022/Management%20%5BT3_2022%5D/selected_task(revised).xlsx?d=wac02013da5224c958ac60fd96fac7b20&csf=1&web=1&e=UfCmZ5]() + +## Component Name + +local-storage.coffee - doubtfire-web/src/app/config/local-storage/local-storage.coffee + +Relevant files: + +- `local-storage.component.ts` + +## Component purpose + +this component local-storage.coffee is used to configures 'localstorage' usage in the application + +![local-congig](/local-config.png) + +## Component outcomes/interactions + +Basically, this component is used to configure the "localstorage" usage, which is used to set up the +prefix on the key-value pair that gets stored in the web browser's local storage. for example: (user +id, email), (login time), and (credentials token). + +## Component migration plan + +As this is a non visual componet which just configures local-storage, so for that i will be creating +a new Typescript file local-storage.component.ts and remove the old local-storage.coffee file. + +**Component review checklist** – What is needs to be checked for this component to work once +migrated? + +once migrated we need to check whether the code compiles without any errors or warnings. + +## Discussion with Client (Andrew Cain) + +See if the component is still needed and present this document so Andrew can review if all the +outcomes and interactions are correct prior to the migration and build of this component. diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/on-long-press.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/on-long-press.md new file mode 100644 index 00000000..4d4b0af9 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/on-long-press.md @@ -0,0 +1,50 @@ +--- +title: Ontrack Component review +--- + +## Student Name: Aryan Bagoria + +## Student ID: 221071501 + +First select a component to review from the list below: + +[https://deakin365.sharepoint.com/:x:/r/sites/ThothTech2/Shared%20Documents/OnTrack%20-%20UI%20Enhancement/T3_2022/Management%20%5BT3_2022%5D/selected_task(revised).xlsx?d=wac02013da5224c958ac60fd96fac7b20&csf=1&web=1&e=UfCmZ5]() + +## Component Name + +on-long-press - doubtfire-web/src/app/common/long-press/on-long-press.coffee + +Relevant files: + +- `on-long-press.component.ts` +- `on-long-press.coponent.html` +- `on-long-press.coponent.scss` + +## Component purpose + +this component on-long-press can detect when a user touches and holds a button for a certain amount +of time (600 milliseconds by default). When this happens it can trigger certain action.this +functionality can be added to any element as an attribute. + +## Component outcomes/interactions + +Basically, this component is used to trigger a special action that can be defined for any element +such as a button. This is useful for touch-based 、interfaces for example on mobile devices, where +holding down on an element can perform a specific action. + +## Component migration plan + +As this is a non visual componet that has a functionality to detect long presses which can be added +to any element as an attribute So I will be converting the old coffee file into .ts file and an html +file to create a button that uses the onLongPress directive to trigger a long press event. + +## Component review checklist + +What is needs to be checked for this component 、to work once migrated? + +once migrated we need to check whether the code compiles without any errors or warnings. + +## Discussion with Client (Andrew Cain) + +See if the component is still needed and present this document so Andrew can review if all the +outcomes and interactions are correct prior to the migration and build of this component. diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/teching-period-breaks.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/teching-period-breaks.md new file mode 100644 index 00000000..0d861b30 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/teching-period-breaks.md @@ -0,0 +1,54 @@ +--- +title: OnTrack Component Review +--- + +## Team Member + +Matt Kinnia + +## Component + +`teaching-period-breaks` + +Relevant files: + +- `teaching-period-breaks.coffee` +- `teaching-period-breaks.tpl.html` + +## Component Purpose + +The purpose of the component is to display the breaks that have been registered against a teaching +period. It also allows the user to sort the list by different criteria. + +![teaching-period-breaks](/teaching-period-breaks.png) + +## Component Outcomes and Interactions + +The expected outcome of the component is to provide a user-friendly interface for managing breaks +registered against a teaching period, allowing the user to quickly find and view information about +specific breaks. + +Interaction occurs with the user through filtering and pagination controls. A button is clickable +which invokes the `CreateBreakModal` (which is out of scope for this review). + +The component takes in a `teachingPeriod` object where its properties are used to display +information in the user interface. + +## Component Migration Plan + +The migration plan is to review similar tabular based components that have already been migrated to +TypeScript and Material UI. + +For example, the `unit-students-editor` component. Based on this review, migrate the component in +such a way that is in line with the previous works to maintain consistency. + +`unit-students-editor` + +![unit-students-editor](/unit-students-editor.png) + +## Component Post-Migration + +The work required to migrate the component is now complete and the migrated component is shown +below. + +![teaching-period-breaks-migrated](/teaching-period-breaks-migrated.png) diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/teching-period-details-editor.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/teching-period-details-editor.md new file mode 100644 index 00000000..50b7a616 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/teching-period-details-editor.md @@ -0,0 +1,49 @@ +--- +title: OnTrack Component Review +--- + +## Team Member + +Matt Kinnia + +## Component + +`teaching-period-details-editor` + +Relevant files: + +- `teaching-period-details-editor.coffee` +- `teaching-period-details-editor.tpl.html` + +## Component Purpose + +The purpose of the component is to edit the details for a teaching period. It also allows the user +to update key properties of a teaching period, such as the name and length. + +![teaching-period-details-editor](/teaching-period-details-editor.png) + +## Component Outcomes and Interactions + +The expected outcome of the component is to provide a user-friendly interface for updating the key +properties of a teaching period. + +Interaction occurs with the user through a form which contains a series of text and date inputs. + +## Component Migration Plan + +The migration plan is to review similar form based components that have already been migrated to +TypeScript and Material UI. + +For example, the `edit-profile-form` component. Based on this review, migrate the component in such +a way that is in line with the previous works to maintain consistency. + +`edit-profile-form` + +![edit-profile-form](/edit-profile-form.png) + +## Component Post-Migration + +The work required to migrate the component is now complete and the migrated component is shown +below. + +![teaching-period-details-editor-migrated](/teaching-period-details-editor-migrated.png) diff --git a/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/teching-period-units.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/teching-period-units.md new file mode 100644 index 00000000..e4513c3e --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/UI Enhancement/teching-period-units.md @@ -0,0 +1,56 @@ +--- +title: OnTrack Component Review +--- + +## Team Member + +Matt Kinnia + +## Component + +`teaching-period-units` + +Relevant files: + +- `teaching-period-units.coffee` +- `teaching-period-units.tpl.html` + +## Component Purpose + +The purpose of the component is to display the units that have been registered against a teaching +period. It also allows the user to search for specific units, sort the list by different criteria, +and navigate to a unit detail view. + +![teaching-period-units](/teaching-period-units.png) + +## Component Outcomes and Interactions + +The expected outcome of the component is to provide a user-friendly interface for managing units +registered against a teaching period, allowing the user to quickly find and view information about +specific units. + +Interaction occurs with the user through filtering and pagination controls. Each table row is +clickable, which links to the unit detail page. A button is clickable which invokes the +`RolloverTeachingPeriodModal` (which is out of scope for this review). + +The component takes in a `teachingPeriod` object where its properties are used to display +information in the user interface. + +## Component Migration Plan + +The migration plan is to review similar tabular based components that have already been migrated to +TypeScript and Material UI. + +For example, the `unit-students-editor` component. Based on this review, migrate the component in +such a way that is in line with the previous works to maintain consistency. + +`unit-students-editor` + +![unit-students-editor](/unit-students-editor.png) + +## Component Post-Migration + +The work required to migrate the component is now complete and the migrated component is shown +below. + +![teaching-period-units-migrated](/teaching-period-units-migrated.png) diff --git a/src/content/docs/products/ontrack/documentation/front-end-migration/introduction.md b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/introduction.md similarity index 79% rename from src/content/docs/products/ontrack/documentation/front-end-migration/introduction.md rename to src/content/docs/Products/OnTrack/Documentation/Front End Migration/introduction.md index e5c265b9..8cf6abe1 100644 --- a/src/content/docs/products/ontrack/documentation/front-end-migration/introduction.md +++ b/src/content/docs/Products/OnTrack/Documentation/Front End Migration/introduction.md @@ -20,7 +20,6 @@ trying to keep things more up to date going forward. --- 1. Testing new branch - - We have a special request from our director Andrew that we need to execute some on testing the doubtfire-web(quality/entity-service-to-npm) branch with doubtfire-api(refactor/entity-service-backend), write up some test scripts for people to run to @@ -30,7 +29,6 @@ trying to keep things more up to date going forward. and report to director 2. Components Migration - - There is **168 components** waiting to be migrated, in T3/2022, I hope we can continue the work that we left in previous trimester and assign some simple components for Juniors. Delivery lead should involve continuing the ongoing components, seniors should continue his work from @@ -73,23 +71,33 @@ As a junior we suggest that you should: inistall a **WSL2 virtual machine**. Make sure you dont have VMware or VirtualBox installed that will enable the HyperV feature which **conflict** with Docker. - **Windows (WSL2)** - 1. Follow [Docker Compose with WSL2](Docker/Docker_Compose_with_WSL2.md) guideline. - 2. Read [Docker Setup Tutorial](Docker/Docker_Setup_Tutorial.md) guideline. + 1. Follow + [Docker Compose with WSL2](/products/ontrack/documentation/front-end-migration/deploy-ontrack/docker-compose-with-wsl2) + guideline. + 2. Read + [Docker Setup Tutorial](/products/ontrack/documentation/front-end-migration/deploy-ontrack/docker-setup-tutorial) + guideline. 3. Watch [Docker Setup Tutorial](https://drive.google.com/file/d/16A5zzG3g0S1B0PCKWrFK9anLhheXgi_b/view?usp=sharing) > Please note that the tutorial used Windows CMD enviroment, it should use WSL2 machine > instead. See the > [issue](https://teams.microsoft.com/l/message/19:bd20175d09414f079490a2403f7fca74@thread.tacv2/1659408245022?tenantId=d02378ec-1688-46d5-8540-1c28b5f470f6&groupId=0e15669c-3f66-49aa-b023-640fe1dda2e0&parentMessageId=1659398288375&teamName=Thoth). - **Mac / Linux** - 1. Read [Docker Setup Tutorial](Docker/Docker_Setup_Tutorial.md) guideline. + 1. Read + [Docker Setup Tutorial](/products/ontrack/documentation/front-end-migration/deploy-ontrack/docker-setup-tutorial) + guideline. > If the servers in the docker running into issues, please follow the backup plan - - > [Troubleshooting Docker - Backup for OnTrack](Docker/Troubleshooting_Docker_Backup_for_OnTrack.md) + > [Troubleshooting Docker - Backup for OnTrack](/products/ontrack/documentation/front-end-migration/deploy-ontrack/troubleshooting-docker-backup-for-ontrack) 3. Migration - 1. Read [Create Brach and Initial Migration](Migration/Create_Branch_and_Initial_Migration) + 1. Read + [Create Brach and Initial Migration](/products/ontrack/documentation/front-end-migration/migration/create-branch-and-initial-migration) + guideline. + 2. Read + [Regular Commit](/products/ontrack/documentation/front-end-migration/migration/regular-migration-step) guideline. - 2. Read [Regular Commit](Migration/Regular_Migration_Step.md) guideline. 4. Testing - 1. Read [Unit Test](Testing/Unit_Test.md) guideline. + 1. Read [Unit Test](/products/ontrack/documentation/front-end-migration/testing/unit-test) + guideline. 5. Do **report any issue** or questions to the senior or deilvery lead. 6. **Writting docemnts** during the learning process which you found intresting or worth to know. 7. Start to migrate some simple components. diff --git a/src/content/docs/Products/OnTrack/Documentation/Incorporate Content Ontrack/design-document.md b/src/content/docs/Products/OnTrack/Documentation/Incorporate Content Ontrack/design-document.md new file mode 100644 index 00000000..0263b8ea --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Incorporate Content Ontrack/design-document.md @@ -0,0 +1,173 @@ +--- +title: Design Documentation:Incorporate Content in OnTrack +--- + +Author: Devanshi Patel + +Company: Thoth Tech + +## Introduction + +This document outlines the design approach for the feature called β€˜Incorporate Content in OnTrack.’ +This feature will be implemented in Ontrack application, which is known as the main source for +course management system for students. This feature aims to provide better flexibility and +performance by allowing unit chair to host content within Ontrack for students to access. This +feature will not only enable unit chair to host content within OnTrack but also organise content, +search content and update content all within OnTrack. This design document will outline error +handling and validations, testing and technical aspects of the application. + +## User Story + +As a unit chair I want to host content within OnTrack and as a student I want to access the content +within OnTrack. + +## Architecture + +The feature β€˜incorporate content in OnTrack’ will be smoothly added to the existing architecture of +the system. This architecture will have frontend and backend component which will uphold the feature +flexibility. + +## Frontend Implementation + +In the frontend, an additional button will be added under the dashboard for both unit chair and +students. For unit chair, the button will open the content page within OnTrack, which allow unit +chair to add content, and make any updates to the content which has been hosted. Additionally, unit +chair can set time and date to when the content should go live, which falls under the organise +content. For students, under the dashboard a new button will be added which will allow them to +access the content as well as search any content and lastly download relevant content to their +device. + +### UI Integration + +When building the application, make sure the design follows the Tailwind CSS, which can provide +better user-friendly experience. Additionally, use Angular component when adding the user interface +element in the application. + +## Backend Implementation + +Make changes to the API endpoint which validates user inputs, along with those API that allows unit +chair to host content, organise content, update content and also access permission. In terms of +student, make changes to API which allows them to access the content, download content and search +content. + +### Database + +Should keep a record of when unit chair add content and last made changes to the content. Use Maria +DB for data management. + +### User Authentication + +Make sure that only authenticate unit chair for certain unit is allowed to host the content. + +## Database Design + +- **Table:** Create a table called β€˜ContentRecord’ which stores all the information about when the + unit chair hosted content within OnTrack and when last modified. + +**Column:** + +- **Unit_chair_Id:** The unit chair who hosted the content. +- **time:** What time the content was hosted within OnTrack. +- **date:** The day the content was hosted within OnTrack. +- **Last_modified:** The date and time unit chair made changes to the content. + +## Validation + +- **Error messages:** Display error messages in its relevant place when unit chair puts irrelevant + date for when the content should be seen on the OnTrack application. +- **API validation:** Validate that the input from the frontend is appropriate and that it meets the + requirement. + +## Exception handling + +Ensure that server-side error is implemented in its place for handling errors that can occur during +the process. Additionally, keep record of the errors that occur during the process for debugging +purposes. + +## Testing + +### Test Case 1: Add content within OnTrack + +Description: Making sure that unit chair can add content in the system + +Steps: + +1. Open Ontrack +1. Go to Dashboard, click on add content. +1. Pick the files which you want to upload. +1. Pick the date you want to upload the content. +1. Click Host. + +Expected outcome: Adding content is successful and now students will be able to view the content +within OnTrack. + +### Test Case 2: Edit content within OnTrack + +Description: Allow unit chair to edit the content within OnTrack. + +Steps: + +1. Access the content which needs editing. +1. Click on the content and start editing. +1. Click save once done. + +Expected Outcome: New version will be uploaded in OnTrack which can be viewed by the student. + +### Test case 3: Unauthorized Access + +Description: Making sure that only unit chair can host the content within OnTrack. + +Steps: + +1. If anyone attempts to access the host content functionality without any authentication. + +Expected Outcome: A error message will display on the screen. + +### Test Case 4: Student can view content + +Description: Making sure that students can view the content within OnTrack + +Steps: + +1. Login to OnTrack +1. Navigate to dashboard and click on content. +1. Start viewing certain content. + +Expected Outcome: It will allow students to have access to the content which was added by the unit +chair. Additionally have the task sheet and the content in one place. + +## Deployment + +Deployment plan will outline how steadily the new feature called β€˜Incorporate Content in OnTrack’ +will be introduced in the current system of OnTrack. + +- Have a backup copy of the existing system for any risk that can occur during the deployment stage. +- Run testing for both frontend and backend to identify any issues. +- Ensure that the code follows the standards and its best practices. +- Make announcement to students and unit chairs about the new feature, along with any downtime when + the deployment process is taking place. +- Include instructions for unit chair on how to use the new feature. +- Record the new feature during the first few days for any problems that can occur. + +### Frontend Deployment + +Deploy frontend into production server and ensure that the new feature is smoothly integrated into +the existing system. + +### Backend Deployment + +Deploy backend into production server and keep record of any errors that can occur during the +process of deployment. Additionally ensure that the new feature is smoothly integrated into the +existing system. + +## Conclusion + +The new feature β€˜incorporate content in OnTrack’ will allow unit chairs to host content within +OnTrack, which will be accessible by the students. Additionally, it will allow unit chair to make +changes to the content that is already visible to the students, along with organising when certain +content should be make visible in the OnTrack application. This design documents outlines how the +feature will be integrated into OnTrack system. The design documents shows that performance, +reliability, and usability will be upheld for better user experience. + +By incorporating this new feature within the existing OnTrack, allows students to view both the +content and task sheet for that unit in place, which upheld the flexibility aspect of this feature. diff --git a/src/content/docs/Products/OnTrack/Documentation/Incorporate Content Ontrack/gather-requirements.md b/src/content/docs/Products/OnTrack/Documentation/Incorporate Content Ontrack/gather-requirements.md new file mode 100644 index 00000000..f4bb187d --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Incorporate Content Ontrack/gather-requirements.md @@ -0,0 +1,122 @@ +--- +title: Gather Requirements:Incorporate content in OnTrack +--- + +Author: Devanshi Patel + +Company: Thoth Tech + +## Introduction + +This documentation outlines the requirements for implementing a feature called β€˜Incorporate content +in OnTrack.’ This feature will be implemented in the OnTrack application. This feature aims to +provide better flexibility by allowing unit chair to add content in one place where it makes easier +for students to access both the content and the task sheet for the unit in one place. + +## User Story + +As an OnTrack unit chair I want to be able to host content within Ontrack and as a student I want to +able to access the content within Ontrack. + +## Functional Requirements + +### Backend + +- Adjust the maria DB that are already in place. +- Keep all the record of when the unit chair adds content within Ontrack. + +### Frontend + +- Under the dashboard an interface should be added to the unit chair Ontrack screen that will allow + them to add content and hide certain content. +- Under the dashboard an interface should be added in the student end that will allow them to view + content. +- An interface should be added for searching relevant content. + +## Non-Functional Requirements + +### Performance + +- The feature should run smoothly and provide the best experience for both students and unit chairs. + +### Reliability + +- The feature should be able to handle failures and should recover quickly. +- ``Additionally, the feature should perform without failure for 95% of use cases. + +### Usability + +- The user interface should be consistent with its navigation and the overall design. +- The user interface should be user-friendly. +- The feature should require only minimum training for Unit chair. + +## Test cases + +### Test Case 1: Add content within OnTrack + +Description: Making sure that unit chair can add content in the system + +Steps: + +1. Open Ontrack +1. Go to Dashboard, click on add content. +1. Pick the files which you want to upload. +1. Pick the date you want to upload the content. +1. Click Host. + +Expected outcome: Adding content is successful and now students will be able to view the content +within OnTrack. + +### Test Case 2: Edit content within OnTrack + +Description: Allow unit chair to edit the content within OnTrack. + +Steps: + +1. Access the content which needs editing. +1. Click on the content and start editing. +1. Click save once done. + +Expected Outcome: New version will be uploaded in OnTrack which can be viewed by the student. + +### Test case 3: Unauthorized Access + +Description: Making sure that only unit chair can host the content within OnTrack. + +Steps: + +1. If anyone attempts to access the host content functionality without any authentication. + +Expected Outcome: A error message will display on the screen. + +### Test Case 4: Student can view content + +Description: Making sure that students can view the content within OnTrack + +Steps: + +1. Login to OnTrack +1. Navigate to dashboard and click on content. +1. Start viewing certain content. + +Expected Outcome: It will allow students to have access to the content which was added by the unit +chair. Additionally have the task sheet and the content in one place. + +## Testing + +- Setting up the environment for testing and ensuring that its functional. +- Opening terminal and navigate to the correct directory. +- Run the test. +- If all the tests are successful a message will display. +- If the tests are failed an error message will display, along with a description of why it failed. +- When troubleshooting, if the tests fail, review the error message, and identify what the issue + might be. +- Rerun the tests to see if it solved the issue. + +## Conclusion + +To conclude, this new feature β€˜Incorporate content in Ontrack’ will allow unit chairs to host +content within OnTrack. Which can be accessible by the students who are enrolled in the unit. +Therefore, this document outlines functional, non-functional requirements along with test cases +which can be used for testing the system amongst various scenarios. This document also outlines what +steps needs to be taken when performing the tests and how to handle issues when running the tests. diff --git a/src/content/docs/Products/OnTrack/Documentation/Incorporate Content Ontrack/incorporate-doc.md b/src/content/docs/Products/OnTrack/Documentation/Incorporate Content Ontrack/incorporate-doc.md new file mode 100644 index 00000000..8bbb2380 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Incorporate Content Ontrack/incorporate-doc.md @@ -0,0 +1,42 @@ +--- +title: Incorporate content in OnTrack +--- + +Author: Devanshi Patel + +This documentation outlines the functionality and the way the new feature is going to be implemented +on OnTrack that will enable unit chairs to host content on OnTrack, which can be accessible from the +students end. This feature aims to provide better flexibility by adding the content in one place +where it makes it easier for students to access both the content and the tasksheet for the unit in +one place. This documentation will outline what needs to be done to achieve this feature. + +## Requirements + +- Clearly define what the feature meant to do and the use case. +- Describe how the feature will interact with front-end and the back end? +- What changes need to be done in the backend to add this new feature. + +## Front end design + +- Design the overview of the front-end interface. +- Make adjustment to API, to ensure that the response is accurate. +- Create a test case for front end that upheld the user experience of the feature. + +## UML Diagram + +- Create a UML diagram that will show the flow of incorporating content on Ontrack and the flow + during the process. +- How it will interact with front end, backend as well as with other features that are already in + place. + +## Coding + +- Code the new feature, that will allow unit chairs to host content and make it accessible for + students to view. +- Code the part where it will allow student to access content from their end. + +## Testing + +- Create a test case for the backend, to ensure the data are correctly handled and ensure that the + request is handle in correct manner. +- Create a documentation that will outline the steps on how to conduct the test. diff --git a/src/content/docs/Products/OnTrack/Documentation/Incorporate Content Ontrack/uml-diagram.md b/src/content/docs/Products/OnTrack/Documentation/Incorporate Content Ontrack/uml-diagram.md new file mode 100644 index 00000000..bd87459d --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Incorporate Content Ontrack/uml-diagram.md @@ -0,0 +1,21 @@ +--- +title: UML diagram:Incorporate content in OnTrack +--- + +Author: Devanshi Patel + +Company: Thoth Tech + +## Introduction + +This Document outlines the flow of the new feature 'incorporate Content' into Ontrack. + +## Use Case Diagram + +- [UML - Incorporate Content] + () + +## UML Diagram + +- [UML - Incorporate Content] + () diff --git a/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/docker-containers-srs.md b/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/docker-containers-srs.md new file mode 100644 index 00000000..3ce36f26 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/docker-containers-srs.md @@ -0,0 +1,102 @@ +--- +title: + Jupyter Notebook/Word Document Docker Containers Software Requirement Specification (SRS) Document +--- + +## 1. Introduction + +### 1.1 Purpose + +Currently, when an end user wishes to upload a Jupyter Notebook file to OnTrack, they must first +manually convert the file to a PDF. The purpose of the Jupyter Notebook conversion feature is to +automatically perform the conversion of Jupyter Notebook files to PDF during the submission process. +During research for this feature it was determined that converting Word documents to PDF was an +extensible feature of the Jupyter Notebook conversion feature. Depending on the type of file that an +end user submits - if it is a Word document or a Jupyter Notebook file - one container will provide +the conversion function for the Jupyter Notebook, and the other container will provide the +conversion function for the Word document. Both containers will output a PDF file. + +### 1.2 Intended Audience + +The intended audience of this feature is all users of the OnTrack system (students and teachers). +This feature will allow all users to submit Jupyter Notebook and Word Document files to OnTrack +directly, instead of having to first manually convert the file to PDF and then submit that to +OnTrack. The feature will also allow users to view their converted file for review or marking. + +### 1.3 Intended Use + +The intended use of this feature is to provide the functionality for the mentioned conversions. The +user will submit either a Jupyter Notebook or a Word document file to OnTrack, and each container +will be used, depending on the file type, to make the necessary conversion of the submitted file to +PDF format. + +### 1.4 Scope + +This feature will be developed in steps: firstly we aim to develop standalone containers which +provide the feature, secondly they will be integrated into OnTrack thus completing the feature. The +scope during this trimester will be to create standalone Docker containers which can provide the +function of converting Jupyter Notebook or Word Document files to PDF format. Also within scope is +testing the containers and ensuring they conform to a testing strategy. + +### 1.5 Definitions and Acronyms + +- OnTrack – an online learning management system that provides task work to users and allows them to + submit work for feedback and assessment purposes. +- DOCX/DOC - a DOCX/DOC file is a document created by Microsoft Word, a word processor. DOCX/DOC + files typically contain text. +- IPYNB – an IPYNB (IPython notebook) file is a document created by Jupyter Notebook, an interactive + computational environment. IPYNB files can contain code input and output, formatted text, + mathematical functions, and images. +- PDF – a PDF (portable document format) file is a multi-platform document commonly used for saving + documents to be viewed on multiple platforms. +- Docker Container Image – a Docker Container Image is a lightweight, stand-alone, executable + package of software that includes everything needed to run an application: code, runtime, system + tools, system libraries and settings. + +## 2. Overall Description + +### 2.1 User Needs + +Users will need to be able to directly submit Jupyter Notebook and Word document files to OnTrack. +Both of these functionalities will be provided by the proposed containers. + +### 2.2 Assumptions and Dependencies + +- It is assumed that: + - The user submits a valid Jupyter Notebook/Word Document file to the OnTrack system. + - The user has a valid internet connection + - The user is aware of how to submit files to OnTrack +- The following dependencies are relied upon: + - The code of the OnTrack system + - Interface + +## 3. System Features and Requirements + +### 3.1 Functional Requirements + +- The successful conversion of Jupyter Notebook files to PDF format +- The successful conversion of Word document files to PDF format +- Redownloading submitted Jupyter Notebook files as a PDF +- Redownloading submitted Word document files as a PDF +- Viewing converted Jupyter Notebook file in Ontrack as a PDF +- Viewing converted Word document file in Ontrack as a PDF + +### 3.2 External Interface Requirements + +- nbconvert library +- Apache library +- Existing OnTrack libraries + +### 3.3 System Features + +- The ability to submit Jupyter Notebook files to OnTrack directly +- The ability to submit Word document files to OnTrack directly +- The ability to download/export converted files from OnTrack + +### 3.4 Nonfunctional Requirements + +- Reliability – The ability of the system to consistently perform its required functions under + stated conditions. +- Scalability – ability of software to be scaled to encompass project scope in its entirety +- Maintainability – ability of software to be maintained, ensuring consistent and upmost performance +- Usability – User standards diff --git a/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/docker-documentation-research-t1-2022.md b/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/docker-documentation-research-t1-2022.md new file mode 100644 index 00000000..38d238ee --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/docker-documentation-research-t1-2022.md @@ -0,0 +1,65 @@ +--- +title: Docker Documentation and Research (WIP) T1-2022 +--- + +[Back to Jupyter Notebook Documentation Index](/products/ontrack/documentation/jupyter-notebook) + +## Intro + +The Jupyter Notebook conversion feature will occur via processes inside Docker containers. In this +document we will discuss the main architecture of this structure in relation to OnTrack. + +OnTrack is deployed through two main containers, they are: + +- The front-end container which hosts the logic behind the user interface of OnTrack (mostly + unrelated to this feature) +- The back-end container which hosts the logic related to database interactions and other processes + +A new container will be created to achieve the Jupyter Notebook conversion feature. This contains +all of the dependencies (Python, TeX, etc.) needed for a .ipynb(Jupyter Notebook File) to PDF +conversion, and performing the conversion process within this container. This allows us to have a +standalone software package that is extendable if required, for example if new Python libraries are +required by a unit. It also means that we are able to create as many standalone containers as +required for different conversion processes, such as: + +- Docx to PDF conversion using Apache POI +- Powerpoint presentation to PDF conversion using Apache POI + +## Overview of Conversion Process + +![ ](/docker_flow.png) + +When the OnTrack front-end sends a new file to the OnTrack back-end, the back-end will be able to +determine the file type, and if the file needs to be converted. If the OnTrack back-end recieves a +.ipynb file, it will run the Jupyter to PDF conversion container to perform the conversion process. + +This is done via a shell command that does several things: + +1. Firstly, it ensures that the file to be converted is renamed to "input.ipynb". +2. It then instructs the container to run AND it mounts the file's directory as a Docker volume. As + the container runs it will execute the conversion process via its `ENTRYPOINT` command. The + converted file will be output to the volume. After the container has run, it will be removed. +3. Finally, it removes the temporary files to ensure there is always free space. + +The `docker run` command provides several options for this type of use-case: we are able to specify +a volume using the `-v` option, and we are able to ask that the container is removed after it has +finished its process with the `--rm` option. + +**Note: we may need to have some process in place to read whether the conversion was a success or a +failure.** + +## Conversion Container Requirements + +For a container to function in this architecture, there are some requirements that have to be met: + +- The container will run the conversion as its `ENTRYPOINT` command _without any user input + required_. +- The container will always look in a single directory (mounted as a volume when the container is + run) for **one** file that will be called "input" (+ whatever file extension is required). +- The container will always output the converted file to the **same** directory (mounted as a volumn + when the container is run) and call it "output.pdf". + +These requirements allow the containers to remain isolated while the file conversion logic is +handled seperately by the OnTrack backend. This is necessary to follow the Single-responsibility +Principle: the container itself is responsible for only one task - that is, performing the +conversion process. diff --git a/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/index.md b/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/index.md new file mode 100644 index 00000000..9b9f1aa7 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/index.md @@ -0,0 +1,26 @@ +--- +title: Jupyter Notebook Documentation Index +--- + +## [Jupyter Notebook Epic](/products/ontrack/documentation/jupyter-notebook/jupyter-notebook-epic-t1-2022) + +Epic for Jupyter Notebook support feature. + + + +## [Docker Documentation and Research](/products/ontrack/documentation/jupyter-notebook/docker-documentation-research-t1-2022) + +Docker documentation + +## [Prototype SRS (Software Requirements Specification)](/products/ontrack/documentation/jupyter-notebook/prototype-srs-software-requirements-specification) + +Software requirements specification for prototype application. diff --git a/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/jupyter-notebook-epic-t1-2022.md b/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/jupyter-notebook-epic-t1-2022.md new file mode 100644 index 00000000..747389cc --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/jupyter-notebook-epic-t1-2022.md @@ -0,0 +1,70 @@ +--- +title: Jupyter Notebook Support Epic +--- + +### Background + +- Students who use OnTrack currently are limited in the way they can upload their Jupyter notebook + files to OnTrack. Students must download their notebook as a HTML through Jupyter notebook and use + an online PDF converter to convert the HTML file to PDF, so their work can be submitted to + OnTrack. + +### Business Value + +- To minimise students needing to use outside sources to be able to upload their work, students must + be able to download their work from a Jupyter notebook, which is saved as a file with β€˜.ipynb’ + file, and upload to OnTrack, where it will be converted to a PDF for submission. This will make it + much more efficient for students to upload their work, which will save time for tutors having to + explain the process of having to outsource to a PDF conversion website. This will increase trust + in our product and improve user experience. + +### In scope + +- Review of previous work +- PDF conversion functionality +- Feature documentation +- User guide documentation + +### Out of scope + +- New features + +### What needs to happen + +- Review of existing work to find what is usable and then plan out what work is still to be done. + - Allow for ipynb files to be accepted for Ontrack + - Convert ipynb files to PDF via LaTeX + - Test files are converted from ipynb to PDF + +### Assumptions / Dependencies + +- Code added doesn’t affect any other parts of OnTrack + +### Analytics Considerations + +- How often is this feature being used? +- Track failed conversions + +### Reg & Compliance Considerations + +- N/A + +### Operations/Support + +- Team members may need training/upskilling in technologies such as Ruby, Ruby on Rails, Docker and + GitHub. +- User guide documentation will need to be release simultaneously with the new feature, so users + know how to use this new feature. + +### What are the challenges? + +- Team members will need to understand existing code contributions and understand what is usable to + integrate their Jupyter notebook support project work. Team members may also need to learn new + technologies used in the integration of Jupyter notebook support + +### Acceptance criteria + +- Validate planning documentation with managing directors +- Documentation is accurate to current version of products +- All functionally of Jupyter notebook support must be tested +- Data is collected on usage to inform future decisions diff --git a/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/prototype-srs-software-requirements-specification.md b/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/prototype-srs-software-requirements-specification.md new file mode 100644 index 00000000..29112c1a --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Jupyter Notebook/prototype-srs-software-requirements-specification.md @@ -0,0 +1,110 @@ +--- +title: Jupyter Notebook Week 6 Prototype - Software Requirement Specification (SRS) +--- + +- [Back to Jupyter Notebook Documentation Index](/products/ontrack/documentation/jupyter-notebook) + +## 1. Introduction + +### 1.1 Purpose + +- The purpose of this prototype is to ensure the code written thus far by team members sufficiently + completes the two key functionalities of converting both Jupyter Notebook files and Word document + files into PDF format. The successful implementation will ensure the team is on the right track in + terms of both their ideas and their coding work. + +### 1.2 Intended Audience + +- Students +- Teachers/Tutors/Lectures + +### 1.3 Intended Use + +- The intended use of this prototype is to be a more-basic first draft of the logic the team wishes + to implement in the final product of the project scope. It will test the conversion to PDF for + both Jupyter Notebook and Word document files. The successful implementation of this prototype + will give the team the knowledge that the code they’ve written works on a smaller scale than + OnTrack. + +### 1.4 Scope + +- The scope of the prototype is to create a simple front-end interface similar to that of OnTrack + and, through the use of command-line commands, allow for the following functionalities: + - Converting a Jupyter Notebook file into PDF format + - Converting a Word file into PDF format + +### 1.5 Definitions and Acronyms + +- Jupyter Notebook – a web application that allows users write and run live code, equations, + visualizations, and plain text in various languages. +- .ipynb – Jupyter Notebook file type +- .doc – Microsoft Word file +- .docx – Microsoft Word file +- PDF – Portable Document Format +- Library – A library is a collection of pre-written code that provide further access to system + functionality such as file I/O that would otherwise be inaccessible. This is done importing the + library at the beginning of the program. +- HTML – HyperText Markup Language +- RubyOnRails – a server-side web application framework written in Ruby. +- Nbconvert – is a library of pre-written code used to convert Jupyter Notebook file to PDF. +- Backend – Is development that happens behind the scenes, it is all the parts of a computer system + or application that is not directly accessed by the user, it is responsible for storing and + manipulating data through code. +- Frontend – Is development on what the user can see and/or directly interact with (i.e., what can + be seen on the computer screen, such as a window, or buttons and input fields/boxes) + +## 2. Overall Description + +### 2.1 User Needs + +- As a student, I want to be able to upload Jupyter Notebook (.ipynb) files without having to go + through the extra step of converting them to a PDF first. +- As a tutor, I want students to be able to upload any file they are working on so they can focus on + the quality of the work. + +### 2.2 Assumptions and Dependencies + +- Assumptions include: + - The user has a working and valid Jupyter Notebook/Word Document ready to be converted to PDF. + - The user wants the input file to be converted as uploaded. +- The user has access to OnTrack. +- Key project member’s availability +- Key project member’s performance +- Key project member’s skills +- Dependencies include: + - Input of a valid Jupyter Notebook/Word Document file. + - A valid internet connection, to interact with OnTrack environment + - A Docker container must be created first before testing of Jupyter Notebook/Word Document + conversion can be tested. + - Approval of project expansion must be given before work on expansion begins + +## 3. System Features and Requirements + +### 3.1 Functional Requirements + +- Convert Jupyter Notebook files to PDF format +- Convert a Word Document to PDF format +- Compatibility with existing code + +### 3.2 External Interface Requirements + +- nbconvert library +- Apache library +- Forked repositories +- User interface (interaction logic between software and user) + +### 3.3 System Features + +- Basic front-end user interface for user to trigger logic +- Ability to convert Jupyter Notebook file to PDF file +- Ability to convert Word document file to PDF file + +### 3.4 Non-functional Requirements + +- Usability – User standards +- Scalability – ability of software to be scaled to encompass project scope in its entirety +- Maintainability – ability of software to be maintained, ensuring consistent and upmost performance +- Reliability – The ability of the system to consistently perform its required functions under + stated conditions. +- Documentation – User documentation, testing results, meeting minutes and notes, contribution + notes, discussions. diff --git a/src/content/docs/Products/OnTrack/Documentation/Multiple Organisations/design-documentation.md b/src/content/docs/Products/OnTrack/Documentation/Multiple Organisations/design-documentation.md new file mode 100644 index 00000000..35787f5b --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Multiple Organisations/design-documentation.md @@ -0,0 +1,141 @@ +--- +title: Design Document:OnTrack - Incorporating Multiple Organisati +--- + +Author: Sanah Quazi + +Company: Thoth Tech + +## Introduction + +This design document outlines the approach for incorporating multiple organisations into the OnTrack +server, enhancing its functionality to accommodate various organisations within a single system +instance. The goal is to provide a comprehensive solution that enables effective organisation +management, user assignment, and access control while maintaining the integrity and security of the +OnTrack system. + +## User Story + +As a Site administrator, I want to be able to manage multiple organisations within the OnTrack +system. This will allow me to efficiently organise users and data, ensuring that each organisation +operates independently. + +## Acceptance Criteria + +- Site administrators can create new organisations, providing details such as name and description. +- Organisations can be edited to update their details. +- Organisations can be disabled when they are no longer in use. +- Users can be associated with specific organisations. +- Users with access to multiple organisations can smoothly switch between them. +- Data access is restricted based on a user's associated organisation. + +## System Architecture + +## Frontend Architecture + +The frontend of the system incorporates the following components: + +- Organisation Management UI: This component allows administrators to create, edit, and disable + organisations. It includes a user-friendly interface for managing organisation details. +- User Management UI: Users are associated with organisations through this interface. It provides a + seamless experience for assigning users to organisations and managing user profiles. +- Organisation Switching UI: Users with access to multiple organisations can easily switch between + them using this interface. It ensures a smooth transition from one organisation's context to + another. + +## Backend Architecture + +The backend of the system handles data management and access control: + +- Organisation Management: Backend services manage the creation, editing, and disabling of + organisations. Data is stored securely in the database, and appropriate permissions are enforced. +- User Organisation Assignment: Backend processes allow site administrators to associate users with + specific organisations. These associations are maintained in the database. +- Access Control: The backend enforces access control rules to ensure that users can only access + data within their associated organisation. This is achieved through role-based access control + mechanisms where site administrator is a new role. + +## Technical Implementation- + +## Frontend Implementation + +Organisation Management UI: + +- Create user interfaces for creating, editing, and disabling organisations. +- Implement forms for entering organisation details. +- Ensure responsive design using modern frontend technologies. + +User Management UI: + +- Develop interfaces for assigning users to organisations and managing user profiles. +- Implement user-friendly features for easy association and disassociation of users with + organisations. + +Organisation Switching UI: + +- Create an intuitive interface for users to switch between organisations. +- Implement secure mechanisms for handling organisation context switches. + +## Backend Implementation + +Organisation Management: + +- Develop API endpoints for creating, editing, and disabling organisations. +- Implement data validation to ensure the integrity of organisation details. +- Ensure data is securely stored and updated in the database. + +User Organisation Assignment: + +- Create API endpoints for associating and disassociating users with organisations. +- Implement validation checks to prevent unauthorized assignments. +- Update user profiles to reflect organisation associations. + +Access Control: + +- Enforce access control rules based on user roles and organisation associations. +- Implement middleware to check permissions before granting access to data. +- Securely manage data queries to ensure isolation between organisations. +- The technical implementation aims to provide a seamless user experience while ensuring data + security and access control across multiple organisations. + +## Database Design + +The database design ensures that organisations can be efficiently managed, users can be associated +with organisations, and access control can be enforced based on these associations. The database +design for incorporating multiple organisations includes the following elements: + +- Organisations Table: Create a table named β€˜organisations’ to store organisation-specific details. + +Columns: + +- organisation_id: Unique identifier for each organisation (primary key). +- name: Name of the organisation. +- description: Description of the organisation. +- Email: official email id of the organisation. +- is_enabled: Flag indicating whether the organisation is active or disabled. + +- Users Table: Update the existing β€˜users’ table to include organisation_id as the foreign key. + +## Error Handling and Validation + +Robust error handling and validation mechanisms are essential for ensuring data integrity and user +satisfaction. Frontend and backend components should implement validation checks and provide clear +error messages to users. + +## Testing Strategy + +Testing is crucial to verify the functionality and security of the system. Both frontend and backend +components should undergo thorough testing to identify and address issues. + +## Deployment Plan + +The deployment plan outlines the steps for introducing the multiple organisations feature into the +OnTrack system, ensuring a smooth transition for users. + +## Conclusion + +The incorporation of multiple organisations into the OnTrack server is a significant enhancement +that enhances the system's flexibility and scalability. By following the design outlined in this +document and implementing it effectively, OnTrack will provide a powerful solution for managing +multiple organisations while maintaining data security and access control. This design document +serves as a roadmap for achieving these goals and delivering a feature-rich, user-friendly system. diff --git a/src/content/docs/Products/OnTrack/Documentation/Multiple Organisations/gather-requirements-for-multiple-organisations.md b/src/content/docs/Products/OnTrack/Documentation/Multiple Organisations/gather-requirements-for-multiple-organisations.md new file mode 100644 index 00000000..8b2f6206 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Multiple Organisations/gather-requirements-for-multiple-organisations.md @@ -0,0 +1,132 @@ +--- +title: Incorporate Multiple Organisations on a Single OnTrack Server +--- + +**Author:** Sanah Quazi + +**Company:** Thoth Tech + +## Introduction + +This documentation outlines the requirements for implementing a feature that enables the +ncorporation of multiple organisations within a single OnTrack server. This feature aims to enhance +the administrative capabilities of the OnTrack application by allowing server operators to manage +and segregate multiple organisations efficiently. + +## User Story + +As an OnTrack server operator, I want to be able to host multiple organisations within my server. + +## Functional Requirements + +### Backend + +- Design a flexible organisational structure to accommodate multiple organisations. +- Develop functionality to create, edit, and disable organisations, including providing a unique + identifier for each organisation. +- Implement a new user role named "Site Administrator" with permissions to manage organisations, + including the ability to add, disable, and edit them. +- Enhance the user profile system to associate users with specific organisations and allow users to + switch between organisations. + +### Frontend + +- Design intuitive user interfaces for organisation creation, modification, and disabling. +- Create a dedicated dashboard for Site Administrators to manage organisations, including options to + add, disable, and edit organisations. +- Update user profile pages to display and allow modification of the associated organisation. + +## Non-Functional Requirements + +### Performance + +- Ensure that the system can handle a significant number of organisations and users without + compromising performance. +- Optimize database queries and access patterns to maintain responsive user experience even with + increased organisational complexity. + +### Reliability + +- Implement data isolation mechanisms to prevent cross-organisation data leaks or unauthorized + access. +- Apply robust error handling to prevent disruptions due to organisational changes. + +## Test Cases + +### Test Case 1:Organisation Creation + +Description: Verify the system allows the creation of a new organisation with a unique name and +identifier. + +### Steps + +- Log in as a Site Administrator. +- Navigate to the organisation creation page. +- Enter a unique organisation name and identifier. +- Submit the form. + +### Expected Outcome + +The organisation is created, and its details are stored in the database. + +### Test Case 2: Organisation Management + +### Description + +Verify the Site Administrator can edit organisation details. + +### `Steps + +- Log in as a Site Administrator. +- Access the organisation management dashboard. +- Select an organisation to edit. +- Modify organisation details and save changes. + +### `Expected Outcome + +Organisation details are updated and reflected in the system. + +### Test Case 3: User Organisation Assignment + +### `Description + +Verify users can be associated with specific organisations. + +### Steps` + +- Log in as a user. +- Access the user profile page. +- Choose an organisation to associate with. +- Save changes. + +### Expected Outcome`` + +The user is now associated with the selected organisation. + +### Test Case 4: Access Control\*\* + +Description: Verify users can access only the resources within their organisation. + +### Steps`` + +- Log in as a user from Organisation A. +- Attempt to access resources belonging to Organisation B. + +### `Expected Outcome`` + +Access is denied, and the user can only access resources within their own organisation. + +### Testing`` + +- Perform unit testing on each component, ensuring that organisation-related functionalities work as + expected. +- Conduct integration testing to ensure smooth interaction between different parts of the system. +- Implement user acceptance testing involving Site Administrators and regular users to validate the + feature's usability and correctness. + +## Conclusion + +In conclusion, the incorporation of multiple organisations within a single OnTrack server brings a +significant enhancement to the application's administrative capabilities. By following the outlined +requirements and test cases, this feature will enable server operators to effectively manage and +segregate various organisations, ensuring a more streamlined and organised user experience. diff --git a/src/content/docs/Products/OnTrack/Documentation/Multiple Organisations/test-scenario-requirements.md b/src/content/docs/Products/OnTrack/Documentation/Multiple Organisations/test-scenario-requirements.md new file mode 100644 index 00000000..8854e853 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Multiple Organisations/test-scenario-requirements.md @@ -0,0 +1,232 @@ +--- +title: Test Cases for Incorporating Multiple Organisations on OnTrack Server +--- + +**Author:** Sanah Quazi + +**Company:** Thoth Tech + +## Introduction + +This document outlines test cases for incorporating multiple organisations on the OnTrack server, +enhancing its functionality to accommodate various organizations within a single system instance. + +## Backend Functionality + +## Organisation Management + +Test Case 1: Creating an Organisation + +Description: Verify the system's ability to create a new organisation. + +Steps: + +1\. Log in as a Site Administrator. + +2\. Access the organisation creation feature. + +3\. Enter valid details for the new organisation (name, description). + +4\. Submit the form. + +Expected Outcome: A new organisation is created, and it appears in the list of organisations managed +by the Site Administrator. + +Test Case 2: Editing an Organisation + +Description: Test the ability to edit an existing organisation's details. + +Steps: + +1\. Log in as a Site Administrator. + +2\. Access the organisation editing feature. + +3\. Select an existing organisation. + +4\. Modify the organisation's details (e.g., description). + +5\. Save the changes. + +Expected Outcome: The organisation's details are updated, and the changes are reflected in the +system. + +Test Case 3: Disabling an Organisation + +Description: Verify the process of disabling an organisation. + +Steps: + +1\. Log in as a Site Administrator. + +2\. Access the organisation management feature. + +3\. Select an existing organisation. + +4\. Disable the organisation. + +Expected Outcome: The organisation is disabled and no longer accessible to users. It is removed from +active use but remains in the system for reference. + +## User Organisation Assignment + +Test Case 4: Associating a User with an Organisation + +Description: Test the capability to associate a user with a specific organisation. + +Steps: + +1\. Log in as a Site Administrator. + +2\. Access the user management feature. + +3\. Select a user. + +4\. Assign the user to an organisation. + +Expected Outcome: The user is associated with the chosen organisation, and their profile reflects +the change. + +Test Case 5: User Switching Between Organisations + +Description: Confirm that users can successfully switch between organisations when they have access +to multiple organizations. + +Steps: + +1\. Log in as a user associated with multiple organisations. + +2\. Access the organisation switch feature. + +3\. Select a different organisation to switch to. + +Expected Outcome: The user's context changes to the selected organisation, and they can access its +resources and functionalities. + +## Access Control + +## Data Access Based on Organisation + +Test Case 6: User Data Access Control + +Description: Ensure that users can access data only within their associated organisation and are +restricted from accessing data from other organisations. + +Steps: + +1\. Log in as a user from Organisation A. + +2\. Attempt to access resources belonging to Organisation B. + +Expected Outcome: Access to resources of Organisation B is denied for the user from Organisation A. + +Test Case 7: Site Administrator Data Access Control + +Description: Verify that Site Administrators can access data only from their organisation while +being restricted from accessing data outside their organisation. + +Steps: + +1\. Log in as a Site Administrator from Organisation A. + +2\. Attempt to access resources belonging to Organisation B. + +Expected Outcome: Access to resources of Organisation B is denied for the Site Administrator from +Organisation A. + +## Frontend Functionality + +## Organisation Management` + +Test Case 8: Frontend - Creating an Organisation + +Description: Verify the frontend functionality for creating a new organisation. + +Steps: + +1\. Log in as a Site Administrator. + +2\. Navigate to the relevant page for organisation creation. + +3\. Enter valid details for the new organisation (name, description). + +4\. Submit the form. + +Expected Outcome: A new organisation is created, and it is displayed in the list of organisations +managed by the Site Administrator. + +Test Case 9: Frontend - Editing an Organisation + +Description: Test the frontend capability to edit an existing organisation's details + +Steps: + +1\. Log in as a Site Administrator. + +2\. Navigate to the organisation editing page. + +3\. Select an existing organisation. + +4\. Modify the organisation's details (e.g., description). + +5\. Save the changes. + +Expected Outcome: The organisation's details are updated in the frontend, and the changes are +reflected in the system. + +Test Case 10: Frontend - Disabling an Organisation + +Description: Verify the frontend process for disabling an organisation. + +Steps: + +1\. Log in as a Site Administrator. + +2\. Access the organisation management feature. + +3\. Select an existing organisation. + +4\. Disable the organisation using the frontend interface. + +Expected Outcome: The organisation is visually disabled and no longer accessible to users via the +frontend. It remains in the system for reference. + +## User Organisation Assignment`` + +Test Case 11: Frontend - Associating a User with an Organisation + +Description: Test the frontend functionality to associate a user with a specific organisation. + +Steps: + +1\. Log in as a Site Administrator. + +2\. Access the user management feature from the frontend. + +3\. Select a user. + +4\. Assign the user to an organisation using the frontend interface. + +Expected Outcome: The user's association with the chosen organisation is visually represented in the +frontend, and their profile reflects the change. + +Test Case 12: Frontend - User Switching Between Organisations + +Description: Confirm that users can successfully switch between organisations via the frontend when +they have access to multiple organisations. + +Steps: + +1\. Log in as a user associated with multiple organisations. + +2\. Use the frontend organisation switch feature. + +3\. Select a different organisation to switch to. + +Expected Outcome: The user's context visually changes to the selected organisation in the frontend, +and they can access its resources and functionalities. + +## Conclusion + +These test cases cover both backend and frontend functionalities comprehensively to ensure that the +multi-organisation feature functions correctly and provides a seamless experience for the users. diff --git a/src/content/docs/Products/OnTrack/Documentation/Multiple Organisations/uml-design.md b/src/content/docs/Products/OnTrack/Documentation/Multiple Organisations/uml-design.md new file mode 100644 index 00000000..5338b526 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Multiple Organisations/uml-design.md @@ -0,0 +1,42 @@ +--- +title: Requirements to incorporate multiple organisations on a single OnTrack server – UML Design +--- + +Author: Sanah Quazi + +Company: Thoth tech + +![a]/(uml.png) + +The UML diagram presented above focuses on achieving efficient organisation management, user +association with organisations, and robust access control. It outlines the database structure for +accommodating multiple organisations, which consists of two main elements: + +Organisations Table: This table, labelled 'organisations,' is responsible for storing +organisation-specific information. It includes the following key columns: + +- organisation_id: This column serves as a unique identifier for each organisation and acts as the + primary key for this table. +- name: The 'name' column holds the organisation's name. +- description: In the 'description' column, you can find detailed descriptions of each organisation. +- email: This column stores the official email address associated with the organisation. +- is_enabled: The 'is_enabled' column is a flag that indicates whether the organisation is currently + active or disabled. + +Users Table: In addition to the 'organisations' table, the diagram illustrates an update to the +existing 'users' table. This update includes the addition of an organisation_id column, which serves +as a foreign key. This column establishes a link between users and their associated organisations, +allowing for efficient organisation assignment and access control enforcement. + +This database design is crucial for the successful implementation of the feature that enables +multiple organisations within the OnTrack system. It ensures data integrity and provides the +necessary structure for managing and securing organisational data. + +## The relationships between these classes are as follows + +- organisations to users: This association indicates a multiplicity of one-to-many (1..\*). It means + that each organisation in the 'organisations' table can be associated with zero to multiple users + from the 'users' table. +- users to organisations: This association specifies a multiplicity of one-to-one (1..1). It + signifies that each user in the 'users' table is uniquely associated with one organisation in the + 'organisations' table. diff --git a/src/content/docs/Products/OnTrack/Documentation/Sidekiq Investigation/sidekiq-investigation.md b/src/content/docs/Products/OnTrack/Documentation/Sidekiq Investigation/sidekiq-investigation.md new file mode 100644 index 00000000..7a163034 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Sidekiq Investigation/sidekiq-investigation.md @@ -0,0 +1,66 @@ +--- +title: "Spike Research: Integrating Sidekiq with Ruby on Rails" +--- + +## Objective + +The purpose of this spike is to explore the integration of Sidekiq for background job processing in +our Ruby on Rails application, understand its setup and configuration, and identify any potential +issues that may arise during its implementation and deployment. + +## Introduction + +Background job processing is an essential component of modern web applications, allowing +long-running tasks to be handled asynchronously to improve user experience and system performance. +Sidekiq is a Ruby background job processor that uses threads to handle many jobs at the same time in +the same process. + +## Methodology + +Research for this spike was conducted by reviewing Sidekiq's official documentation, community +forums, and GitHub issues. Additionally, a prototype was created in a development environment to +test the integration points and monitor the behaviour of Sidekiq within the context of our +application. + +## Findings + +1. Installation and Configuration + +- Sidekiq is easily installable as a gem in Ruby on Rails. +- Configuration is straightforward, with the need to set up a sidekiq.yml file and initialize the + Redis server, which Sidekiq uses for job storage. +- Sidekiq's dashboard provides a web interface to monitor job queues, which can be mounted within + Rails routes. + +2. Operational Insights + +- Sidekiq requires Redis to be available and properly configured. +- Memory usage is manageable, but careful monitoring is required to prevent leaks over time. +- Concurrency settings and job prioritization are critical for optimal performance. + +3. Deployment Considerations + +- Deployment to platforms like Heroku requires additional add-ons for Redis. +- Environment variables need to be managed securely, especially for the Redis URL. +- Sidekiq can be scaled independently by increasing worker dynos. + +4. Best Practices + +- Regularly update the Sidekiq gem to benefit from the latest improvements and security patches. +- Ensure idempotency of jobs to avoid duplicating work in case of retries. +- Monitor Sidekiq with tools like New Relic or Sentry to track failures and performance issues. + +## Challenges and Solutions + +1. - Challenge: Ensuring jobs are retried correctly after failures. + - Solution: Implementing custom retry logic within jobs and leveraging Sidekiq's middleware for + error handling. +2. - Challenge: Handling large job volumes without overloading the Redis instance. + - Solution: Scaling Redis and optimizing job size and complexity. + +## Conclusion + +The integration of Sidekiq into our Ruby on Rails application appears to be a robust solution for +our background processing needs. With its ease of use, extensive documentation, and active +community, Sidekiq offers the features we require to improve our application's performance and +reliability. diff --git a/src/content/docs/Products/OnTrack/Documentation/Voice Verification/architecture-document.md b/src/content/docs/Products/OnTrack/Documentation/Voice Verification/architecture-document.md new file mode 100644 index 00000000..9329f950 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Voice Verification/architecture-document.md @@ -0,0 +1,95 @@ +--- +title: Architecture Document | Voice Verification for OnTrack Delivery +--- + +## Introduction + +### Purpose + +This document provides a comprehensive architectural overview of the Voice Verification system, +using a few different architectural views to depict different aspects of the system. It is intended +to capture and convey the significant architectural decisions which have been made on the system. + +### Scope + +This Architecture Document provides an architectural overview of Voice Verification System. The +Voice Verification System is being developed to address the issues concerning contract cheating on +online learning management platforms. + +## Architectural Goals and Constraints + +### Goals + +- Students can register their voice on OnTrack using the Speaker Verification system. +- Upon task submission, the attached voice file is analysed for verification. +- Deployed on the OnTrack instance in a docker container format. +- Support for gathering both front and backend telemetry should be present in the system to allow + for analysis of user interaction, and system performance. + +### Constraints + +- Speaker Verification system must have compatibility for voice recording across multiple browsers. +- Front-end components should comply with existing OnTrack requirements. +- System should adhere to existing OnTrack privacy/compliance requirements in addition to existing + OnTrack security requirements. + +## Use-Case View + +### Architecturally Significant Use Cases + +![Figure 1: Architecturally Significant Use Cases](/Use%20Cases.png) + +1. As a student, I want Ontrack to have a function that can identifies me by my voice. + **Description:** The feature highlighted through this user story is having a "Enrol the + voiceprint". This feature allows a student to register a voiceprint for later verification + +2. As a student submitting my assignments, I want able to upload audio files to Ontrack. + **Description:** The feature highlighted through this user story is having a "Submit a voice + file”. This feature allows a student to submit an assignment audio to Ontrack System. +3. As a Deep Speaker Classifier, β€œI” can recognise student by their voice at a confidence level. + **Description:** The Deep Speaker Model is an actor involved within β€œCompare two audio samples” + which will automatically confirm student’s identity by comparing their new voice submission to + their voiceprint. This takes place within the Voice Verification Container. + +4. As a tutor/student, I want to receive the result of voice verification to be aware of the outcome + of the verification. **Description:** Voice Verification system will return/export the voice + verification result to the Tutor and Student (a confidence score of how likely it is that the + voice in the recording is the student in question) in a readable way. + +## Logical View + +### Architecture + +![Figure 2: High Level Architecture](/Architecture%20Diagram.png) + +### Detailed description of the architecture diagram + +The diagram shows the communication types between each of the systems of the project. The User +interacts with both the frontend website OnTrack and the voice verification system through a Ruby +app. The voice verification method used takes advantage of Deep Speaker. Deep Speaker is a deep +learning model that can be used to verify a user's identity by comparing their voice to a +voiceprint. The voice verification system is deployed in a docker container format. + +### General Flow diagram + +![Figure 3: General Flow Diagram](/Flow%20Diagram.png) + +The User has its requests go through the existing OnTrack system, with the OnTrack system sending +further requests to the Voice Verification API. The sends the voice files to the docker container. + +## Size and Performance + +The Size and Performance as of this stage cannot be calculated. However, the following information +should be recorded when the system has been developed: + +- Size of Voice Files for enrolment and verification. +- Response time for API calls +- Throughput of API calls + +## Quality + +The Quality of the system must be further measured. The required information is as follows: + +- Quality of Voice Validation results +- Testing of Voice Submissions (placing multiple speakers in the audio file, placing the speech at + different stage of the audio file) diff --git a/src/content/docs/Products/OnTrack/Documentation/Voice Verification/audio-system-interface-design.md b/src/content/docs/Products/OnTrack/Documentation/Voice Verification/audio-system-interface-design.md new file mode 100644 index 00000000..13a8d719 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Voice Verification/audio-system-interface-design.md @@ -0,0 +1,92 @@ +--- +title: Audio System Interface Design Document +--- + +## Author Information + +--- + +- Author: [agahis](https://github.com/agahis) +- Team: OnTrack – Voice Verification +- Team (Delivery and/or Product) Lead: [Shae Christmas](https://github.com/ShaeChristmas) + +## Document Summary + +--- + +- Documentation Title: Audio System Interface Design Document +- Documentation Type: Technical +- Documentation Information Summary: Design document detailing the implementation of the OnTrack + Voice Verification audio system interface, showcased by wire frames for frontend development. + Interface to allow tutors to see the results from the voice verification test with the new OnTrack + Overseer system as well. The perspective is from a tutors as they are the only ones who have + access to it. + +## Document Review Information + +--- + +- Date of Original Document Submission to GitHub: 26/09/2022 +- Documentation Version: 1.0 +- Date of Previous Documentation Review: 26/09/2022 +- Date of Next Documentation Review: to be decided + +## Key Links/Resources + +--- + +- [OnTrack Overseer Repository](https://github.com/thoth-tech/doubtfire-overseer) +- [OnTrack Web Repository](https://github.com/thoth-tech/doubtfire-web) +- [OnTrack API Repository](https://github.com/thoth-tech/doubtfire-api) +- [OnTrack Voice Verification Python Container Repository](https://github.com/thoth-tech/speaker-verification) +- [OnTrack Voice Verification API Repository](https://github.com/thoth-tech/speaker-verification-api) +- [Thoth Tech Documentation Template](https://github.com/thoth-tech/documentation/blob/main/docs/OnTrack/Documentation/OnTrack%20Documentation%20Template.md) +- [OnTrack Documentation Template Guide](https://github.com/thoth-tech/documentation/blob/main/docs/OnTrack/Documentation/OnTrack-Documentation-Template-Guide.md) +- [Software Requirements Specifications Document](https://github.com/thoth-tech/documentation/blob/main/docs/OnTrack/Voice%20Verification/Voice%20Verification%20SRS%20Document.md) + +## Contacts for further information + +--- + +See [Thoth Tech Handbook](https://github.com/thoth-tech/handbook/blob/main/README.md). + +## Low Fidelity Designs + +--- + +**Figure 1** below shows the initial sketches and brainstorming put into place for the tutors +interface when accessing the voice verification results. + +![figure 1](/figure1.jpeg) + +**Figure 2** below shows a digital draft design for the flowchart between the three different +results and visualisations shown in Figure 1. The visualisations are shown for the results and +similar conventions used for display. Branching off to the main processes that would subsequently +become an output from clicking on these results. + +![figure 2](/figure2.PNG) + +## High Fidelity Designs + +--- + +**Figures 3 and 4** below shows the process and results when the tutor clicks on an audio file. +These figures show files that are still pending. + +![figure 2](/figure3.PNG) + +![figure 3](/figure4.PNG) + +**Figures 5 and 6** below shows the process and results of when the tutor clicks on an verification +pending audio file. + +![figure 5](/figure5.PNG) + +![figure 6](/figure6.PNG) + +**Figures 7 and 8** shows the process and results of when the tutor clicks on an audio file that has +completed the Verification process. + +![figure 7](/figure7.PNG) + +![figure 8](/figure8.PNG) diff --git a/src/content/docs/Products/OnTrack/Documentation/Voice Verification/voice-verification-design-document.md b/src/content/docs/Products/OnTrack/Documentation/Voice Verification/voice-verification-design-document.md new file mode 100644 index 00000000..2dcb8566 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Voice Verification/voice-verification-design-document.md @@ -0,0 +1,201 @@ +--- +title: OnTrack Voice Verification Design Document +--- + +## Author Information + +--- + +- Author: [ShaeChristmas](https://github.com/ShaeChristmas) +- Team: OnTrack - Voice Verification +- Team (Delivery and/or Product) Lead: Shae Christmas + +## Document Summary + +--- + +- Documentation Title: Voice Verification Design Document +- Documentation Type: Technical +- Documentation Information Summary: Design Document detailing implementation of Voice Verification + system in the OnTrack Project + +## Document Review Information + +--- + +- Date of Original Document Submission to GitHub: 14/09/2022 +- Documentation Version: 1.1 +- Date of Previous Documentation Review: 30/09/2022 +- Date of Next Documentation Review: to be decided + +## Key Terms + +--- + +CLI: Command Line Interface; Interacting with something through the terminal + +Docker Container: A small program contained inside a virtual machine. The containerisation program +used is called Docker. + +RabbitMQ: A message broker that allows for the communication between different programs. + +## Key Links/Resources + +--- + +- [OnTrack Overseer Repository](https://github.com/thoth-tech/doubtfire-overseer) +- [OnTrack Web Repository](https://github.com/thoth-tech/doubtfire-web) +- [OnTrack API Repository](https://github.com/thoth-tech/doubtfire-api) +- [OnTrack Voice Verification Python Container Repository](https://github.com/thoth-tech/speaker-verification) +- [OnTrack Voice Verification API Repository](https://github.com/thoth-tech/speaker-verification-api) + +## Contacts for further information + +--- + +See [Thoth Tech Handbook](https://github.com/thoth-tech/handbook/blob/main/README.md). + +## Related Documents + +--- + +- [Voice Verification Software Requirements and Specifications Document](/products/ontrack/documentation/voice-verification/voice-verification-srs-document) + +## Delivery Description + +--- + +OnTrack as a platform allows for students to track assessments for enrolled subjects, and submit +their work once completed. Audio submissions have been a substitute for in-person discussions in +recent years. + +The OnTrack Voice Verification system aims to verify audio submissions, to ensure that the speaker +in the submission is the correct student. + +This system would be implemented inside the existing OnTrack Project, and integrated into OnTrack by +using the pre-existing audio submission system. + +## Problem Statement + +--- + +When submitting an assessment with an oral component, the student may take advantage of the OnTrack +audio submissions system. + +However, any audio file may be submitted through this system; it is not verified at any stage in the +current OnTrack implementation. Contract cheating or other methods of cheating could be used, and +would not be picked up by the system automatically. + +A possible method to cheat by taking advantage of the pre-existing system would be to pay someone +else to answer audio questions. As no verification process is taking place, tutors may not identify +that the person speaking is not the student who is being assessed. + +A verification system for testing audio submissions against a baseline audio sample would make this +type of cheating more difficult. + +The voice verification system would give a confidence in the speakers identity, which could then be +verified by an assessor if necessary. + +As such, this allows for greater verification of submissions, and ensuring that cheating using the +audio submission system can be minimised. + +## Current Works + +--- + +The current voice verification system is not linked to the OnTrack architecture. Instead, the system +is implemented as a Docker Container, that can accept audio inputs, and produces a confidence +variable with certainty of the speakers identity. + +At this stage, the system receives a known sample, and a new audio file. These must be manually +submitted to the container through the CLI. + +As such, a system to link the existing Docker container to the OnTrack system must be implemented +for automatic verification and display of results. + +## Design + +--- + +The Voice Verification Architecture uses similar to a system in place within OnTrack called OnTrack +Overseer. + +When an audio file is received in the database, a trigger is sent to the Message Queue system that +the Voice Verification architecture employs. This system uses RabbitMQ as a message queue, to send +files to be verified to the main Voice Verification container. This container uses Deep Speaker +verification to test the new file against the baseline file collected for that student. Then, the +confidence value appended to the message on the message queue, and saved in the database. + +After the confidence value is saved in the database alongside the file, this can be retrieved by the +system. This retrieval takes place when the file is requested for marking. + +### Architecture + +![Proposed Architecture of Voice Verification implementation](/Voice-Verification-Architecture-Diagram.png) + +### Data Formats + +The Voice Verification system uses similar data formats to the OnTrack system. The audio files are +stored in an SQLite database, attached to the OnTrack API. In the database, three new values are +appended to audio submissions: + +| Database Tag | Purpose | Possible Values | Example | +| ------------ | ---------------------------------------------------------------------------------------- | --------------- | ------- | +| `Verified` | To determine if the file has already been verified | Boolean | `True` | +| `Baseline` | To determine if this is the baseline file to verify new submissions | Boolean | `False` | +| `Confidence` | Returned confidence values from verification. Number between 0-1. 0 if not yet verified. | Real | `0.87` | + +These values are appended to the existing documents in the SQLite Database. + +### Data Flow + +The messages in the Voice Verification Message Queue should follow the same structure as the OnTrack +Overseer Message Queue. Requests to the database have the following parameters: + +- `task_id`: task associated with the submission +- `submission`: path to the submission zip file or folder +- `overseer_assessment_id`: id of the overseer message. used to keep track of individual + assessments. + +Messages to the Voice Verification system also contain a `baseline` parameter, which is the file +path to the baseline audio sample for that student. + +Messages from the Voice Verification system have the following parameters: + +- `task_id`: task associated with the submission +- `submission`: path to the submission zip file or folder +- `overseer_assessment_id`: id of the overseer message. used to keep track of individual + assessments. +- `confidence`: confidence value returned from the verification system +- `verification time`: when the verification was completed. + +These values are then appended to the existing documents in the SQLite Database. + +### User Interaction + +Ideally, students wont no interaction with the verification system. Once an audio file has been +submitted, it is automatically be queued for verification. Once verified, the assessor can listen to +the audio submission, and view the confidence value. + +### Testing + +Testing for the implemented system would must include the following strategies: + +- Validation of files with the same speakers. +- Verification of files with different speakers. +- Verification of files with multiple different speakers. +- Verification of files with no speakers. + +Additionally, other methods of bypassing the system should be investigated. This would include +testing database security; more specifically where the validation results are stored. + +Finally, testing different values for confidence thresholds would allow for more refined use of the +voice verification system. + +## Success metrics + +--- + +To measure the success of the system, a Confusion Matrix should be generated to determine the false +positive and false negative rate of the system. As results would be validated by an assessor, this +information can be tracked per assessor, and collated for review. diff --git a/src/content/docs/Products/OnTrack/Documentation/Voice Verification/voice-verification-srs-document.md b/src/content/docs/Products/OnTrack/Documentation/Voice Verification/voice-verification-srs-document.md new file mode 100644 index 00000000..5b21046b --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Voice Verification/voice-verification-srs-document.md @@ -0,0 +1,146 @@ +--- +title: Software Requirements Specifications Document +--- + +### Voice Verification for OnTrack Delivery + +## Product Purpose + +The purpose of the Voice Verification System for OnTrack is to add the ability for Voice Samples +that are submitted to OnTrack to undergo a verification process to ensure that the speaker in the +sample is the same as the person taking part in the unit. Specifically, this is to identify when a +student is contract cheating, or if the person in the specific submission is also the person +undertaking the unit. + +The intended audience for this project is the users of OnTrack; both students for using the system +to submit and verify their own audio files, as well as Tutors, who would be able to see the results +of the verification and verify that the student has undertaken the task themselves. + +The systems intended use is for the verification of Audio files that are submitted as part of Deakin +assessments to OnTrack, to further verify that the student has done the work themselves and is not +taking part in cheating; more specifically, to verify that the student has not hired someone else to +do the task for them, as is the case with Contract Cheating. + +The ccope of the project is to verify and validate a Python Container that can compare two voice +samples and give the confidence level that the person speaking is the same in both voice samples. +This requires a deployment to a testing system, as well as deployment to the OnTrack staging +platform for Thoth Tech. + +## Description of overall System + +## User requirements + +The user requirements of the system are that the system needs to be usable by both Students and +Tutors. These requirements include: + +- Ability to submit voice files for Enrolment and Verification +- Attainment of results for Students and Tutors to show the validity of the voice file in the + context of the assessment. +- Ease of use +- Secure system + +These requirements are mainly focused on the user experience, and how the user will interact with +the system. + +## Assumptions and Dependencies + +This system has a few assumptions. These include: + +- Users has access to OnTrack and a valid internet connection + +- Students do submit an enrolment voice file for later comparison. +- Tutors use the system whenever a voice submission is required. +- The same person is speaking throughout the entirety of the voice files. + +Each of these assumptions is important for the use and requirements of the system. The system should +be able to deal with multiple requests in quick succession, be actively deployed to the OnTrack +System, and have strict requirements for the initial voice file. + +Furthermore, a few different aspects are relied upon for the project to function. These include: + +- OnTrack as a deployment platform +- Deployment of the full connected system (OnTrack, plus API, and the Python Container) + +These assumptions are that OnTrack is used as the deployment platform for the voice verification +system, mainly as this is where it is being more properly integrated and developed for. +Additionally, for OnTrack to function correctly, the full system (Frontend and API) needs to be +deployed and using the Python Container effectively. + +## System Requirements + +## Functional Requirements + +The functional requirements of the system are as follows: + +- The system should be able to accept an enrolment voice file for later comparison. +- The system should be able to accept a new voice file to validate against the enrolment file. +- The system should return readable results to the users (Both Student and Tutor). + +## Interface Requirements + +The interface for the system will be entirely within the OnTrack platform. As such, it will have the +following requirements: + +- The system's interface should be following the same format and design as other sections of the + OnTrack Platform. +- The system should be easy to use for both Tutors and Students. +- The system should return results in a readable way and be clear about the results of the + verification. + +## Hardware Interfaces + +This project is completely software based. + +## Communication Interfaces + +A basic internet connection is required to view the site. + +## Software Interfaces + +The speaker verification system includes the following components: + +- A Python library for audio file validation (Python 3.8) +- Speaker Verification API: contain the backend RESTful API implemented in Django and Python +- Doubtfire and Speaker Verification Integration: Ruby app that integrates the Speaker Verification + API with OnTrack (Doubtfire LMS) via RabbitMQ queue +- Docker-compose: contain the most likely setup for development setups + +## System Features + +The system mainly focuses on the verification of voice files. As such, the features of the system +are as follows: + +- The system will accept voice files for the enrolment of a student in a Unit. +- The system can accept new voice files to verify that the same student is speaking in both files. +- The system will compare two voice files and produce a confidence rating, outlining how confident + it is that the speaker is the same in both voice files. +- The system will return the results to the Tutor and Student to ensure that the users are aware of + the outcome of the verification. + +## Non-functional requirements + +The non-functional requirements of the system largely revolve around the data storage and security +of the system. These include: + +- The system will only keep track of Enrolment files, for later verification use. +- The system will not store voice files for submission and verification. +- The system will be secure. +- The system should be easy to use. +- The system should be in line with other OnTrack systems. + +## Definitions, Acronyms, Abbreviations + +- Docker: a simple container that specify a complete package of components needed to run your + software, or an application build and deployment tool +- RabbitMQ: a message-queueing software also known as a message broker or queue manager. It is + software where queues are defined, to which applications connect in order to transfer a message or + messages. +- Python Library: a library is a collection of pre-written code in Python language that provide + further access to system +- Ruby On Rails: a server-side web application framework written in Ruby. +- Backend: development that happens behind the scenes, it is all the parts of a computer system or + application that is not directly accessed by the user, it is responsible for storing and + manipulating data through code (language use: Python, Ruby) +- Frontend: development on what the user can see and/or directly interact with (language uses: + Angular JS and TypeScript) +- API: Application Programming Interface diff --git a/src/content/docs/Products/OnTrack/Documentation/Voice Verification/voice-verification-user-design-document.md b/src/content/docs/Products/OnTrack/Documentation/Voice Verification/voice-verification-user-design-document.md new file mode 100644 index 00000000..1addd6d6 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/Voice Verification/voice-verification-user-design-document.md @@ -0,0 +1,111 @@ +--- +title: OnTrack Voice Verification User Document +--- + +## Author Information + +--- + +- Author: [Ha Nguyen](https://github.com/hantt-8) +- Team: OnTrack - Voice Verification +- Team (Delivery and/or Product) Lead: ShaeChristmas + +## Document Summary + +--- + +- Documentation Title: Voice Verification User Document +- Documentation Type: Documentation +- Documentation Information Summary: User Design Document detailing guide on Enrolment - How + Students can register their voice to Voice Verification System + +## Document Review Information + +--- + +- Date of Original Document Submission to GitHub: 28/09/2022 +- Documentation Version: 1.0 +- Date of Previous Documentation Review: 28/09/2022 +- Date of Next Documentation Review: to be decided + +## Key Terms + +--- + +A voiceprint is another way to use your unique features to identify who you are, similar to a +fingerprint. + +## Key Links/Resources + +--- + +- [OnTrack Overseer Repository](https://github.com/thoth-tech/doubtfire-overseer) +- [OnTrack Web Repository](https://github.com/thoth-tech/doubtfire-web) +- [OnTrack API Repository](https://github.com/thoth-tech/doubtfire-api) +- [OnTrack Voice Verification Python Container Repository](https://github.com/thoth-tech/speaker-verification) +- [OnTrack Voice Verification API Repository](https://github.com/thoth-tech/speaker-verification-api) + +## Contacts for further information + +--- + +See [Thoth Tech Handbook](https://github.com/thoth-tech/handbook/blob/main/README.md). + +## Related Documents + +--- + +- [Voice Verification Software Requirements and Specifications Document](/products/ontrack/documentation/voice-verification/voice-verification-srs-document) +- [Voice Verification Design Document](https://github.com/thoth-tech/documentation/blob/6354f1f7e1a161d865d408d9d263c36c2e2e73aa/docs/OnTrack/Voice%20Verification/Voice%20Verification%20Design%20Document.md) + +## Delivery Description + +--- + +The OnTrack Voice Verification system allows student to enrol their voice and use their voice print +to verify their identity when discussing or submitting works + +This system would be implemented inside the existing OnTrack Project, and integrated into OnTrack by +using the pre-existing audio submission system. + +Voice Verification system has two phases: + +- Enrolment - Student's voice is recorded and specific voice features are extracted into a voice + print. + +- Verification - Student's audio submission is compared against a previously created voice print. + +## Main Process + +![Proposed how voice verification system work](/Voice-Verification-Overview-Process.png) + +- Verified: The audio file passed a certain confidence value and concluded as same person +- Unverified:The audio file is under a confidence value range and concluded as not a same person +- Pending: The audio is pending/in awaiting queue for comparing + +## Constraints + +--- + +1. Login to OnTrack site as an Deakin student +2. Allow browser use device's microphone +3. Speaking language: English +4. The voice must be between three seconds and one minute +5. The volumes must not exceed 5 MB +6. Supported file types: .wav, mp3, m4a, .flac (now the voice system only accepts .flac type files) + +Tips: Speak at a normal cadence and clearly. + +## Detailed Process + +### Voice Enrolment Check Flow + +![Voice Enrolment GUI](/Voice-Enrolment-Process-Flow.png) + +### Voice Enrolment GUI + +![Voice Enrolment GUI](/Voiceprint-Enrolment-GUI.png) + +## References + +[Speaker Verification Enrolment Flow Example](https://techdocs.audiocodes.com/voice-ai-connect/Content/VAIG_Combined/speaker-verification.htm#:~:text=Each%20speaker%20recognition%20system%20has%20two%20phases%3A%20Enrollment,is%20compared%20against%20a%20previously%20created%20voice%20print.) diff --git a/src/content/docs/Products/OnTrack/Documentation/review-ontrack-github.md b/src/content/docs/Products/OnTrack/Documentation/review-ontrack-github.md new file mode 100644 index 00000000..97e23f53 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Documentation/review-ontrack-github.md @@ -0,0 +1,27 @@ +--- +title: Review of OnTrack folder in GitHub Document +--- + +This document reviews the folders within OnTrack repository and determines which folders fall under +what categories. + +| **Projects** | **Documentation** | +| ---------------------------------------------- | --------------------------------------------------------------------- | +| Group task submission | Deployment –Enhanced Authentication | +| Numbas | Deployment – Google Cloud | +| Staff Grant Extension | Deployment | +| Task Submission& Redesign-Design_Images | Documentation | +| Task Submission& Redesign – misc_media T3-2022 | File Submission Enhancements-Word Document Submission Project Summary | +| Task Submission & Redesign Arrangement | Front End Migration – Framework | +| Tutor Times | Front End Migration - Migration | +| | Front End Migration – Research & Findings | +| | Front End Migration – Testing | +| | Incorporate Content Ontrack | +| | Jupyter Notebook \* Don’t include Meeting Minutes | +| | Multiple Organisations | +| | UI Enhancement \* put under the Front End Migration | +| | Voice Verification | + +| **OnTrack SetUp** | +| ----------------- | +| Local SetUp | diff --git a/src/content/docs/Products/OnTrack/Issues and Resolutions/doubtfire-in-codespaces.md b/src/content/docs/Products/OnTrack/Issues and Resolutions/doubtfire-in-codespaces.md new file mode 100644 index 00000000..ea03e45b --- /dev/null +++ b/src/content/docs/Products/OnTrack/Issues and Resolutions/doubtfire-in-codespaces.md @@ -0,0 +1,139 @@ +--- +title: Spike - Investigate running Dev container and code base in CodeSpaces +--- + +**Spike:** 01 + +**Title:** Investigate running Dev container and code base in CodeSpaces + +**Author:** Brian Caldera, + +![GitHub CodeSpaces Logo](/spike-cover-1.jpg) + +## Goals / Deliverables + +Creating a cloud-based development environment using GitHub Codespaces to run Ontrack is a valuable +initiative to streamline the setup process for students struggling with local development +environments. To explore this, here's a step-by-step guide on setting up Ontrack in a Codespace. + +Codespaces offer a flexible, cloud-based development environment but might have limitations +depending on the specific requirements of the application. Testing and validation are crucial to +ensure it meets the needs of running Ontrack effectively. + +## Technologies, Tools, and Resources used + +- Internet Browser; Google Chroame, FireFox, Safari +- GitHub Account +- GitHub Codespaces +- Docker +- Docker-in-Docker +- GitHub Repository: thoth-tech/dotfire-deploy, thoth-tech/doubtfire-web and + thoth-tech/doubtfire-api +- Text Editor: VsCode +- Terminal: zsh + +## Tasks undertaken + +1. Creating a Codespace + - Sign in to GitHub and navigate to the repository containing Ontrack. (Make sure you fork the + repository first from thoth-tech/dotfire-deploy, thoth-tech/doubtfire-web and + thoth-tech/doubtfire-api) + - Click on the "Code" button and select "Open with Codespaces" or navigate to "Code" > "New + Codespace." + + ![figure-1](/codespaces-8.png) + +2. Install Docker-in-Docker in Codespace + - Confirm that Docker is installed and running in the Codespace by running the following command + in the terminal: wihch docker + + ![figure-2](/codespaces-1.png) + +3. Configuring Codespace for Ontrack: + - Codespaces use a configuration file called .devcontainer to define the development environment. + Create a .devcontainer folder in the root of the Ontrack repository if it doesn’t exist. + (Replace this folder with the existing .devcontainer folder in the repository) + +4. Running Ontrack in Codespace: + - Codespaces will use the defined configuration to create a containerized environment. It will + automatically install dependencies, clone the repository, and set up Ontrack based on the + configuration provided. + + ![figure-3](/codespaces-3.png) + + ![figure-4](/codespaces-4.png) + + ![figure-5](/codespaces-2.png) + +## What we found out + +The front-end seemed to run fine, but the back-end was not working as expected. The back-end server +was not running, and the database was not connected. The following error was displayed in the +terminal: + +```shell +ERROR: ActionDispatch::HostAuthorization::DefaultResponseApp Blocked host: +``` + +![figure-6](/codespaces-7.png) + +![figure-7](/codespaces-6.png) + +![figure-8](/public/codespaces-5.png) + +## Open issues/risks + +Typically this error occurs when the Rails application is configured to allow requests only from +specific hosts for security reasons. When attempting to access the application from an unauthorized +host (in this case, the Codespace), this error is triggered. + +To resolve this issue when running a Rails application in a Codespace, you can modify the +configuration to allow requests from the Codespace host. Here are steps you can take: + +- Step 1: Find the Codespace host name. (To determine the host that your Codespace is using, you can + usually find it in the browser's address bar when you access the application.) +- Step 2: Add the host name to the list of allowed hosts in the Rails application. (To do this, you + can add the host name to the config.hosts array in the config/environments/development.rb file.) +- Step 3: Restart the Rails server. (To restart the Rails server, you can run the following command + in the terminal: `rails s`) + +**Note**: + +Always ensure that the hosts allowed in the config.hosts array are trusted and secured. Adding a +Codespace host should be done cautiously, especially in a production environment. + +By adding the Codespace host to the allowed hosts in your Rails application's configuration, you +should be able to resolve the Blocked host error and access the application within the Codespace +without issues. + +**Important**: + +![figure-9](/codespaces-9.png) + +Ontrack demands substantial resources, specifically a minimum of a 4-core, 16GB RAM, 32GB virtual +machine for smooth operation. This high resource demand could pose a potential issue with +cost-effectiveness, as provisioning Codespaces meeting these specifications might lead to increased +expenses, especially for extended use or multiple concurrent instances. Evaluating the cost +implications alongside performance requirements is crucial before deciding to utilize GitHub +Codespaces for running Ontrack's development environment. Further optimization or alternative +hosting solutions might need consideration to balance performance needs and cost efficiency +effectively. + +## Recommendations + +Despite encountering challenges related to the initial setup and resource requirements, this spike +has significantly increased the team's confidence in the feasibility of deploying Ontrack on GitHub +Codespaces. While there were hurdles to overcome regarding security configurations and +resource-intensive demands, the successful resolution of these issues demonstrates the adaptability +and potential of utilizing Codespaces for development purposes. + +It is recommended that the team proceed with caution and further exploration of deploying Ontrack on +GitHub Codespaces. However, before full implementation, a comprehensive cost-benefit analysis should +be conducted to assess the long-term financial implications of maintaining Codespaces meeting +Ontrack's resource demands. Additionally, ongoing optimizations and adjustments to streamline the +development environment within Codespaces could enhance efficiency and mitigate potential cost +concerns. + +With careful consideration of costs, continuous optimization efforts, and confidence gained from +this spike, the team can move forward confidently toward leveraging GitHub Codespaces for Ontrack's +development environment, recognizing its potential benefits for the development workflow. diff --git a/src/content/docs/products/ontrack/issues-and-resolution/troubleshooting doubtfire setup.md b/src/content/docs/Products/OnTrack/Issues and Resolutions/troubleshooting doubtfire setup.md similarity index 99% rename from src/content/docs/products/ontrack/issues-and-resolution/troubleshooting doubtfire setup.md rename to src/content/docs/Products/OnTrack/Issues and Resolutions/troubleshooting doubtfire setup.md index b333832e..5a68240c 100644 --- a/src/content/docs/products/ontrack/issues-and-resolution/troubleshooting doubtfire setup.md +++ b/src/content/docs/Products/OnTrack/Issues and Resolutions/troubleshooting doubtfire setup.md @@ -9,7 +9,6 @@ title: Troubleshooting Doubtfire Setup > You need to change β€œdocker compose” of file run-full.sh in doubtfire-deploy/development 2. doubtfire-web doesn’t compile successfully: - - Open terminal - Head to folder doubtfire-deploy/development by cd - Run this in 1 line: @@ -20,7 +19,6 @@ title: Troubleshooting Doubtfire Setup ``` 3. doubtfire-api don’t run and exit with code 0/1. - - Open terminal - Head to folder doubtfire-deploy/development by cd - Run this in 1 line: diff --git a/src/content/docs/Products/OnTrack/Ontrack Setup/How to Run OnTrack with Ubuntu.md b/src/content/docs/Products/OnTrack/Ontrack Setup/How to Run OnTrack with Ubuntu.md new file mode 100644 index 00000000..cc4b7d0c --- /dev/null +++ b/src/content/docs/Products/OnTrack/Ontrack Setup/How to Run OnTrack with Ubuntu.md @@ -0,0 +1,144 @@ +--- +title: How to Run OnTrack with Ubuntu on an External SSD +--- + +:::note + +More Set Up guides located in the +[Front End Migration/Deploy OnTrack](/products/ontrack/documentation/front-end-migration/deploy-ontrack/setting-up-doubtfire) +folder. + +::: + +## Requirements + +- A PC with Windows 10 installed. +- An external SSD with at least 64GB of storage. +- A USB drive with at least 8GB of storage. (Recommended) + +## 1. Download Ubuntu and Rufus + +- Download [Ubuntu](https://ubuntu.com/download/desktop) from the official website. +- Download [Rufus](https://rufus.ie/en/). + +## 2. Create a Bootable USB Drive + +1. Open Rufus. +2. Select the USB drive from the 'Device' dropdown. +3. Click the 'SELECT' button to choose the Ubuntu ISO (should be in your downloads folder). +4. Click the 'START' button at the bottom. + + ![Rufus Start](/rufus_screenshot.png) + +## 3. Prepare Booting + +1. Plug the USB or SSD into your PC. +2. Restart your PC and continually hit the boot menu key to open BIOS settings. + + ![Boot Keys](/bootkeys.png) + +3. There should be a list of boot options including Windows Boot Manager. Select the bootable USB + with the Ubuntu ISO. +4. The Ubuntu OS will load in portable mode from the USB. + +## 4. Install Ubuntu on External SSD + +1. After booting into Ubuntu you should be provided with the option to Try Ubuntu or Install Ubuntu. + Select Install Ubuntu. + + ![Ubuntu Boot Options](/ubuntu_options.png) + +2. If not prompted, open the "Install Ubuntu" application from the desktop. + + ![Ubuntu Desktop](/install_ubuntu.png) + +3. Proceed through the initial steps until you reach the "Installation type" step. +4. Choose the "Something else" option to manually configure partitions. +5. Identify the external SSD as a device like `/dev/sdb`. + + ![Installation Type](/installation_type.png) + +## 5. Partitioning + +1. Create the root partition: + - Use as: Ext4 journaling file system. + - Mount point: / + - Tick the box to format. + + ![Root Partition](/root_partition.png) + +2. Click OK to start the installation. +3. Select your timezone. + +## 7. Deakin WiFi Setup (Optional) + +1. Connect to the Deakin Setup WiFi network. +2. It should launch this webpage in your browser. + + ![Deakin Setup Page](/deakin_setup_page.png) + +3. Click the JoinNow button to download the setup wizard. +4. Change directory into the `Downloads` folder in the terminal. + + ```shell + cd Downloads + ``` + +5. Enter the following command in the terminal to connect to the wifi network and follow the prompts + to enter your Deakin username and password. + + ```shell + sh SecureW2_JoinNow.run + ``` + + ![Deakin Setup Terminal](/deakin_setup_terminal.png) + +## 6. Install Additional Software + +1. After installation, open a terminal. +2. Install Git: + + ```shell + sudo apt install git + ``` + +3. Install Docker + + ```shell + sudo apt install docker.io + ``` + +4. Install vscode + + ```shell + sudo snap install --classic code + ``` + +## 7. Clone OnTrack Repository + +1. Clone the OnTrack repository (change `YOUR_USERNAME` to your GitHub username): + + ```shell + git clone --recurse-submodules git clone https://github.com/YOUR_USERNAME/doubtfire-deploy + ``` + +2. Open the `doubtfire-deploy` folder in vscode: + + ```shell + cd doubtfire-deploy + code . + ``` + +3. Run change remotes script in the integrated terminal to change the remote to your own repository. + + ```shell + ./change-remotes.sh + ``` + + and follow the prompts to enter your GitHub username. + +## 8. Run OnTrack + +1. After re-opening vscode, the script should automatically run and open the OnTrack application in + your browser. +2. Happy coding! diff --git a/src/content/docs/Products/OnTrack/Ontrack Setup/TutorialSetupT3.mdx b/src/content/docs/Products/OnTrack/Ontrack Setup/TutorialSetupT3.mdx new file mode 100644 index 00000000..9cf2b126 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Ontrack Setup/TutorialSetupT3.mdx @@ -0,0 +1,258 @@ +--- +title: OnTrack Development Setup Guide - 2025T3 +--- + +## Before You Begin + +Before starting the setup, ensure the following are installed and ready: + +- Visual Studio Code (VS Code) +- Git +- A GitHub account (used to fork the repositories) + +If you have attempted the setup previously and encountered errors. It is recommended to restart +Docker Desktop Follow this guide from the beginning to avoid configuration issues. + +## Video walkthrough + +If you prefer a visual guide, you can watch the full OnTrack development setup walkthrough here: + +β–Ά **OnTrack development setup video** + +The full setup video is hosted on the Deakin shared drive: + +[Watch the OnTrack setup video (Deakin SharePoint)](https://deakin365.sharepoint.com/:f:/r/sites/ThothTech2/Shared%20Documents/OnTrack/Ontrack%20Development%20Setup%20T3%202025?csf=1&web=1&e=B3ih2G) + +## 1. INSTALLING DOCKER DESKTOP + +Docker Desktop is essential for running the OnTrack development container. + +Steps: + +- Download Docker Desktop from `docker.com` + +- For Windows users: +- Docker Desktop installation includes Windows Subsystem for Linux (`WSL2`) +- If `WSL2` isn't automatically installed, follow the setup wizard +- Docker Desktop installs WSL (aka whistle) as part of the process + +- Complete the installation and restart your computer if prompted + +- Start Docker Desktop and ensure it is running before proceeding + +- Verify installation by opening a terminal and running: + `docker --version` + +IMPORTANT: Keep Docker Desktop running throughout the development process. + +## 2. FORKING THE REQUIRED REPOSITORIES + +OnTrack consists of three main repositories that need to be forked from Doubtfire LMS: + +### Required Repositories + +OnTrack consists of three main repositories that need to be forked from Doubtfire LMS: + +1. `doubtfire-deploy` + - Contains `docker-compose` configuration + - Main deployment setup + +2. `doubtfire-api` + - Backend API (Ruby on Rails) + - Contains the Ruby application code + +3. `doubtfire-web` + - Frontend application (Angular) + - Contains the user interface + +### Optional (for testing) + +4. `doubtfire-lti` + - Used for LTI integration testing + +How to Fork: + +- Navigate to the Thoth Tech GitHub organisation: + `https://github.com/thoth-tech/` + +- For each repository (`deploy`, `api`, `web`): a. Go to the repository page + b. Ensure you're on the `development` branch initially + c. Click the **Fork** button in the top-right + d. Keep all default settings + e. **Uncheck** β€œCopy the main branch only” if shown + f. Click **Create fork** + +Your forked repositories will appear at: + +- `https://github.com/YOUR_USERNAME/doubtfire-deploy` +- `https://github.com/YOUR_USERNAME/doubtfire-api` +- `https://github.com/YOUR_USERNAME/doubtfire-web` + +## 3. PULLING THE DOCKER IMAGE + +Before starting development, pull the required Docker image from Docker Hub. +The Docker image contains all dependencies for OnTrack development. + +Steps: + +- Open Docker Desktop terminal (recommended for Windows users) +- In Docker Desktop, click the terminal icon at the bottom + +- Run the following command: + `docker pull lmsdoubtfire/formatif-dev-container:10.0.0-14` + +Note: + +- The version number (`10.0.0-14`) comes from the `docker-compose.yaml`. +- File in the `doubtfire-deploy` repository. + +- This will download all dependencies and may take several minutes + +- Verify the image was pulled by running: + `docker images` + You should see `lmsdoubtfire/doubtfire-dev-container:10.0.0-14` + +Where to find the image version: + +- Open `doubtfire-deploy/docker-compose.yaml` +- Look under `services` > `image` +- The format is: `lmsdoubtfire/doubtfire-dev-container:[version]` + +## 4. CLONING REPOSITORIES LOCALLY + +Now clone your forked repositories to your local machine. + +Steps: + +- Open your terminal (PowerShell on Windows, Terminal on macOS/Linux) + +- Navigate to your preferred directory: `cd ~` + or + `cd C:\Users\YOUR_USERNAME\Documents\Projects` + +- Clone `doubtfire-deploy` first: `git clone https://github.com/YOUR_USERNAME/doubtfire-deploy.git` + +- Navigate into the directory: `cd doubtfire-deploy` + +- Clone the remaining repositories: `git clone https://github.com/YOUR_USERNAME/doubtfire-api.git` + `git clone https://github.com/YOUR_USERNAME/doubtfire-web.git` + +- (Optional) Clone `doubtfire-lti`: `git clone https://github.com/YOUR_USERNAME/doubtfire-lti.git` + +You should now have: `doubtfire-deploy/` +`β”œβ”€β”€ doubtfire-api/` +`β”œβ”€β”€ doubtfire-web/` +`└── doubtfire-lti/ (optional)` + +## 5. SETTING UP GIT REMOTES + +Git remotes allow you to sync with both your fork (`origin`) and the ThothTech repository +(`upstream`). + +Understanding remotes: + +- `origin`: your forked repository on GitHub +- `upstream`: ThothTech’s repository + +Steps for `doubtfire-deploy`: + +- Check current remotes: + `git remote -v` + +- Add ThothTech as upstream: + `git remote add upstream https://github.com/thothtech/doubtfire-deploy.git` + +- Verify: + `git remote -v` + +Repeat the same steps for: + +- `doubtfire-api` +- `doubtfire-web` + +## 6. SWITCHING TO THE CORRECT BRANCH + +IMPORTANT: You must work on the `10.0.x` branch, not `main` or `development`. + +For each repository: + +- Check current branch: `git branch` +- Switch branch: `git checkout 10.0.x` +- Pull latest changes: `git pull` +- Verify: `git status` + +(Optional but recommended): +`git fetch` + +## 7. OPENING IN VS CODE + +Now open the `doubtfire-deploy` directory in VS Code. + +Steps: + +- From the `doubtfire-deploy` directory, run: + `code .` + +Alternatively: + +- Open VS Code manually +- Select **File > Open Folder** +- Choose the `doubtfire-deploy` folder + +## 8. STARTING THE DEVELOPMENT CONTAINER + +The development container runs all OnTrack services inside Docker. + +Automatic method: + +- VS Code will detect the `.devcontainer` configuration +- A popup will appear saying **β€œReopen in Container”** +- Click **Reopen in Container** + +Manual method: + +- Press `Ctrl+Shift+P` (`Cmd+Shift+P` on macOS) +- Type `Dev Containers: Reopen in Container` +- Select the option + +## 9. ACCESSING THE APPLICATION + +Once the container is running, OnTrack will be accessible via your browser. + +Ports: + +- `localhost:4200` – OnTrack frontend (Angular) +- `localhost:3000` – OnTrack API (Ruby on Rails) + +Default admin credentials: + +- Username: `admin` +- Password: `password` + +## 10. TROUBLESHOOTING + +Issue: Docker Desktop not running +Solution: + +- Open Docker Desktop +- Wait for it to fully start +- Reopen the container in VS Code + +Issue: Wrong branch +Solution: + +- Run `git checkout 10.0.x` + +Issue: CSS not loading +Solution: + +- Wait a few minutes +- Refresh the page + +## CONCLUSION + +You have now successfully set up the OnTrack development environment. + +Document Version: 2025T3 +Last Updated: November 2025 +Author: Jayam Patel diff --git a/src/content/docs/Products/OnTrack/Projects/Group Task Submission/group-task-submission-doc.md b/src/content/docs/Products/OnTrack/Projects/Group Task Submission/group-task-submission-doc.md new file mode 100644 index 00000000..78730c6a --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Group Task Submission/group-task-submission-doc.md @@ -0,0 +1,118 @@ +--- +title: Design a way to improve the group Task submission - Documen +--- + +## Solution 1: Selecting Students Who Can Submit + +Solution 1 requires certain changes to be made in the frontend and backend which are described as +follows: + +## Frontend Changes + +- **User Interface Updates:** + +The frontend interface needs to be updated to allow instructors to select which students are +eligible to submit a particular task. This could involve adding a checkbox or similar UI element for +each student when creating or configuring a task. + +- **Task Submission:** + +The task submission process for students should include a check to determine if they are eligible to +submit based on the CanSubmitTask attribute. If they are not eligible, an appropriate error message +should be displayed. + +- **Task Status Display:** + +The frontend should display the submission status of each task, showing whether it has been +submitted or not. + +**Backend Changes:** + +- **Database Schema Updates:** + +The database schema needs to be updated to include the CanSubmitTask attribute in the User table. + +- **Task Submission Logic:** + +The backend logic for task submission should check the CanSubmitTask attribute of the user to +determine whether the submission is allowed. If allowed, update the SubmissionStatus attribute of +the associated task to "Submitted." + +- **API Endpoints:** + +New API endpoints might be needed to manage task submission eligibility, such as updating the +CanSubmitTask attribute for users. + +- **Data Validation:** + +Backend logic should validate that only eligible students can be associated with tasks when creating +or updating tasks. + +- **Error Handling:** + +Proper error handling and status codes should be implemented to handle cases where submission is not +allowed. + +- **Notifications:** + +Instructors may want to be notified when a student submits a task, or when a submission is rejected +due to eligibility. + +## Solution 2: Adding Password for Certain Students + +Solution 2 requires certain changes to be made in the frontend and backend which are described as +follows: + +## Frontend Changes`` + +- **User Interface Updates:** + +Modify the user interface to prompt students for their submission password when attempting to submit +a task. + +- **Task Submission Form:** + +Add a field for students to enter their submission password while submitting a task. + +- **Submission Validation:** + +Implement frontend logic to validate the submission password before allowing the task submission. +Display appropriate messages if the password is incorrect. + +## Backend Changes + +- **Database Schema Updates:** + +Update the database schema to include the SubmissionPassword attribute in the User and Task tables. + +- **Task Submission Logic:** + +Implement backend logic to compare the user's submitted password with the stored password. If they +match, update the SubmissionStatus attribute of the associated task to "Submitted." + +- **API Endpoints:** + +Create new API endpoints to handle the password validation during task submission. + +- **Data Validation:** + +Implement backend data validation to ensure that only eligible users with the correct password can +submit tasks. + +- **Error Handling:** + +Implement proper error handling for password validation and submission process. + +- **Notifications:** + +Consider implementing notifications to inform users about successful or unsuccessful task +submissions. + +- **Security Measures:** + +Implement secure password storage practices (such as hashing and salting) to protect user passwords. + +- **Password Management:** + +Provide a way for users to reset their submission password if needed and, ensure secure password +reset procedures. diff --git a/src/content/docs/Products/OnTrack/Projects/Group Task Submission/group-task-submission-uml-design.md b/src/content/docs/Products/OnTrack/Projects/Group Task Submission/group-task-submission-uml-design.md new file mode 100644 index 00000000..87cdbb01 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Group Task Submission/group-task-submission-uml-design.md @@ -0,0 +1,29 @@ +--- +title: Design a way to improve the group Task submission – UML design +--- + +## Solution 1: Selecting Students Who Can Submit + +In this solution, the system allows the instructor to specify which students are eligible to +submitthe group task. Each user (student) is associated with a task through a one-to-one +relationship, indicated by the "1" multiplicity on both sides of the association line. The +CanSubmitTask attribute is a boolean alue indicating whether a user can submit the task. The +SubmissionStatus attribute in the Task class reflects whether a task has been submitted or not. When +a user submits the task, the system checks the CanSubmitTask attribute to determine if the +submission is allowed. If allowed, the SubmissionStatus attribute of the task is updated to +"Submitted." If not, the submission is rejected. + +![solution](/Solution_1.png) + +## Solution 2: Adding Password for Certain Students + +In this solution, a password-based approach is used to control task submissions. Each user (student) +is associated with a task through a one-to-one relationship, indicated by the "1" multiplicity on +both sides of the association line. Each user has a unique SubmissionPassword attribute acting as a +password for task submission. Similarly, the Task class also has a SubmissionPassword attribute. +When a user attempts to submit a task, they need to provide their SubmissionPassword. The system +validates this password against the user's stored password. If the passwords match, the task is +considered submitted, and the SubmissionStatus attribute of the task is updated to "Submitted." +Otherwise, the submission is rejected. + +![solution](/Solution_2.png) diff --git a/src/content/docs/products/ontrack/documentation/numbas/Numbas Feasibility Check.md b/src/content/docs/Products/OnTrack/Projects/Numbas/NumbasFeasabilityCheck.md similarity index 95% rename from src/content/docs/products/ontrack/documentation/numbas/Numbas Feasibility Check.md rename to src/content/docs/Products/OnTrack/Projects/Numbas/NumbasFeasabilityCheck.md index ca9a7aef..26317c3c 100644 --- a/src/content/docs/products/ontrack/documentation/numbas/Numbas Feasibility Check.md +++ b/src/content/docs/Products/OnTrack/Projects/Numbas/NumbasFeasabilityCheck.md @@ -8,14 +8,14 @@ title: Project feasability study document **Ontrack**. -**Numbas feasibility check**. +## Numbas feasibility check -**Preamble**. +## Preamble The aim of this study is to check the feasibility of setting up or linking Numbas into Ontrack a live production environment running on Rails/Angular. -**Research information**: +## Research information For this project I have been reviewing several links and pages of information to ensure we take the correct direction. As well as to upskill to ensure I have the key skills required for this project. @@ -30,7 +30,7 @@ correct direction. As well as to upskill to ensure I have the key skills require [https://community.dataminer.services/information-security-research-unsafe-attribute-bindings-on-iframe-elements-in-angular/](https://community.dataminer.services/information-security-research-unsafe-attribute-bindings-on-iframe-elements-in-angular/) -**Outcome**. +## Outcome So after some research the two main ways we can approach this task is to embed an iframe, then later capture the test objecet and store it. @@ -41,7 +41,7 @@ natively. The second option initially looks more secure and longer to setup, I was concerned about iFrame from a security risk related to XSS, however it looks like in Angular 15 this was resolved. -**Plan**. +## Plan I will look at configuring both solutions and see which one performs best and gives us the best features moving forward. Hopefully by week 6 a have a trial version of both and make the final diff --git a/src/content/docs/Products/OnTrack/Projects/Numbas/NumbasProjectGuideline.md b/src/content/docs/Products/OnTrack/Projects/Numbas/NumbasProjectGuideline.md new file mode 100644 index 00000000..7fada546 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Numbas/NumbasProjectGuideline.md @@ -0,0 +1,43 @@ +--- +title: Project guideline document +--- + +## Daniel Maddern + +## Project guideline – Numbas Integration to Ontrack + +## Aim + +The aim is to introduce Numbas tests into the Ontrack platform, to ultimately save these results in +the Database. + +The first part of the project will be to enable the creation and use of a Numbas test, without +storing the data, then time dependent we will look at enhancing this to saving the data to the +backend and a means to access that information. + +## Key Outcomes + +- Feasibility report of product – Check how this can be achieved and the potential problems with the + possible solutions. +- Front end integration to either host or link an existing numbas test for students to complete. +- Back-end configuration to store the numbas test +- Security check of the component + +## Delivery Time frames + +I will be aiming to have the feasibility report and the Front end integration working to a standard +of production by the end of T1 2023. + +We will be aiming for Back end configuration and storing of tests by the end of T2 2023. + +## Team Members + +Product : Ontrack + +Deliver Lead – Daniel Maddern + +Team Members – TBA + +Skills required: + +Angular, Ruby on Rails, API integration/Package installation. diff --git a/src/content/docs/Products/OnTrack/Projects/Numbas/ProjectSignOffNumbas.md b/src/content/docs/Products/OnTrack/Projects/Numbas/ProjectSignOffNumbas.md new file mode 100644 index 00000000..38f8f7b7 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Numbas/ProjectSignOffNumbas.md @@ -0,0 +1,90 @@ +--- +title: Project Name:Numbas Integration +--- + +## Delivery Lead: Daniel Maddern + +## Student Name: Daniel Maddern + +## Clients: Julien, Andrew, Jake + +## **Scope** + +The purpose of this project is to integrate Numbas testing into Ontrack. With the aim for a test to +be presented to the student on submission of a task, prior to submitting reflections or other +required documents. The aim is o be able to let the Unit Chair import, setup and assign tests to the +tasks. Also for students to be able to complete tests as part of the submission process. + +## **Outcomes** + +This project will be deliverying: + +- A project scope for the clients to sign off on. +- A feasiblity study of the ways this can be implemented. +- A rough design document including: + - Rough hand drawn design documents for how this intergration will work. + - A data flow diagram of how different data will be accesssed and encapsualted. + - Diagrams showing model changes to the core model + - Backend coding changes to accomodate and store the tests. + - Front end code to support the changes from the Unit chair and student view. +- Unit tests to ensure features work as expected + +## **Delivery** + +### Features + +- Deliverables + - Design document - sketches of new UI, model changes, API changes + - Web and API changes +- Features + - Unit chairs can upload Numbas tests to a task definition + - Unit chairs can validate that the test works + - Unit chairs can set the required pass level for the test + - Unit chairs can set the number of attempts before test needs to be reset by a tutor + - Unit chairs can set the delay between attempts to be a set number of minutes, or a built-in + increasing delay + - Students are required to pass the test before they can submit work for feedback + - Students can view their test attempts (can unit chairs disable this?) + - Tutors can view student test attempts + - Tutors can reset student tests to enable additional attempts - or require resit on resubmission + - Test results are included in the portfolio when generated + +There will need to be a means to upload the test files that are created locally via Numbas. An +Addtional window after "requesting feedback" on a task that will present the test, this will then +either take you to the next stage if you pass or go back to the task screen if you do not pass. + +There will need to be a configuration section within the Unit chair task setup page. + +We will provide different options for the test setup such as: + +1: Restricted / Unlimited test attempts 2: Delays in test attempts - minutes, or built-in +increamenting delay + +We will also need to either enable or disable a test. + +**Student View** ![StudentView](/StudentView.jpg "Student View Design") + +**Unit Chair View** ![UnitChair](/UnitChair.jpg "Unit Chair Design") + +**Data Flow Design** ![DataFlow](/DataFlow.jpg "Data Flow Design") + +In terms of the changes we will require, we will need a new table in the DB to store the tests. + +We will need to create a new API and model to transfer the test data between the front and the back +end. + +We will need to create a new service and model in Angular to accomodate this, we will also need to +adjust the existing services such as Unit/Tasks to include the test objects for a student user. + +Then we will need to create a new componente for taking the test, as well as adjust the Unit Chair +Task Setup component to include the new settings as per the design above. + +## **Sign Off:** + +Delivery Lead Signature: +\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ + +Team Member Signature: +\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ + +Client Signature: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ diff --git a/src/content/docs/Products/OnTrack/Projects/Numbas/ProjectSignOffTemplate.md b/src/content/docs/Products/OnTrack/Projects/Numbas/ProjectSignOffTemplate.md new file mode 100644 index 00000000..2407a9a5 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Numbas/ProjectSignOffTemplate.md @@ -0,0 +1,36 @@ +--- +title: Project Documentation Template +--- + +## Delivery Lead: \<\\> + +## Student Name:\<\\> + +## Student ID: \<\< Student ID\>\> + +## Client: \<\\> + +## **Scope** + +\<\\> + +## **Outcomes** + +\<\\> + +## **Delivery** + +\<\\> + +\<\< Also include Delivery times for stages of the project\>\> + +## **Sign Off:** + +Delivery Lead Signature: +\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ + +Team Member Signature: +\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ + +Client Signature: \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ diff --git a/src/content/docs/Products/OnTrack/Projects/Numbas/SpikeOutcome-Scorm2004.md b/src/content/docs/Products/OnTrack/Projects/Numbas/SpikeOutcome-Scorm2004.md new file mode 100644 index 00000000..e94bd3ac --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Numbas/SpikeOutcome-Scorm2004.md @@ -0,0 +1,114 @@ +--- +title: Spike Outcomes +--- + +**Spike:** 1 + +**Title:** Understanding the SCORM 2004 API structure + +**Author:** Daniel Maddern, + +## Goals & Deliverables + +After several issues with the NUMBAS integration and having to move to SCORM 2004, this Spike is +intended to revise the updated functionality of SCORM 2004 and how it works, how the functions can +be used in the current project. + +## Technologies Tools and Resources used + +List of information needed by someone trying to reproduce this work + +- Internet Browser; Google Chroame, FireFox, Safari +- Programming Languages: +- Angular/TypeScript/JavaScript +- Programming Libraries: +- PipWerks SCORM +- Text Editor: VsCode +- Terminal + +## Tasks undertaken + +Key Tasks + +- Review the key functions available in SCORM 2004 + () + +- See how each function could be applied to NUMBAS + +- Test the functionality out in the PoC + +## What we found out + +There are some big changes between SCORM 1.1 and 2004, the key methods used in 2004 are: + +- Initialize( β€œβ€ ) : bool – Begins a communication session with the LMS. + +- Terminate( β€œβ€ ) : bool – Ends a communication session with the LMS. + +- GetValue( element : CMIElement ) : string – Retrieves a value from the LMS. + +- SetValue( element : CMIElement, value : string) : string – Saves a value to the LMS. + +- Commit( β€œβ€ ) : bool – Indicates to the LMS that all data should be persisted (not required). + +- GetLastError() : CMIErrorCode – Returns the error code that resulted from the last API call. + +- GetErrorString( errorCode : CMIErrorCode ) : string – Returns a short string describing the + specified error code. + +- GetDiagnostic( errorCode : CMIErrorCode ) : string – Returns detailed information about the last + error that occurred. + +They Key Data Model elements for our use are: + +- cmi.entry (ab_initio, resume, β€œβ€, RO) Asserts whether the learner has previously accessed the SCO + +- cmi.exit (timeout, suspend, logout, normal, β€œβ€, WO) Indicates how or why the learner left the SCO + +- cmi.learner_id (long_identifier_type (SPM: 4000), RO) Identifies the learner on behalf of whom the + SCO was launched + +- cmi.mode (β€œbrowse”, β€œnormal”, β€œreview”, RO) Identifies one of three possible modes in which the + SCO may be presented to the learner + +- cmi.score.scaled (real (10,7) range (-1..1), RW) Number that reflects the performance of the + learner + +- cmi.score.raw (real (10,7), RW) Number that reflects the performance of the learner relative to + the range bounded by the values of min and max + +- cmi.score.min (real (10,7), RW) Minimum value in the range for the raw score + +- cmi.score.max (real (10,7), RW) Maximum value in the range for the raw score + +- cmi.suspend_data (characterstring (SPM: 64000), RW) Provides space to store and retrieve data + between learner sessions + +- cmi.total_time (timeinterval (second,10,2), RO) Sum of all of the learner’s session times + accumulated in the current learner attempt + +- cmi.success_status (β€œpassed”, β€œfailed”, β€œunknown”, RW) Indicates whether the learner has mastered + the SCO + +- cmi.session_time (time interval (second,10,2), WO) Amount of time that the learner has spent in + the current learner session for this SCO + +By making use of the flags in the data model we can implement a resume test functionality, this will +be done by saving the suspend data json string in the DB. + +A new end point will need to be created to store the suspend data json string, as well as the +Attempt number, status and isnew flag. + +## Recommendations + +It is reccomended to build out the new endpoint needed in the PoC and then to implement a resume +test functionality there + +prior to starting the build in Ontrack. The new Endpoint would be in addition to the current Numbas +API that streams the test. + +It would need a get and put functionlaity and would be making use of cmi.mode, cmi.suspend_data +during both Commit and Terminate functions. + +We also need to move the intitaliztion of the Window object outside of the launch test in the front +end Angular code. diff --git a/src/content/docs/Products/OnTrack/Projects/Staff Grant Extension/DESIGN.md b/src/content/docs/Products/OnTrack/Projects/Staff Grant Extension/DESIGN.md new file mode 100644 index 00000000..cb2e044f --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Staff Grant Extension/DESIGN.md @@ -0,0 +1,374 @@ +--- +title: Design Document:OnTrack - Staff Grant Extension Featur +--- + +## 1-Introduction + +This document outlines the design approach for integrating the "Staff Grant Extension" feature into +OnTrack, our learning management system. This feature empowers staff members to grant extensions to +students, even without formal requests. The purpose is to cater to unique situations that might +require tailored support. + +The "Staff Grant Extension" feature enables staff to initiate extension requests, define durations, +and create extension records for students. The system automates notifications to students about +granted extensions, fostering transparent communication. + +This design document covers technical implementation, user authentication, UI, error handling, +testing, and deployment aspects. It ensures the feature's smooth integration, responsiveness, +security, and scalability. The goal is to enhance OnTrack's adaptability and communication, +ultimately benefiting both staff and students. + +## 2-Use Case + +### 2-1-User Story + +As a staff member, I want to be able to grant extensions to students, even when no formal extension +requests are submitted through the system. This allows me to accommodate special circumstances that +may have been communicated through other means. + +### 2-2-Acceptance Criteria + +- Staff members can initiate extension requests for specific students. +- Staff members can specify the duration of the extension. +- Extension requests initiated by staff members are recorded in the system for future reference. +- Students receive notifications about granted extensions. + +## 3-High-level Architecture + +The "Staff Grant Extension" feature seamlessly integrates into the existing architecture of the +OnTrack system. This architecture consists of both frontend and backend components, each +contributing to the feature's functionality and user experience. + +### 3-1-Frontend Architecture + +The frontend of the feature is designed to provide an intuitive and user-friendly interface for +staff members to initiate extension requests. The key components include: + +- **Grant Extension Form:** Integrated into the staff dashboard, this form enables staff members to + select a student, specify the extension duration, add relevant notes, and indicate the reason for + the extension. A search interface allows easy student selection. This form is built using Angular + and styled with Tailwind CSS for a consistent and responsive user experience. + +- **Notifications**: The frontend also handles the notifications sent to students. Upon a staff + member's extension grant, notifications are triggered. The frontend ensures these notifications + are displayed to students, either through email or within the system. + +### 3-2 Backend Architecture + +The backend architecture focuses on processing extension requests, managing extension records, and +ensuring data security. Backend components include: + +- **Extension Record Management:** When a staff member grants an extension, the backend stores + extension records in the database. These records are associated with the student and staff member + involved, along with the specified extension duration. Ruby on Rails, the backend framework, + manages data interactions and database updates. + +- **User Authentication and Authorisation:** The backend enforces user authentication to ensure that + only authorised staff members can access the "Grant Extension" functionality. Access controls are + implemented to secure data and maintain system integrity. + +The collaboration between frontend and backend components ensures a cohesive user experience. Staff +members interact with the intuitive form at the frontend, triggering backend processes that record +extension data securely in the database. Meanwhile, students receive notifications regarding granted +extensions, enhancing communication and transparency. + +This architecture underscores the feature's user-centric design, smooth integration with existing +systems, and adherence to best practices for security and usability. The separation of frontend and +backend responsibilities enables efficient development, testing, and maintenance, contributing to +the feature's overall success within the OnTrack system. + +## 4-Technical Implementation + +The implementation of the "Staff Grant Extension" feature involves both frontend and backend +development, utilizing the existing technology stack of the OnTrack system. + +### 4-1 Frontend Implementation + +#### _Grant Extension Form:_ + +The frontend implementation revolves around the creation of the "Grant Extension" form within the +staff dashboard. This involves the following steps: + +- **UI Integration:** Integrate the form seamlessly into the staff dashboard using Angular + components. Ensure its responsive design using Tailwind CSS, providing a user-friendly experience + across devices. + +- **Form Fields:** Implement form fields for selecting students, entering extension duration, adding + notes, and specifying the reason for the extension. Create an interface for searching and + selecting students efficiently. + +#### _Notifications:_ + +The frontend is responsible for handling notifications sent to students: + +- **Notification Trigger:** Upon extension grant, trigger the notification mechanism. Depending on + student preferences, notifications are sent either via email or displayed within the system. + +### 4-2 Backend Implementation + +#### _Extension Record Creation:_ + +Backend implementation focuses on processing extension requests, managing extension records, and +ensuring secure data handling: + +- **API Endpoint:** Create an API endpoint to handle extension grant requests from the frontend. + Validate inputs, including extension duration. + +- **Database Interaction:** Upon successful validation, store extension records in the database. + Associate each record with the relevant student and staff member. Utilize Ruby on Rails' ORM + (Object-Relational Mapping) for seamless data management. + +#### _User Authentication and Authorisation:_ + +Implement user authentication and authorisation to secure the feature: + +- **Authentication:** Leverage existing authentication mechanisms to ensure only authenticated staff + members access the "Grant Extension" functionality. + +- **Authorisation:** Apply access controls to authorise staff members based on their roles and + permissions. This guarantees data security and minimizes unauthorised access. + +The successful integration of the frontend and backend components ensures the seamless operation of +the feature. Staff members interact with the frontend form, which triggers backend processes to +store extension records and handle notifications. This technical implementation enhances the OnTrack +system's capabilities, enabling staff members to provide individualized support to students and +fostering efficient communication within the platform. + +## 5-Database Design + +The database design for the "Staff Grant Extension" feature revolves around efficiently storing +extension records and maintaining the associations between students, staff members, and granted +extensions. + +### _Extension Records:_ + +- **Table:** Create a new table named "ExtensionRecords" to store extension-related information. +- **Columns:** + - **id:** Unique identifier for each extension record. + - **student_id:** Foreign key referencing the student associated with the extension. + - **staff_member_id:** Foreign key pointing to the staff member who granted the extension. + - **duration:** The duration of the extension in days or hours. + - **reason:** The reason provided for granting the extension. + - **created_at:** Timestamp indicating when the extension record was created. + +### _Associations:_ + +- **Student and Staff Member Associations:** Establish relationships between extension records, + students, and staff members using foreign keys. +- **Extensions to Students:** Link extension records to the respective students they apply to. +- **Extensions by Staff Members:** Associate extension records with the staff members who granted + the extensions. + +This database design ensures efficient querying and retrieval of extension data, enabling staff +members to track granted extensions and students to view their extension history. + +By adhering to this structured database design, the "Staff Grant Extension" feature effectively +maintains a historical record of granted extensions and establishes clear relationships between +students, staff members, and extension records. This architecture guarantees data integrity, +simplifies reporting and auditing, and contributes to the seamless operation of the feature within +the OnTrack system. + +[UML - Staff Grant Extension](https://lucid.app/lucidchart/06237ce4-9cd9-4aad-838f-45bff2249059/edit?invitationId=inv_da8c9660-84a6-46a3-9690-f210fc5ceb8d) + +## 6-User Interface Design + +[UI - Staff Grant Extension](https://www.figma.com/team_invite/redeem/MRSQ5n3VRvoVqTm4Eu3sGc) + +## 7-Error Handling and Validation + +Error handling and validation are critical aspects of ensuring the robustness and reliability of the +"Staff Grant Extension" feature. The system must effectively handle user errors and input anomalies +while maintaining data integrity. + +### Frontend Validation + +- **Form Validation:** Implement client-side form validation to prevent invalid data from being + submitted. Validate extension duration to ensure it's a positive numeric value. +- **Error Messages:** Display clear error messages next to the relevant form fields in case of + validation errors. Inform users about the specific issue and guide them towards correcting it. + +### Backend Validation + +- **API Input Validation:** Validate the input received from the frontend at the backend. Ensure + that the duration is a valid positive numeric value and that all required fields are provided. +- **Error Responses:** Return appropriate error responses if validation fails. Include relevant + error codes and messages to guide developers in diagnosing and addressing the issue. + +## Database Integrity + +- **Foreign Key Integrity:** Ensure the integrity of foreign key relationships between extension + records, students, and staff members. Reject extension creation if associated entities do not + exist. +- **Data Consistency:** Maintain consistent data by validating the input against predefined rules + and constraints. Avoid situations where data conflicts or contradictions arise. + +## Exception Handling + +- **Server-Side Errors:** Implement exception handling in the backend to catch unexpected errors + during processing. Log these errors for debugging purposes and provide users with a friendly error + message. + +- **Client-Facing Errors:** Translate backend errors into user-friendly messages on the frontend to + maintain a positive user experience. + +By rigorously implementing error handling and validation mechanisms, the "Staff Grant Extension" +feature ensures that user inputs are accurate, data integrity is maintained, and users are guided +through corrective actions when necessary. This approach contributes to a seamless and +frustration-free experience for both staff members and students, enhancing the overall reliability +of the OnTrack system. + +## 8-Testing Strategy + +Ensuring the robustness, security, and performance of the "Staff Grant Extension" feature is +paramount. The testing strategy encompasses both backend and frontend components. + +### 8-1 Backend Testing + +The backend testing strategy involves validating the functionality, security, and data integrity of +the "Staff Grant Extension" feature. + +### Test Case 1: Successful Extension Granting + +- **Description:** Verify that a staff member can successfully grant an xtension to a student. +- **Steps:** + 1. Authenticate as a staff member. + 2. Select a student. + 3. Enter a valid extension duration. + 4. Submit the form. +- **Expected Outcome:** The extension is granted, a new extension record is created in the database, + and both staff and student receive notifications. + +### Test Case 2: Invalid Extension Duration + +- **Description:** Test the system's response when a staff member enters an invalid extension + duration. +- **Steps:** + 1. Authenticate as a staff member. + 2. Access the "Grant Extension" functionality. + 3. Select a student. + 4. Enter an invalid extension duration. + 5. Submit the form. +- **Expected Outcome:** The system displays an error message, no extension record is created, and + the form remains accessible for correction. + +### Test Case 3: Unauthorised Access + +- **Description:** Verify that unauthorised users cannot access the "Grant Extension" functionality. +- **Steps:** + 1. Attempt to access the "Grant Extension" functionality without proper authentication. +- **Expected Outcome:** The system denies access and displays an appropriate error message. + +### Test Case 4: Notification Sent to Student + +- **Description:** Check if the student receives a notification when an extension is granted. +- **Steps:** + 1. Authenticate as a staff member. + 2. Grant an extension to a student. + 3. Verify the student's notifications. +- **Expected Outcome:** The student receives a notification indicating the granted extension and its + duration. + +## 8-2 Frontend Testing + +Frontend components will undergo testing to ensure a seamless user experience. + +- **Form Validation Testing:** Validate the form's behaviour when inputs are correct and incorrect, + ensuring error messages display appropriately. +- **Integration Testing:** Test the integration of the "Grant Extension" form into the staff + dashboard, ensuring proper rendering and interaction. +- **Notification Testing:** Verify that notifications are triggered and displayed correctly for + students. +- **Responsive Testing:** Test the form's responsiveness across various devices and screen sizes. + +By executing comprehensive backend and frontend tests, we ensure the "Staff Grant Extension" feature +functions accurately, is secure from unauthorised access, and provides a seamless experience to +staff and students. Successful testing will lead to a reliable and user-friendly addition to the +OnTrack system. + +## 9-Deployment Plan + +The deployment plan outlines the steps to smoothly introduce the "Staff Grant Extension" feature +into the OnTrack system, ensuring minimal disruptions and optimal user experience. + +### 9-1-Pre-Deployment Preparation + +- Conduct thorough testing of both frontend and backend components, addressing any identified + issues. +- Review and ensure that the codebase adheres to coding standards and best practices. +- Create a backup of the existing system and database to mitigate potential risks during deployment. + +### 9-2-Deployment Steps + +- **Database Migration:** Apply necessary database migrations to accommodate the new extension + records. + +- **Backend Deployment:** Deploy the backend changes to the production server. Monitor for any + errors or anomalies during deployment. + +- **Frontend Deployment:** Deploy the updated frontend components to the production server. Ensure + that the new form and notifications are integrated seamlessly. + +### 9-3-Post-Deployment Tasks + +- **Data Migration:** If needed, migrate existing data to match the new database schema. +- **Testing:** Conduct thorough testing in the production environment to ensure everything works as + expected. + +### 9-4-Rollback Plan + +- In case of unforeseen issues during deployment, have a rollback plan in place to revert to the + previous version of the system. + +### 9-5-Communication + +- Notify staff members and users about the upcoming feature addition and any potential downtime + during deployment. +- Communicate the benefits and functionality of the "Staff Grant Extension" feature to encourage + user adoption. + +### 9-6-Monitoring and Support + +- Monitor the system closely during the initial days after deployment to detect any unexpected + behaviors. +- Provide quick response and support to address any user issues or inquiries related to the new + feature. + +### 9-7-Documentation Update + +- Update user documentation, guides, and tutorials to reflect the new "Staff Grant Extension" + feature. +- Include instructions for staff members on how to use the new functionality effectively. + +### 9-8-Continuous Improvement + +- Gather feedback from staff members and users about their experience with the new feature. +- Use this feedback to make necessary improvements and enhancements to the feature in future + updates. + +By following this deployment plan, the "Staff Grant Extension" feature will be seamlessly integrated +into the OnTrack system, offering enhanced capabilities to staff members and students while +maintaining the stability and reliability of the platform. + +## 10-Conclusion + +The design document for the "Staff Grant Extension" feature presents a comprehensive blueprint for +integrating this pivotal enhancement into the OnTrack system. By empowering staff members to grant +extensions to students, the feature addresses the evolving needs of educational environments, +ensuring a tailored and adaptable approach to supporting students' unique circumstances. + +The "Staff Grant Extension" feature enriches the OnTrack system by seamlessly bridging frontend and +backend components. Through a user-friendly form, staff members can initiate extension requests, +specifying durations and reasons, which are then securely stored in the system's database +Notifications are triggered, enhancing communication with students. Robust error handling, +validation mechanisms, and stringent security measures ensure data integrity and user confidence. + +The envisioned architecture fosters collaboration between students and staff members, enabling +personalized solutions without disrupting established workflows. The design emphasizes usability, +scalability, and performance, thereby elevating the user experience across the platform. + +Incorporating the "Staff Grant Extension" feature extends OnTrack's capability to adapt and respond +to students' unique circumstances, fostering a more inclusive and flexible educational experience. +By following the outlined design principles and implementation strategies, the feature promises +seamless integration, streamlined functionality, and enhanced communication within the OnTrack +system. This design document serves as a roadmap to achieving these goals and advancing the +educational support provided by the platform. diff --git a/src/content/docs/Products/OnTrack/Projects/Staff Grant Extension/REQUIREMENTS.md b/src/content/docs/Products/OnTrack/Projects/Staff Grant Extension/REQUIREMENTS.md new file mode 100644 index 00000000..adc5edad --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Staff Grant Extension/REQUIREMENTS.md @@ -0,0 +1,179 @@ +--- +title: Requirements Document:OnTrack - Staff Grant Extension Feature +--- + +## 1-Introduction + +The purpose of this document is to outline the requirements for the implementation of the "Staff +Grant Extension" feature in the OnTrack (also known as Doubtfire). This feature aims to empower +staff members to grant extensions to students, even in cases where there are no formal extension +requests within the system. + +## 2-Use Case + +### 2-1-User Story + +As a staff member, I want to be able to grant extensions to students, even when no formal extension +requests are submitted through the system. This allows me to accommodate special circumstances that +may have been communicated through other means. + +### 2-2-Acceptance Criteria + +- Staff members can initiate extension requests for specific students. +- Staff members can specify the duration of the extension. +- Extension requests initiated by staff members are recorded in the system for future reference. +- Students receive notifications about granted extensions. + +## 3-Functional Requirements + +### 3-1-Frontend Functionality + +#### _3-1-1-Grant Extension Form_ + +- A new option should be added to the staff dashboard or relevant pages for granting extensions. +- The form should include fields for selecting the student, entering the extension duration, and + adding any relevant notes. +- The reason for the extension to be granted. +- The medium the extension was requested (if not formal). +- An interface to search for and select students should be provided. + +#### _3-1-2-Notifications_ + +- Students should receive notifications via email or within the system when a staff member grants an + extension. +- Notifications should include details about the granted extension and its duration. + +### 3-2-Backend Functionality + +#### _3-2-1-Extension Record_ + +- An extension record should be created and associated with the student, the staff member initiating + the extension, and the specified duration. +- Extension records should be viewable by both staff members and students. + +## 4-Technical Requirements + +### 4-1-Technology Stack + +The "Staff Grant Extension" feature should be implemented using the existing technology stack of the +Doubtfire system. + +- Frontend: Angular and Tailwind CSS +- Backend: Ruby on Rails + +### 4-2-Data Management + +- Extension records should be stored in the system's database, associated with the relevant student + and staff member. + +### 4-3-User Authentication and Authorisation + +- Only authorised staff members should have access to the "Grant Extension" functionality. +- Appropriate access controls should be implemented to ensure data security. + +## 5-Non-Functional Requirements + +### 5-1-Usability + +- The user interface for granting extensions should be intuitive and user-friendly, requiring + minimal training for staff members. + +### 5-2-Performance + +- The feature should be responsive and provide a seamless experience for staff members, even during + periods of high system usage. + +## 6-Future Considerations + +- Integration with existing extension request workflows, if applicable. +- Ability to generate reports on granted extensions for administrative purposes. + +## 7-Testing + +### 7-1-Test Cases for Backend Extension Granting Endpoint + +#### _Test Case 1: Successful Extension Granting_ + +Description: Verify that a staff member can successfully grant an extension to a student. + +Steps: + +1. Authenticate as a staff member. +2. Access the "Grant Extension" functionality. +3. Select a student. +4. Enter a valid extension duration. +5. Submit the form. + +Expected Outcome: The extension is granted, and a new extension record is created in the database. +The student receives a notification, and the staff member can view the granted extension details. + +#### _Test Case 2: Invalid Extension Duration_ + +Description: Test the system's response when a staff member enters an invalid extension duration. + +Steps: + +1. Authenticate as a staff member. +2. Access the "Grant Extension" functionality. +3. Select a student. +4. Enter an invalid extension duration (e.g., a negative value or non-numeric input). +5. Submit the form. + +Expected Outcome: The system displays an error message indicating that the entered duration is +invalid. No extension record is created. + +#### _Test Case 3: Unauthorised Access_ + +Description: Verify that unauthorised users cannot access the "Grant Extension" functionality. + +Steps: + +1. Attempt to access the "Grant Extension" functionality without proper authentication as a staff + member. + +Expected Outcome: The system denies access and displays an appropriate error message. + +#### _Test Case 4: Notification Sent to Student_ + +Description: Check if the student receives a notification when an extension is granted. + +Steps: + +1. Authenticate as a staff member. +2. Grant an extension to a student. +3. Verify the student's notifications. + +Expected Outcome: The student receives a notification indicating the granted extension and its +duration. + +### 7-2-Running Tests and Interpreting Results + +#### _7.2.1. Running Tests_ + +1. Ensure the backend development environment is set up and functional. +2. Open a terminal/command prompt. +3. Navigate to the project's backend directory. +4. Run the test suite using a testing framework. + +#### _7.2.2. Interpreting Results_ + +1. If all tests pass, you will see a success message(s). +2. If any test fails, you will see a descriptive error message indicating the test that failed and + the reason for failure. + +#### _7.2.3. Troubleshooting_ + +1. If tests fail, review the error messages and stack traces to identify the issue. +2. Check the backend code related to the failing test to diagnose and fix the problem. +3. Rerun the tests after making changes to verify that the issue has been resolved. + +## 8-Conclusion + +The "Staff Grant Extension" feature enhances the flexibility and responsiveness of the OnTrack +learning management system by allowing staff members to grant extensions to students based on +individual circumstances. This document outlines the functional, technical, and non-functional +requirements for the successful implementation of this feature. Thorough testing of the backend +extension granting endpoint ensures that the "Staff Grant Extension" feature functions as expected. +The test cases cover various scenarios, including successful extension granting, error handling, and +notifications. Running the tests and interpreting the results helps identify and address issues +before deploying the feature to production. diff --git a/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/2022-t3-hand-over-document.md b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/2022-t3-hand-over-document.md new file mode 100644 index 00000000..8aed313d --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/2022-t3-hand-over-document.md @@ -0,0 +1,65 @@ +--- +title: 2022 T3 Hand-Over Document +--- + +[Back to Index](/products/ontrack/projects/task-submission-and-redesign) + +## Purpose of Document + +The purpose of this document is to explain to future collaborators of this project what has been +accomplished. This document is a guide for future collaborators, on what their next course of action +ought to be. + +## State of Project When Received + +- Several key stakeholders had been identified. +- Several features had been derived from the stakeholder personas. +- Two designs had been handed to us. +- A so-called "back-end emulator" and "front-end simulator" was handed to us, which was supposed to + be an educationally assistive technology. + +## State of Project at Hand-Over + +- The so-called "back-end emulator" and "front-end simulator" were redefined as an API, the + "`chathistorydisplayer-api`" application, and a web interface geared towards testing the API, the + "`chathistorydisplayer-web`" application. + - The `chathistorydisplayer-api` application is located in the directory called `emulator` in the + [thoth-tech/ChatHistoryDisplayer](https://github.com/thoth-tech/ChatHistoryDisplayer) + repository. + - The `chathistorydisplayer-web` application is located in the directory called + `frontEndSimulator` in the + [thoth-tech/ChatHistoryDisplayer](https://github.com/thoth-tech/ChatHistoryDisplayer) + repository. +- The `chathistorydisplayer-api` application had its containerisation refactored. +- The `chathistorydisplayer-web` application was containerised. +- `Docker Compose` was integrated and configured to handle spinning up both the + `chathistorydisplayer-api` and `chathistorydisplayer-web` applications. +- Quality of life features were integrated into the `chathistorydisplayer-api` application. Namely, + a static code analyser and linter (`rubocop`) and a testing suite (`RSpec` and `Capybara`). +- 83 offenses in the `chathistorydisplayer-api`, as detected by the newly integrated static code + analyser, were fixed manually. +- The `chathistorydisplayer-api` application was altered to facilitate the creation of user + directories, project directories, and write files from JSON payloads. In comparison, it formerly + only created user directories and initialised those are git repositories. The back-end team deemed + it appropriate to change this, so that each project is handled as a git repository; this will + allow each project to have its history queries for integration into a chat interface. +- An API end-point was created in the `chathistorydisplayer-api` application to fetch the most + recent `git diff` of a file. +- API end-points were created in the `chathistorydisplayer-api` application to handle the deletion + of user directories, project directories, and files in project directories. +- A diagram, which acts as a proposition, was created on how the [thoth-tech/ChatHistoryDisplayer] + may be integrated into + [thoth-tech/doubtfire-api](https://github.com/thoth-tech/doubtfire-api). +- The `chathistorydisplayer-web` application had a React component library integrated and it was + then leveraged. This resulted in a visual overhaul of the web application. +- The `chathistorydisplayer-web` application had visual buttons created for the deletion of user + directories, project directories, and files in project directories. +- The `chathistorydisplayer-web` application had `Javascript` events integrated into the text input + fields, so that it would be clearer what variables were set to during testing. +- The `chathistorydisplayer-web` application had `Javascript` events integrated into the buttons, so + that appropriate API end-points were called. + +## What Next? + +- Read + [Project On-boarding](/products/ontrack/projects/task-submission-and-redesign/project-on-boarding) diff --git a/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/2023-t1-hand-over-document.md b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/2023-t1-hand-over-document.md new file mode 100644 index 00000000..9621c8ec --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/2023-t1-hand-over-document.md @@ -0,0 +1,165 @@ +--- +title: 2023 T1 Hand-Over Document +--- + +[Back to Index](/products/ontrack/projects/task-submission-and-redesign) + +## Purpose of Document + +This document aims to inform potential collaborators about the project progress and accomplishments. +It guides collaborators by outlining the next steps and actions they should take. The document +ensures project continuity and coherence by detailing previous work. It helps newcollaborators +understand the project status and build on it. This document also helps future collaborators make +strategic and informed decisions. It helps themidentify gaps, challenges, and opportunities and +suggests next steps. It streamlines projectefforts, and empowers future collaborators to effectively +contribute to project success byleveraging past successes and experiences. + +## Project Overview, Goals, and Objectives + +The Task Submission and Redesign Project, which is a component of the Ontrack Project, has clear +goals and objectives aimed at enhancing the functionality and efficiency of the existing product. +The primary objective of the project is to modify the current system in a way that allows each +submitted artifact to be easily displayed and interpreted by users. + +The project also helps markers inspect these artefacts, who evaluate and provide feedback. The +project aims to speed up marking by helping markers quickly evaluate artefacts, and hence improve +evaluation efficiency. The Task Submission and Redesign Project aims to streamline marking and add a +chatbot. The chatbot will mediate marker-student activities. The chatbot may help, answer questions, +guide, and facilitate communication. + +Overall, the Task Submission and Redesign Project optimizes artefact submission and evaluation. The +project aims to improve user experience, efficiency, and collaboration between markers and students +in the Ontrack Project by introducing different submitted artefact display, efficient marking +procedures, and a chatbot. + +## Project Deliverables + +This sections outlines project deliverables for 2023 T1. For overall project deliverables, please +check the markdown docment in +[thoth-tech/documentation](https://github.com/thoth-tech/documentation/blob/main/docs/OnTrack/Task%20Submission%20%26%20Redesign/Deliverables.md). + +### Short-term (2023 T1) + +### Documentation Oriented + +- [x] Update the project epic (make it relevant to T1/2023). + - A modification to a markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +- [x] Update the document that outlines the deliverable items of the project. + - A markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/blob/main/docs/OnTrack/Task%20Submission%20%26%20Redesign/Deliverables.md). + +- [x] Create a T1/2023 hand-over document. + - A markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +- [x] Update the project Index (make it relevant to T1/2023). + - A modification to a markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +- [x] Update the project Onboarding (make it relevant to T1/2023). + - A modification to a markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +- [x] Update the project Scope Sign Off Document (to reflect scope changes relevant to T1/2023). + - A modification to a markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +### Front-end Oriented + +#### Design + +- [x] Create frame-by-frame flows of tutors using the primary design. + - Multiple images and a video showcase, as output from [Figma] ,in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign/design_images), + + - Additional information: These flows should determine whether an alteration to the single, + primary design is required and what specific alteration is required. This could be broken down + into tasks regarding specific flows for showing the use of specific features. + +- [x] Create `TaskSubmissionEnhancement` new Features to the student-view design. + - Multiple images and a video showcase in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign/design_images), + as output from [Figma](https://www.figma.com/). + + - A markdown document that explains the functions and implementation of the new features in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +#### Code + +- [x] Create `Submission enhancement test environment` for the new features on Student View. + - A source code of the test environment, demonstration video to showcase the new features and how + it could present in Ontrack with additional documentation in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +### Cyber-security Oriented + +- [x] Create a document that outlines the cybersecurity concerns of the current changes. + - A markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +- [x] Create a document that introduce administrators to potential cyber security threats or issues. + - A markdown document (or multiple) in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +- [x] Create a code script of malware-detection software to implement for the new feature. + - A markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +## State of Project When Received + +- Several key stakeholders had been identified and several user stories and features had been + derived from the stakeholder personas. +- Two designs (Student and Tutor) had been found in Figma. +- The "`chathistorydisplayer-api`" and "`chathistorydisplayer-web`" applications were redefined as + an API and a web interface geared towards testing the API. +- The "`chathistorydisplayer-api`" application had its containerisation refactored, the + "`chathistorydisplayer-web`" application was containerised, Docker Compose was integrated, quality + of life features were integrated, and 83 offenses were fixed manually. +- The "`chathistorydisplayer-api`" application was altered to facilitate the creation of user + directories, project directories, and write files from JSON payloads. An API end-point was created + to fetch the most recent git diff of a file, and API end-points were created to handle the + deletion of user directories, project directories, and files in project directories. +- The `chathistorydisplayer-api` application was located in the directory called `emulator` in the + [thoth-tech/ChatHistoryDisplayer] repository. +- The `chathistorydisplayer-web` application is located in the directory called `frontEndSimulator` + in the [thoth-tech/ChatHistoryDisplayer](https://github.com/thoth-tech/ChatHistoryDisplayer) + repository. +- More information can be found in the 2022 T3 Handover Document: A markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +## State of Project at Hand-Over + +- Frame-by-frame flows of tutors performing current and new proposed features using the primary + design have been created. +- The design enhancements, specifically the `TaskSubmissionEnhancement`, have been incorporated into + the student-view design. +- A test environment for `TaskSubmissionEnhancement` has been created for the new features on the + Student View. The source code, a demonstration video showcasing the new features, and additional + documentation are provided. +- A document outlining the cyber-security concerns related to propositional changes has been + created. +- Documents introducing potential cyber-security threats or issues to OnTrack administrators have + been prepared. +- A code script for malware-detection software implementation for the new feature has been provided. +- These completed deliverables demonstrate progress in different aspects of the project, including + documentation updates, front-end design enhancements, code implementation, and consideration of + cyber-security concerns. The project is now ready for handover, with comprehensive documentation + and tangible outcomes that can serve as a foundation for future development and collaboration. + +## What Next? + +- Finalise Figma design for component student-views with client and UI enhancement team. +- Iterate on component source code and add ROR implementation if necessary. +- Implement submission enhancement features for production. +- Expand scope features such as automated task stage changing; for exxample if task is in Task not + yet started stage, upload of a file will automatically change it to Working on it. +- Based on the student-views new components progress, work on integrating the new features into + tutor-views after finalizing the Figma prototype for tutor-views with client to UI enhancement + team. +- Read 2023 T1 Project Weekly updates, Meeting Minutes and other documents in the project TEAMS + channel. + +- Read + [Project On-boarding](/products/ontrack/projects/task-submission-and-redesign/project-on-boarding) diff --git a/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/deliverables.md b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/deliverables.md new file mode 100644 index 00000000..a3e3546e --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/deliverables.md @@ -0,0 +1,193 @@ +--- +title: Deliverable Items +--- + +## Purpose of this Document + +This document outlines the deliverable items the Task View and Submission Redesign project intends +to deliver upon. Each trimester, this document is to be reassessed. All team members are expected to +express their expertise by breaking down deliverable items into smaller, actionable tasks on a +collaborative technology such as Trello. + +## Structure of the Deliverable Items Document + +All deliverable items are grouped into roles, but team members are allowed (and encouraged) to +operate outside of their selected roles. + +All deliverable items have the common form: + +- [ ] What needs to be done. + - What evidence needs to be produced to show this is completed or on-going. + - (OPTIONAL) Pre-requisites: The pre-requisite deliverable items for this deliverable. + - (OPTIONAL) Additional information: Any additional information that may inform a reader about the + deliverable. + +These deliverable items should then be decomposed into constituting tasks, mediated by some +collaborative technology (for example, [Trello](https://trello.com/)). + +All team members should participate in the decomposition of deliverable items. Team members are also +encouraged to contribute ideas for deliverable items, as informed by their CLOs. + +## Deliverable Items + +### Purely Documentation Oriented + +- [x] Modify the project epic (make it relevant to T1/2023). + - A modification to a markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + +- [x] Modify/Update a document that outlines the deliverable items of the project. + - A markdown document in [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + +- [x] Create a T1/2023 hand-over document. + - A markdown document in [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + +### Front-end Oriented + +#### Design + +- [ ] Create frame-by-frame flows of tutors performing current and new features. + - Multiple images and a video showcase, as output from [Figma](https://www.figma.com/), in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/), as output from + [Figma](https://www.figma.com/). + + - Pre-requisite: A single, primary design must be selected for this to be followed through with. + +- [ ] Create frame-by-frame flows of students performing current and new features. + - Multiple images, as output from [Figma](https://www.figma.com/), in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + + - Pre-requisite: A single, primary design must be selected for this to be followed through with. + + - Additional information: These flows should determine whether an alteration to the single, + primary design is required and what specific alteration is required. This could be broken down + into tasks regarding specific flows for showing the use of specific features. + +- [ ] Complete the tutor-view design on [Figma](https://www.figma.com/). + - An image, as output from [Figma](https://www.figma.com/), in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + + - Pre-requisite: The creation of all the flows of the single, primary tutor-view design. + + - Additional information: This deliverable item is completed once all changes, as informed by + usability and smart default problems obtained from the construction of the flows, are fixed. + +- [x] Complete the student-view design on [Figma](https://www.figma.com/). + - An image, as output from [Figma](https://www.figma.com/), in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/) + + - Pre-requisite: The creation of all the flows of the single, primary student-view design. + + - Additional information: This deliverable item is completed once all changes, as informed by + usability and smart default problems obtained from the construction of the flows, are fixed. + +- [ ] Create new `TaskSubmissionEnhancement` Features to the student-view + [Figma](https://www.figma.com/) design. + - An image and video showcase, as output from [Figma](https://www.figma.com/), in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + +- [ ] Create an administrator-view [Figma](https://www.figma.com/) design. + - An image, as output from [Figma](https://www.figma.com/), in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + +- [ ] Create a convenor-view [Figma](https://www.figma.com/) design. + - An image, as output from [Figma](https://www.figma.com/), in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + +- [ ] Create frame-by-frame flows of administrators performing current and new features. + - Multiple images, as output from [Figma](https://www.figma.com/), in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + - Pre-requisite: The administrator-view deliverable item from this deliverable document must be + completed. + + - Additional information: This could be broken down into tasks regarding specific flows for + showing the use of specific features. + +- [ ] Create frame-by-frame flows of convenors performing current and new features. + - Multiple images, as output from [Figma](https://www.figma.com/), in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + + - Pre-requisite: The conventor-view deliverable item from this deliverable document must be + completed. + + - Additional information: This could be broken down into tasks regarding specific flows for + showing the use of specific features. + +#### Code + +- [ ] Modify the existing front-end implementation of OnTrack to conform with any of the completed + designs. + +- [x] Expand the `chathistorydisplayer-web` web application. + +### Back-end Oriented + +#### Documentation + +- [x] Create design propositions on how the `ChatHistoryDisplayer` integrates with the OnTrack + platform. + - An image file in [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + +#### `ChatHistoryDisplayer` + +- [x] Refactor the implementation of Docker at `chathistorydisplayer-api`. + +- [x] Implement Docker at `chathistorydisplayer-web`. + +- [x] Integrate Docker Compose at the root of the [thoth-tech/ChatHistoryDisplayer] repository. + +- [x] Add functionality to `chathistorydisplayer-api`: create user directories. + +- [x] Add functionality to `chathistorydisplayer-api`: create project directories in user + directories. + - Additional information: Project directories must be initialised as git repositories. + +- [x] Add functionality to `chathistorydisplayer-api`: write file from JSON payload. + - Additional information: Pertains to text files. + +- [x] Add functionality to `chathistorydisplayer-api`: API end-point that retrieves the last + `git diff` of a text file. + +- [ ] Add functionality to `chathistorydisplayer-api`: authorisation at API end-points. + +- [ ] Add functionality to `chathistorydisplayer-api`: version control of PDF documents using the + `git gem`. + +#### `TaskSubmissionEnhancement` + +- [ ] Create a prototype of `TaskSubmissionEnhancement` Component of the Ontrack platform that adds + the following four features that would benefit both students and teaching staff: + - The ability to submit files regardless of the task state. + - The ability to submit individual task files. + - The ability to submit optional additional files outside of the task requirements. + - The ability to observe task file upload differences. + +#### `Doubtfire` + +- [ ] Modify OnTrack to serve raw files, where appropriate. + - Additional information: This contributes towards the integration of the + `chathistorydisplayer-api` into the OnTrack platform, as the OnTrack platform needs PDF + processing removed and separate handling for different classes of files (text files and PDFs + come to mind). + +- [ ] The integration of `chathistorydisplayer-api` into the Docker environment of the OnTrack + platform. + +- [ ] Integrate `TaskSubmissionEnhancement` into the OnTrack platform. + +### Cyber-security Oriented + +- [ ] Create a document that outlines the cyber-security protocols for project group members. + - A markdown document in [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + +- [ ] Create a document, or documents, that introduce OnTrack administrators to potential + cyber-security threats or issues. + - A markdown document (or multiple) in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + +- [ ] Create a document outlining the security concerns of propositional changes (or current enacted + changes). + - A markdown document in [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). + +- [ ] Create a document that surveys group member compliance with security protocols. + - A markdown document in [thoth-tech/documentation](https://github.com/thoth-tech/documentation/). diff --git a/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/epic.md b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/epic.md new file mode 100644 index 00000000..b83244ed --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/epic.md @@ -0,0 +1,149 @@ +--- +title: Author Information +--- + +[Back to index](/products/ontrack/projects/task-submission-and-redesign) + +- Authors: [Yaser Deeb](https://github.com/YADEEB21) +- Team: OnTrack - Task View and Submission Redesign +- Team Delivery Lead: Yaser Deeb + +## Document Summary + +--- + +- Documentation Title: Epic Document +- Documentation Type: Technical +- Documentation Information Summary: Critical links and resources; the background, context, and + business value of the project; and the acceptance criteria. + +## Document Review Information + +--- + +- Date of modified Document Submission to GitHub: 15/05/2023 +- Documentation Version: 3.0 +- Date of Previous Documentation Review: 22/09/2022 +- Date of Next Documentation Review: T2/2023 + +## Key Terms + +--- + +Trello: A web-based list-making application designed with a focus on teams that implement a scrum +style of organisation. + +Figma: A web-based application for user interface and user experience design. + +UI: User Interface; the means by which a human interacts with a machine, these are typically +graphical interfaces that accept input from an end-user. + +UX: User Experience; all aspects of the end-user's interactions with an application or device. + +Flow: A frame-by-frame image of a user (a student, tutor, convenor, or administrator) performing a +necessary function from beginning to end. Flows allow designers to think critically about how the +usability of a design. It may save the project from investing time and resources into unusable +dead-ends. + +## Key Links/Resources + +--- + +- [T1/2023 Trello Board](https://trello.com/b/FWyBUYG8/task-view-re-design-team-ontrack-project) +- [OnTrack Overseer Repository](https://github.com/thoth-tech/doubtfire-overseer) +- [OnTrack Web Repository](https://github.com/thoth-tech/doubtfire-web) +- [OnTrack API Repository](https://github.com/thoth-tech/doubtfire-api) +- [thoth-tech/ChatHistoryDisplayer](https://github.com/thoth-tech/ChatHistoryDisplayer) +- [T3/2022 Delivery Lead's ChatHistoryDisplayer](https://github.com/rickydodd/ChatHistoryDisplayer) +- [T1/2023 Figma](https://www.figma.com/files/project/61538483/Team-project?fuid=1226098815565608315) + +## Contacts for further information + +--- + +see [Thoth Tech Handbook](https://github.com/thoth-tech/handbook/blob/main/README.md) + +## Related Documents + +--- + +- [Task Submission redesign requirements and specifications document](/products/ontrack/projects/task-submission-and-redesign/requirements) + +## View Task and Submission Epic Document + +## Background / Context + +OnTrack is employed by multiple institutions as a learning management system. The View Task and +Submission project intends to create user-centric modifications to existing features, addition of +new features to the task submission and view in the OnTrack platform. + +## Business Value + +By further modernising OnTrack, institutions can deploy the OnTrack platform to satisfy the needs of +their students, markers, assessors, and auditors. The platform can support all stakeholders to +fulfil their obligations and, in the case of the student, support the learning of essential +concepts. By streamlining the experience of markers, then associated costs may decrease. +Additionally, the feedback loop for students (the learning feedback loop) may shorten. + +## In Scope + +- Design planning and documentation +- Removal of redundant features +- Modification of existing features +- Addition of new features +- Task view for students +- Task submission for students +- Task view for markers +- Front-end +- Back-end +- Security +- Database + +## Out of Scope + +- Visual flavour +- Logo + +## UI/UX Considerations + +- Navigability + - Can all features be navigated to? + - New features? + - Previous features that were retained? + - Navigability can be gauged by the creation of multiple flows. +- Accessibility + +## Regulation & Compliance Considerations + +- Storage and privacy of user's data. +- Security +- Retention policy. + +## Operations / Support / Training Considerations + +Team members may require training/up-skilling in applications, technologies, and languages, such as: + +- [git](https://git-scm.com/) +- [GitHub](https://github.com/), +- [Figma](https://figma.com/), +- [Docker](https://www.docker.com/), +- [Ruby](https://www.ruby-lang.org/en/), +- [Ruby on Rails](https://rubyonrails.org/), +- [Python](https://www.python.org/), +- [TypeScript](https://www.typescriptlang.org/), +- [Bootstrap](https://getbootstrap.com/), +- [Angular](https://angular.io/), +- [Sinatra](https://sinatrarb.com/), +- [React](https://reactjs.org/), +- [MUI](https://mui.com/). + +Team members must express testing skills by use of various testing tools to ensure functionalitie +work as intended. They also must be able to fix and/or document and report on issues or bugs as they +arise. + +## Acceptance Criteria + +- Managing director must approve of the design before implementation. +- If a change is required, then an alteration to the design (with approval from the managine + director) must be completed first. +- All code must be tested before an attempt to pull into the upstream repositories. diff --git a/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/index.md b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/index.md new file mode 100644 index 00000000..692b26df --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/index.md @@ -0,0 +1,32 @@ +--- +title: View Task and Submission Redesign Documentation Index +--- + +## [T1, 2023 Hand-over Document](/products/ontrack/projects/task-submission-and-redesign/2023-t1-hand-over-document) + +A document created to reflect what has been so far accomplished in the project. + +## [T1, 2023 Project Scope Sign Off Document](/products/ontrack/projects/task-submission-and-redesign/project-scope-signoff-document) + +A document created to reflect the scope of the project and its deliverables for T1 / 2023. + +## [T2, 2022 Hand-over Document](/products/ontrack/projects/task-submission-and-redesign/2022-t3-hand-over-document) + +A document created to be the first document read on the project. + +## [Project On-boarding](/products/ontrack/projects/task-submission-and-redesign/project-on-boarding) + +A document created to assist with the on-boarding process of new contributors to the Task View and +Submission Redesign project. + +## [View Task and Submission Redesign Epic](/products/ontrack/projects/task-submission-and-redesign/epic) + +The epic for the View Task and Submission Redesign project. + +## [User Stories and Features](/products/ontrack/projects/task-submission-and-redesign/user-stories-and-features) + +The user stories and the features generated by said user stories. + +## [Requirements](/products/ontrack/projects/task-submission-and-redesign/requirements) + +The requirements for the Task View and Submission Redesign project. diff --git a/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/project-on-boarding.md b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/project-on-boarding.md new file mode 100644 index 00000000..8639a608 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/project-on-boarding.md @@ -0,0 +1,137 @@ +--- +title: Project On-boarding +--- + +[Back to Index](/products/ontrack/projects/task-submission-and-redesign) + +## Purpose of Document + +The purpose of this document is to position you, the potential contributor, such that you can +contribute to the project. Regardless of your selected role, it is paramount that you join and +configure all facets of the project. You are encouraged to work outside of your role. + +## Notice + +All team members are expected to have all facets of the project set up, irrespective of your +selected or designated roles. This increases the team agility. + +## Trello + +- Register a [Trello](https://trello.com/signup) account. +- Confirm your Trello account by email (may go to Trash, so be sure to check there). +- Join the Trello board that is assigned by your delivery Lead. The previous team's + [Trello board](https://trello.com/b/FWyBUYG8/task-view-re-design-team-ontrack-project) + +## Figma + +- Register a [Figma](https://www.figma.com/) account. +- Confirm your Figma account by email (may go to Trash, so be sure to check there). +- Join the + [Figma project](https://www.figma.com/files/project/61538483/Team-project?fuid=1226098815565608315). + +## Configuring git (global) + +If you haven't already, you must configure git. + +1. Set your git username by `git config --global user.name "FIRST_NAME LAST_NAME"`, + where`FIRST_NAME` is your first name and `LAST_NAME` is your last name. +1. Set your git email by `git config --global user.email "YOUR_EMAIL"`, where `YOUR_EMAIL` is your + email. It is advised that you use your `@users.noreply.github.com` email address, which is, by + default, `@users.noreply.github.com`, where `` is your GitHub username. + +## Cloning the Documentation + +This enables you to contribute to the project documentation. You should also read the +[documentation contribution guidelines](https://github.com/thoth-tech/documentation/blob/main/CONTRIBUTING.md). + +```shell +git clone -b doc/view-task-and-submission-redesign --single-branch https://github.com/thoth-tech/documentation.git +``` + +## WSL2 + +If you are on a Windows machine, then we recommend that you install WSL2. + +## Get OnTrack Running on Local Machine + +You need a terminal that supports shell scripts (on Windows, you need WSL2, Msys2, or Cygwin). + +1. Fork [doubtfire-deploy](https://github.com/doubtfire-lms/doubtfire-deploy), + [doubtfire-api](https://github.com/doubtfire-lms/doubtfire-api), and + [doubtfire-web](https://github.com/doubtfire-lms/doubtfire-web) + +2. Clone your [doubtfire-deploy](https://github.com/doubtfire-lms/doubtfire-deploy). Make sure to + fetch submodules to get the sub-projects. + + ```shell + git clone --recurse-submodules https://github.com/YOUR_USERNAME/doubtfire-deploy + ``` + +3. `cd` into the directory. + + ```shell + cd doubtfire-deploy + ``` + +4. Open a terminal that supports `sh` scripts (on Windows, you require WSL2, Msys2, or Cygwin). Run + the following command to set your fork as the remote. + + ```shell + ./change_remotes.sh + ``` + +5. Your delivery lead provides you with the GitHub username to use in this command. This allows you + to use `git fetch task-view-submission`, `git pull task-view-submission`, and + `git push task-view-submission`. + + ```shell + git remote add task-view-submission https://github.com/PROVIDED_USERNAME/doubtfire-deploy + ``` + +6. You can now follow the remaining instructions, from instruction four, in the `doubtfire-deploy` + [contributing file](https://github.com/doubtfire-lms/doubtfire-deploy/blob/development/CONTRIBUTING.md#working-with-docker-compose). + +## What Next? + +- Become familiar with + [the project epic](/products/ontrack/projects/task-submission-and-redesign/epic) +- Become familiar with + [the user stories and features](/products/ontrack/projects/task-submission-and-redesign/user-stories-and-features) + - Are there any users that are not served in the user stories or by the features? +- Become familiar with + [the requirements](/products/ontrack/projects/task-submission-and-redesign/requirements) + - Are all stakeholders sufficiently provided for, with this set of requirements? +- Become familiar with + [the deliverables](/products/ontrack/projects/task-submission-and-redesign/deliverables) + - Are there deliverable items that should be added? + - Are there deliverable items that should be removed? + - Are there deliverable items that can be decomposed into smaller deliverable items? +- Examine the first proposed design below and ensure all requirements are met, and that the + inclusion of the features are user-friendly. + + ![the first proposed design](/iteration-3-design-1.png) + +- Examine the second proposed design and ensure all requirements are met, and that the inclusion of + the features are user-friendly. + + ![the second proposed design](/iteration-3-design-2.png) + - Examine + [the second design's prototype](https://www.figma.com/proto/XmKxWQ43MwrD6Red1DvYq6/Wire-Frame-Designs?node-id=478%3A4466&scaling=min-zoom&page-id=476%3A4327&starting-point-node-id=478%3A4466). + +- Select a front-end design to modify, improve, extend, or implement. +- Examine the back-end emulator. + - Has it successfully passed proof-of-concept? + - How can git be implemented on the back-end of the OnTrack product? +- Work on implementing the front-end and back-end. +- If somebody on your team is well-versed in cyber-security, then an examination of the security of + the implementation is required. +- If somebody on the team is well-versed in databases and database administration, then a model of + the database is required. + +## Helpful Points + +- If you are using Windows as your primary operating system and you have not downloaded, installed, + and/or set-up MinGW, then a former team found the Linux subsystem + [WSL 2](https://docs.microsoft.com/en-us/windows/wsl/install) and + [Docker Desktop WSL 2 backend](https://docs.docker.com/desktop/windows/wsl/) as a helpful + development environment. diff --git a/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/project-scope-signoff-document.md b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/project-scope-signoff-document.md new file mode 100644 index 00000000..b01ba21d --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/project-scope-signoff-document.md @@ -0,0 +1,99 @@ +--- +title: Project Scope SignOff Document +--- + +## Project Information + +- Project Name: Task View Re-design +- Project Client: Julien, Andrew, Jake +- Delivery Lead: Yaser Deeb +- Team Members: Yaser Deeb, William Lowe, Sivasamyuktha A Selvarajuh + +## Purpose of Document + +The purpose of this document is to give an overiew of the scope of the project at the kick-off and +verify with the client the project scope for T1 2023. It includes client-approved deliverables, and +acceptance criteria. + +## State of Project When Received + +- Several key stakeholders had been identified. +- Several features had been derived from the stakeholder personas. +- Two designs and one design Prototype had been handed. +- Enhanced ChatHistoryDisplayer: Implemented MUI, Docker Integration. The ChatHistoryDisplayer + consists of two parts: the server, which is being developed as an API, and the front-end, which + tests the API. The server is situated in the emulator directory, while the front-end is situated + in the frontEndSimulator directory. The mission of the API is to be integrated into the OnTrack + platform. + +## Deliverables Verification for T1 2023 + +The following items will be completed to verify that the project scope has been met: + +### Purely Documentation Oriented + +- [x] Modify the project epic and other related documents (make it relevant to T1/2023). + - A modification to a markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +- [x] Update the document that outlines the deliverable items of the project. + - A markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +- [x] Create a T1/2023 hand-over document. + - A markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +### Front-end Oriented + +#### Design + +- [x] Create frame-by-frame flows of tutors using the primary design. + - Multiple images and a video showcase, as output from [Figma](https://www.figma.com/), in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign/design_images), + + - Additional information: These flows should determine whether an alteration to the single, + primary design is required and what specific alteration is required. This could be broken down + into tasks regarding specific flows for showing the use of specific features. + +- [x] Create `TaskSubmissionEnhancement` new Features to the student-view design. + - Multiple images and a video showcase in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign/design_images), + as output from [Figma](https://www.figma.com/). + + - A markdown document that explains the functions and implementation of the new features in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +### Back-end Oriented + +#### `TaskSubmissionEnhancement` + +- [x] Create a prototype of `TaskSubmissionEnhancement` Component of the Ontrack platform that adds: + - The ability to submit files regardless of the task state. + - The ability to submit individual task files. + - The ability to submit optional additional files outside of the task requirements. + - The ability to observe task file upload differences. + +- [x] Create `Submission enhancement test environment` for the new features on Student View. + +### Cyber-security Oriented + +- [x] Create a document that outlines the cybersecurity concerns of the current changes. + - A markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +- [x] Create a document that introduce administrators to potential cyber security threats or issues. + - A markdown document (or multiple) in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +- [x] Create a code script of malware-detection software to implement for the new feature. + - A markdown document in + [thoth-tech/documentation](https://github.com/thoth-tech/documentation/tree/main/docs/OnTrack/Task%20Submission%20%26%20Redesign). + +## Sign Off + +- Client: Andrew Cain + +- Team Lead: Yaser Deeb + +- Code Guru Team: William Lowe, Sivasamyuktha A Selvarajuh πŸ”₯ diff --git a/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/requirements.md b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/requirements.md new file mode 100644 index 00000000..06673546 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/requirements.md @@ -0,0 +1,78 @@ +--- +title: Requirements +--- + +[Back to index](/products/ontrack/projects/task-submission-and-redesign) + +- [Feature requirements](#feature-requirements) +- [Resources](#resources) + +## Feature Requirements + +Features: + +- [Chat bot](#chat-bot) +- [Require tutor interaction](#require-tutor-interaction) +- [Time-based log](#time-based-log) +- [Stages for tasks](#stages-for-tasks) +- [Commit system for uploads and comments](#commit-system) +- [Selective file replacer](#file-replacer) +- [Diff viewer](#diff-viewer) +- [Testing environment](#testing-environment) + +### Chat bot + +A chat bot that takes on existing features and mediates new features: + +### Require tutor interaction + +When a new upload event occurs, the tutor is required to send a substantive message to their +student. This can be communicated to the tutor via the [chat bot](#chat-bot). + +### Time-based log + +Displaying student/tutor and teacher events in a time-based log with the ability to scroll back and +view previous events. This uses a git-based ruby backend to store submission files. There is a +repository created for each individual submission task. + +### Stages for tasks + +The implementation of stages as extra resources for students who require more resources and +confidence. This enables students to tackle the task in different ways to help support their +learning. + +### Commit system + +The implementation of a commit system for tasks, enabling a set of mandatory core files to be +uploaded in the form of a commit. + +### File replacer + +The ability for students, tutors/teachers to view submitted files in their browser as well as write +and view submitted comments regarding those files. The file replacer is supported by the uplifted +file management system. + +### Diff viewer + +The ability for tutors to be able to compare code files submitted by students via a difference +viewer. + +### Testing environment + +An emulation of the back-end is required as a proof-of-concept. The emulation also serves as an +education piece for future collaborators. + +## Resources + +### Front-end development resources + +- [Google Font Icons](https://fonts.google.com/icons) +- [Figma Material Symbols](https://www.figma.com/community/plugin/1088610476491668236/Material-Symbols) +- [Figma Angular Materials](https://www.figma.com/community/file/967106164617088179) + +### Back-end development resources + +- [How to serve and manipulate git repositories from rails](https://stackoverflow.com/questions/67791598/how-to-serve-manipulate-git-repo-from-rails) +- [Rugged, a library for accessing libgit2 in Ruby](https://github.com/libgit2/rugged) +- [Ruby git](https://github.com/ruby-git/ruby-git) +- [Building a HTTP server in Ruby](https://blog.appsignal.com/2016/11/23/ruby-magic-building-a-30-line-http-server-in-ruby.html) diff --git a/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/submission-enhancement-overview-doc.md b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/submission-enhancement-overview-doc.md new file mode 100644 index 00000000..50477dee --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/submission-enhancement-overview-doc.md @@ -0,0 +1,104 @@ +--- +title: Submission Enhancement Overview Document +--- + +## Component Overview + +During Week 5 of the trimester, the team was able to secure a meeting with the client Andrew Cain +who suggested a pivoted focus towards enhancement for the Task Submission Component of the Ontrack +platform. The client outlined four features that he believes would benefit both students and +teaching staff. The features include: + +- The ability to submit files regardless of the task state. +- The ability to submit individual task files. +- The ability to submit optional additional files outside of the task requirements. +- The ability to observe task file upload differences. + +## Feature: The ability to submit files, regardless of the task state + +### Feature 1 Current Implementation + +Currently, the Ontrack platform only allows students to submit their files when the task state is +changed to β€˜Ready for Feedback’. + +### Feature 1 Proposal + +Presented as a new button within the task card, the enhancement would allow for students to submit +their task files regardless of the task state (β€˜Not Started’, β€˜Working On It’, β€˜Need Help’ and +β€˜Ready for Feedback’). Future iterations of this feature could include automated task state changing +depending on conditional statements. E.g. Task remain as β€˜Not Started’ until a file is uploaded +where it is then changed to β€˜Working on It’ and then automatically changed to ’Ready for Feedback’ +when all files are uploaded. + +### Feature 1 Value + +In conjunction with the ability to submit individual task files, teaching staff will be able to +observe the progression of a student through the task. The ability to submit files during any stage +would allow for students to request help from the teaching staff for already submitted files so +discussion can be more targeted to the submissions in question. + +## Feature: The ability to submit individual task files + +### Feature 2 Current Implementation + +Currently, the Ontrack platform requires students to submit all the required task files, and in a +specific order, when completing the tasks. + +### Feature 2 Proposal + +Implemented alongside the ability to submit task files, regardless of the task state, the +enhancement will be present as a new upload dialog in which files can be upload in any order and +won’t require all files to be uploaded at once. Future iterations of this feature could include +individual task states (β€˜Working On It’, β€˜Need Help’, and β€˜Completed’) for each uploaded task. + +### Feature 2 Value + +The ability to submit individual files will benefit students by allowing them to submit portions of +their task. For tasks that require multiple files to be submitted for completion, this means that +students can submit their files a number of times as a form of version control, minimising the +potential for file loss if technical difficulties occur. + +## Feature: The ability to submit optional additional outside of the task requirements + +### Feature 3 Current Implementation + +Currently, the Ontrack platform does not allow for the upload of additional files outside of the +comment section for attachments. Students are only able to submit the required task files. + +### Feature 3 Proposal + +Implemented within the ability to submit individual files and in conjunction with the added freedom +to upload tasks in any order, the feature will present as a new submission item alongside the +required files, allowing students to submit files that are outside of the task’s requirements. + +### Feature 3 Value + +The feature will add value to both students and teaching staff as the students will be able to +submit files that they believe to be complementary to the task (e.g. Learning summaries, output +files, etc). Teaching staff will also be able to request additional files (expanded explanations, +output files, additional tasks) from the students during feedback, without having the need to use +the comment section’s attachments. + +## Feature: The ability to observe task file upload differences + +### Feature 4 Current Implementation + +Currently, the Ontrack platform does not support upload file diff-viewing. + +### Feature 4 Proposal + +The feature will be presented as a new tab or button or button to open a new display where task +submission files can be viewed as a side-by-side view with differences highlighted, akin to GitHub +pull-requests. + +### Feature 4 Value + +Primarily of value to the teaching staff, tasks that may have been marked as β€˜Fix/Resubmit’ will be +able to be compared to their resubmitted task file. This will allow for easier identification of the +changes made, ensuring that appropriate fixes have been made by the student without the need to +review the entire upload. + +## Additional Notes + +No design choices have been finalised and should be iterated upon with input from the client and the +UI Enhancement team. diff --git a/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/user-stories-and-features.md b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/user-stories-and-features.md new file mode 100644 index 00000000..fa65adf5 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Task Submission and Redesign/user-stories-and-features.md @@ -0,0 +1,71 @@ +--- +title: User Stories and Features +--- + +[Back to index](/products/ontrack/projects/task-submission-and-redesign) + +The personas, user stories, and features (as derived from the user stories) for the Task View and +Submission Redesign project. + +## Identified Personas + +- Students +- Tutors +- Convenors +- Developers + +## User Stories + +In the form, "As a \[persona\], I \[want to\], \[so that\]." + +### Students + +1. As a \[student\], I \[want to be able to traverse OnTrack in a sensible way\], so that I \[can + submit my work with ease\]. +1. As a student, I \[want to be able to re-submit some of many files\], so that I \[do not have to + re-upload all files related to a task\]. +1. As a student, I \[want to be able to see a history of events\], so that I \ + [can see the last time a file was uploaded or a message was sent by the tutor\]. +1. As a student, I \[want to be able to include comments with my uploads\], so that I \[may discuss + the task with my tutor\]. +1. As a student, I \[want to be able to view my submissions in my browser\], so that I \[don't have + to keep downloading copies of my submissions\]. + +### Tutors + +1. As a tutor, I \[want to make sure that my students understand a concept\], so that \[they can + succeed at their studies\]. +1. As a tutor, I \[want to see a clear log of my interactions\], so that I \ + [can orient quicker\]. +1. As a tutor, I \[want to be able to compare student code files they have submitted\]. +1. As a masker, I \[want to be able to highlight and leave notes on files\], so that I \[can provide + feedback to my students\]. + +### Convenors + +1. As a convenor, I \[want tutors to interact with their students before marking\], so that \[they + interact with their students\]. + +### Developers + +1. As a developer, I \[want a high-fidelity wire-frame\], so that I \[can create a design that + further incorporates OnTrack/Doubtfire's visual style and nuance\]. +1. As a developer, I \[want a UI\UX prototype of the product\], so that I \[can create documentation + on the design\]. +1. As a developer, I \[want a UI/UX prototype of the product\], so that I \[can create a prototype + of the design\]. +1. As a developer, I \[want more interaction facilitated by a chat-bot\], so that \[interactions are + streamlined and feel modern\]. + +## Features + +1. A time-based log. + - Derived from student user story no. 3 and tutor user story no. 2. +1. Stages for tasks. + - Derived from tutor user story no. 1. +1. In-browser file viewer with comment appending capabilities. + - Derived from student user story no. 5 and tutor user story no. 4. +1. Selective file replacement. + - Derived from student user story no. 2. +1. Diff viewer + - Derived from tutor user story no. 3. diff --git a/src/content/docs/Products/OnTrack/Projects/Tutor Times/Documentation/design-back-end.md b/src/content/docs/Products/OnTrack/Projects/Tutor Times/Documentation/design-back-end.md new file mode 100644 index 00000000..c33ef58e --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Tutor Times/Documentation/design-back-end.md @@ -0,0 +1,145 @@ +--- +title: Backend Design Document for "Tutor Times" Feature in OnTrack +--- + +## 1. Introduction + +### 1.1 Purpose + +This document outlines the design of the backend for the "Tutor Times" feature in OnTrack (formerly +known as Doubtfire). The purpose is to establish the architectural and functional aspects of the +backend necessary to support efficient time tracking and management for tutors. + +### 1.2 Scope + +The scope of this design document covers the following aspects of the backend development for the +"Tutor Times" feature: + +- Data Models and Schema +- API Endpoints +- Authentication and Authorisation +- Background Jobs/Triggers +- Data Integrity Constraints +- Performance Optimization +- Security Measures +- Compatibility with Frontend and Other Modules + +### 1.3 Intended Audience + +This document is intended for backend developers, database administrators, and stakeholders involved +in the implementation of the "Tutor Times" feature. + +## 2. Architecture and Data Models + +- A link for UML diagrams will be provided here in future to illustrate the architecture and data + models for the "Tutor Times" feature. + +### 2.1 Data Storage + +- Create a new database table named `tutor_times` or modify an existing one to store marking time + data for tutors and students. +- Define fields such as `tutor_id`, `student_id`, `task_id`, `start_time`, and `end_time` to record + marking session details. + +### 2.2 Data Schema + +- Define a comprehensive data schema that includes relationships between tables to support the + required functionality. +- Ensure that the schema accommodates storing marking time data at both the student and task levels. + +### 2.3 Database Relationships + +- Establish relationships between tables to associate marking time data with tutors, students, and + tasks. +- Define foreign keys and indices to optimize query performance. + +## 3. API Design + +### 3.1 API Endpoints + +- Develop a set of RESTful API endpoints to interact with marking time data. +- Implement the following endpoints: + - `POST /api/tutor-times`: Create a new marking session record. + - `GET /api/tutor-times/:id`: Retrieve a specific marking session record. + - `GET /api/tutor-times/tutor/:tutor_id`: Retrieve all marking session records for a specific + tutor. + - `GET /api/tutor-times/student/:student_id`: Retrieve all marking session records for a specific + student. + - `PUT /api/tutor-times/:id`: Update an existing marking session record. + - `DELETE /api/tutor-times/:id`: Delete a marking session record. + +### 3.2 Authentication and Authorisation + +- Implement user authentication and authorisation to secure access to marking time data. +- Ensure that only authorised users (tutors and unit chairs) can perform CRUD operations on marking + session records. + +## 4. Background Jobs/Triggers + +### 4.1 Calculation of Marking Time Totals + +- Develop background jobs or database triggers to calculate and update total marking time for each + tutor and student. +- The system should automatically update marking time totals when new marking session records are + added or modified. + +## 5. Data Integrity and Validation + +### 5.1 Data Integrity Constraints + +- Implement data integrity constraints to ensure the accuracy and consistency of data. +- Enforce rules such as referential integrity and data type validation to maintain data quality. + +## 6. Non-Functional Requirements + +### 6.1 Performance Optimization + +- Optimize database queries and operations to ensure fast data retrieval, even as the volume of + marking time records grows. +- Implement caching mechanisms to reduce query load and enhance system performance. + +### 6.2 Security Measures + +- Implement necessary security measures to protect marking time data and prevent unauthorized + access. +- Use encryption to secure sensitive data, such as user credentials. + +### 6.3 Compatibility + +- Ensure compatibility with the frontend and other system components. +- Verify that the API endpoints work seamlessly with modern web browsers and other clients. + +## 7. Testing Strategy + +### 7.1 Unit Testing + +- Develop comprehensive unit tests for API endpoints, database interactions, and background jobs to + ensure the correctness and reliability of backend components. + +### 7.2 Integration Testing + +- Perform integration testing to verify the seamless integration of backend components with the + frontend and other system modules. + +## 8. Deployment Plan + +### 8.1 Deployment Environment + +- Deploy the backend of the "Tutor Times" feature to the production environment of OnTrack. + +### 8.2 Deployment Process + +- Follow a systematic deployment process to release backend updates, including version control and + continuous integration practices. + +## 9. Conclusion + +This design document provides a detailed plan for the backend implementation of the "Tutor Times" +feature in OnTrack. It covers the architectural aspects, data models, API design, security measures, +testing strategies, and deployment plans. By following this design, we ensure the reliable and +efficient operation of the "Tutor Times" feature, enhancing the user experience for tutors and +students. + +## 10. Appendices + +- Include any additional information, diagrams, or references that support the design document. diff --git a/src/content/docs/Products/OnTrack/Projects/Tutor Times/Documentation/design-front-end.md b/src/content/docs/Products/OnTrack/Projects/Tutor Times/Documentation/design-front-end.md new file mode 100644 index 00000000..7135b73a --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Tutor Times/Documentation/design-front-end.md @@ -0,0 +1,210 @@ +--- +title: Frontend Design Document for "Tutor Times" Feature in OnTrack +--- + +## 1. Introduction + +### 1.1 Purpose + +This document outlines the design of the frontend for the "Tutor Times" feature in OnTrack (formerly +known as Doubtfire). The purpose is to provide an intuitive and user-friendly interface for tutors +to track and manage the time spent on providing feedback to students. + +### 1.2 Scope + +The scope of this design document covers the user interface (UI) and user experience (UX) aspects of +the "Tutor Times" feature within the OnTrack Learning Management System. This feature will enhance +the skill-based course delivery model by enabling tutors to monitor their time management +efficiently. + +### 1.3 Intended Audience + +This document is intended for frontend developers, designers, and stakeholders involved in the +implementation of the "Tutor Times" feature. + +## 2. User Interface (UI) Design + +### 2.1 Overview + +The "Tutor Times" feature will seamlessly integrate into the existing OnTrack UI, maintaining a +cohesive visual identity and navigation structure. + +### 2.2 Wireframes and Mockups + +#### 2.2.1 Dashboard + +- A link will be provided here in future to the mockup for the Dashboard. + +- The dashboard provides an overview of marking time statistics, including total time spent, average + time per student, and notifications. + +#### 2.2.2 Student Feedback Page + +- A link will be provided here in future to the mockup for the Student Feedback Page. + +- The Student Feedback Page displays a list of students and their respective marking times. Tutors + can start, stop, or manually input time for each student. + +### 2.3 Responsive Design + +The UI will be responsive to ensure a consistent user experience across various devices, including +desktops, tablets, and mobile phones. + +### 2.4 Colour Scheme + +- **Primary Colour**: OnTrack primary colour +- **Secondary Colour**: OnTrack secondary colour +- **Text Colour**: OnTrack text colours + +### 2.5 Typography + +- **Headings**: OnTrack head text font (Bold) +- **Body Text**: OnTrack body text font (Regular) +- **Buttons**: OnTrack button text (Semi-Bold) + +### 2.6 Icons + +Standard icons will be used for actions such as starting and stopping timers, along with custom +icons for notifications. + +### 2.7 Navigation + +The "Tutor Times" feature will be accessible through the main navigation menu within OnTrack. Clear +breadcrumbs will guide users through the application. + +### 2.8 Forms and Inputs + +Input forms will include text fields for manual time input, along with start and stop buttons for +timers. Error handling will include validation and user-friendly error messages. + +### 2.9 Notifications + +Notifications will be displayed at the top of the dashboard, providing real-time feedback on marking +progress and milestones. + +### 2.10 User Profiles + +Tutors will have access to their profiles to view personal information and settings. + +## 3. User Experience (UX) Design + +### 3.1 User Flows + +#### 3.1.1 Tracking Marking Time + +1. Tutors log in to OnTrack. +2. Tutors access the "Tutor Times" feature from the dashboard. +3. Tutors start a timer for a specific student. +4. Tutors stop the timer when finished. +5. Tutors can manually input time if needed. +6. Tutors receive notifications for milestones and progress. + +### 3.2 Accessibility + +Accessibility features will be implemented, including alt text for images, keyboard navigation, and +screen reader compatibility. + +### 3.3 Usability + +The UI will prioritize usability, with clear and intuitive interactions, ensuring tutors can +efficiently manage marking times. + +### 3.4 User Feedback + +A feedback mechanism will be incorporated for users to report issues or suggest improvements, +enhancing the feature over time. + +## 4. Interactive Features + +### 4.1 Timer/Stopwatch Feature + +- Tutors can start, stop, and reset timers to track marking time for each student accurately. + +### 4.2 Manual Time Input + +- Tutors have the option to manually input marking time for students, providing flexibility in time + tracking. + +### 4.3 Notification System + +- Real-time notifications will alert tutors of milestones and progress, enhancing user engagement. + +## 5. Performance Considerations + +### 5.1 Page Load Times + +Efforts will be made to optimize page load times to ensure a seamless user experience. + +### 5.2 Caching + +Caching mechanisms will be implemented to reduce load times and improve overall performance. + +## 6. Compatibility + +### 6.1 Browser Compatibility + +- Supported browsers: Chrome, Firefox, Safari, Edge +- Cross-browser compatibility will be ensured. + +### 6.2 Device Compatibility + +Responsive design will ensure compatibility with various devices, including desktops, tablets, and +mobile phones. + +## 7. Security + +### 7.1 Data Security + +- User data will be securely stored and protected against unauthorized access. + +### 7.2 HTTPS + +- HTTPS will be enforced to secure data transmission between the frontend and backend. + +## 8. Version Control and Collaboration + +### 8.1 Version Control + +- Git will be used for version control, following a branching strategy for collaborative + development. + +### 8.2 Collaboration Tools + +- Tools like Slack and project management software will facilitate communication among team members. + +## 9. Testing Plan + +### 9.1 Unit Testing + +- Unit tests will be developed for frontend components, including timers, input forms, and + notifications. + +### 9.2 User Acceptance Testing + +- User acceptance testing (UAT) will ensure that the "Tutor Times" feature meets user requirements + and expectations. + +## 10. Deployment Plan + +### 10.1 Deployment Environment + +- The feature will be deployed to the OnTrack production environment. + +### 10.2 Deployment Process + +- A systematic deployment process will be followed to release frontend updates to the live + environment. + +## 11. Conclusion + +This design document provides a comprehensive plan for the frontend implementation of the "Tutor +Times" feature in OnTrack. It outlines the UI/UX design, interactive features, performance +considerations, compatibility, security measures, and testing strategies. This design will enhance +the learning experience for tutors and students, promoting efficient time management and feedback +delivery. + +## 12. Appendices + +- Once the UI and UX designs are finalized, links will be provided to the mockups. +- Once the UML diagrams are finalized, links will be provided to the diagrams. +- Once the feature is implemented, a link will be provided to the frontend repository. diff --git a/src/content/docs/Products/OnTrack/Projects/Tutor Times/Documentation/requrirements-back-end.md b/src/content/docs/Products/OnTrack/Projects/Tutor Times/Documentation/requrirements-back-end.md new file mode 100644 index 00000000..b029b0fe --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Tutor Times/Documentation/requrirements-back-end.md @@ -0,0 +1,153 @@ +--- +title: Backend Requirements Document +--- + +## Project Overview + +## Table of Contents + +1. [Introduction](#1-introduction) 1.1 [Purpose](#11-purpose) 1.2 [Scope] (#12-scope) 1.3 + [Intended Audience](#13-intended-audience) + +2. [Functional Requirements](#2-functional-requirements) 2.1 [Data Storage] (#21-data-storage) 2.2 + [API Endpoints](#22-api-endpoints) 2.3 + [Authentication and Authorisation](#23-authentication-and-authorisation) 2.4 + [Background Jobs/Triggers](#24-background-jobstriggers) 2.5 [Data Schema](#25-data-schema) + +3. [Non-Functional Requirements](#3-non-functional-requirements) 3.1 [Performance](#31-performance) + 3.2 [Security](#32-security) 3.3 [Compatibility](#33-compatibility) + +4. [User Stories](#4-user-stories) 4.1 [As a tutor...](#41-as-a-tutor) 4.2 + [As a unit chair...](#42-as-a-unit-chair) 4.3 [As a unit chair...](#43-as-a-unit-chair) + +5. [Database Schema](#5-database-schema) 5.1 [Tables and Fields] (#51-tables-and-fields) 5.2 + [Relationships](#52-relationships) 5.3 + [Data Integrity Constraints](#53-data-integrity-constraints) + +6. [Testing Requirements](#6-testing-requirements) 6.1 [Unit Testing] (#61-unit-testing) 6.2 + [Integration Testing](#62-integration-testing) + +## 1. Introduction + +### 1.1 Purpose + +The purpose of this document is to outline the requirements for the backend development of the +"Tutor Times" feature. This feature will enable the storage and retrieval of marking time data for +tutors and students. + +### 1.2 Scope + +The scope of this document covers the functional and non-functional requirements for the backend +implementation of the "Tutor Times" feature. + +### 1.3 Intended Audience + +This document is intended for backend developers and the development team responsible for +implementing the "Tutor Times" feature. + +## 2. Functional Requirements + +### 2.1 Data Storage + +- Create a new database table named `tutor_times` or modify an existing one to store marking time + data for tutors and students. +- Define fields such as `tutor_id`, `student_id`, `task_id`, `start_time`, and `end_time` to record + marking session details. + +### 2.2 API Endpoints + +- Develop a set of RESTful API endpoints to interact with marking time data. +- Implement the following endpoints: + - `POST /api/tutor-times`: Create a new marking session record. + - `GET /api/tutor-times/:id`: Retrieve a specific marking session record. + - `GET /api/tutor-times/tutor/:tutor_id`: Retrieve all marking session records for a specific + tutor. + - `GET /api/tutor-times/student/:student_id`: Retrieve all marking session records for a specific + student. + - `PUT /api/tutor-times/:id`: Update an existing marking session record. + - `DELETE /api/tutor-times/:id`: Delete a marking session record. + +### 2.3 Authentication and Authorisation + +- Implement user authentication and authorisation to secure access to marking time data. +- Ensure that only authorised users (tutors and unit chairs) can perform CRUD operations on marking + session records. + +### 2.4 Background Jobs/Triggers + +- Develop background jobs or database triggers to calculate and update total marking time for each + tutor and student. +- The system should automatically update marking time totals when new marking session records are + added or modified. + +### 2.5 Data Schema + +- Define a comprehensive data schema that includes relationships between tables to support the + required functionality. +- Ensure that the schema accommodates storing marking time data at both the student and task levels. + +## 3. Non-Functional Requirements + +### 3.1 Performance + +- Optimize database queries and operations to ensure fast data retrieval, even as the volume of + marking time records grows. +- Implement caching mechanisms to reduce query load and enhance system performance. + +### 3.2 Security + +- Implement necessary security measures to protect marking time data and prevent unauthorised + access. +- Use encryption to secure sensitive data, such as user credentials. + +### 3.3 Compatibility + +- Ensure compatibility with the frontend and other system components. +- Verify that the API endpoints work seamlessly with modern web browsers and other clients. + +## 4. User Stories + +### 4.1 As a tutor + +- Tutors should be able to view their marking time data on the frontend interface, which is + retrieved from the backend via API calls. + +### 4.2 As a unit chair + +- Unit chairs should have access to total marking time data for each tutor through the frontend + interface. + +### 4.3 As a unit chair + +- Unit chairs should be able to see marking time data at the task level through the frontend + interface. + +## 5. Database Schema + +- Will include a database schema diagram here in future. + +### 5.1 Tables and Fields + +- Create or modify database tables according to the defined schema. +- Define fields, data types, constraints, and relationships between tables. + +### 5.2 Relationships + +- Establish relationships between tables to associate marking time data with tutors, students, and + tasks. + +### 5.3 Data Integrity Constraints + +- Implement data integrity constraints to ensure the accuracy and consistency of data. + +## 6. Testing Requirements + +### 6.1 Unit Testing + +- Develop comprehensive unit tests for API endpoints, database interactions, and background jobs to + ensure the correctness and reliability of backend components. + +### 6.2 Integration Testing + +- Perform integration testing to verify the seamless integration of backend components with the + frontend and other system modules. diff --git a/src/content/docs/Products/OnTrack/Projects/Tutor Times/Documentation/requrirements-front-end.md b/src/content/docs/Products/OnTrack/Projects/Tutor Times/Documentation/requrirements-front-end.md new file mode 100644 index 00000000..9149d7cc --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Tutor Times/Documentation/requrirements-front-end.md @@ -0,0 +1,150 @@ +--- +title: Frontend Requirements Document +--- + +## Project Overview + +## Table of Contents + +[1. Introduction](#1-introduction) + +- [1.1 Purpose] +- [1.2 Scope] +- [1.3 Intended Audience] + +[2. Functional Requirements] + +- [2.1 Tutor's Marking Progress Page] +- [2.2 User Interface] +- [2.3 Timer/Stopwatch Feature] +- [2.4 Manual Time Input] +- [2.5 Notification System] + +[3. Non-Functional Requirements](#3-non-functional-requirements) + +- [3.1 Performance] +- [3.2 Usability] +- [3.3 Compatibility] +- [3.4 Security] + +[4. User Stories](#4-user-stories) + +- [4.1 User Story 1] +- [4.2 User Story 2] +- [4.3 User Story 3] + +[5. Design Mockups](#5-design-mockups) + +[6. Testing Requirements](#6-testing-requirements) + +- [6.1 Unit Testing] +- [6.2 User Acceptance Testing] + +## 1. Introduction + +### 1.1 Purpose + +The purpose of this document is to outline the requirements for the frontend development of the +"Tutor Times" feature. This feature will enable tutors to track and manage the time spent on +providing feedback to students. + +### 1.2 Scope + +The scope of this document covers the functional and non-functional requirements for the frontend +implementation of the "Tutor Times" feature. + +### 1.3 Intended Audience + +This document is intended for frontend developers and the development team responsible for +implementing the "Tutor Times" feature. + +## 2. Functional Requirements + +### 2.1 Tutor's Marking Progress Page + +- Create a dedicated page/dashboard where tutors can view their marking progress. +- Display the time spent providing feedback to each student. + +### 2.2 User Interface + +- Design an intuitive and user-friendly interface for the Tutor's Marking Progress Page. +- Ensure responsive design for various screen sizes and devices. +- Provide an option for tutors to manually input marking time. + +### 2.3 Timer/Stopwatch Feature + +- Implement a timer or stopwatch feature that tutors can start and stop to track time spent on each + student. +- Ensure accuracy in time tracking. + +### 2.4 Manual Time Input + +- Allow tutors to manually input marking time for each student in case they forget to start or stop + the timer. + +### 2.5 Notification System + +- Implement a notification system to alert tutors when they reach specific time milestones. + +### 3. Non-Functional Requirements + +## 3.1 Performance + +- Ensure that the Tutor's Marking Progress Page loads quickly. +- Minimize any performance impact on the overall application. + +## 3.2 Usability + +- The user interface should be intuitive and easy to use for tutors. +- Ensure that the feature is accessible to all users. + +## 3.3 Compatibility + +- Ensure compatibility with modern web browsers (e.g., Chrome, Firefox, Safari). +- Verify cross-browser compatibility and address any compatibility issues. + +## 3.4 Security + +- Implement necessary security measures to protect user data and prevent unauthorized access to + arking time records. + +## 4. User Stories + +### 4.1 User Story 1 + +**# As a tutor, I want to see how long I have spent providing feedback to each student.** + +- Tutors should be able to view the time spent on each student's feedback on the Tutor's Marking + Progress Page. + +### 4.2 User Story 2 + +### As a unit chair, I want to see how long each tutor has spent providing + +feedback to each student.\*\* + +- Unit chairs should have access to view the total marking time for each tutor on the Tutor's + Marking Progress Page. + +## 4.3 User Story 3 + +**As a unit chair, I want to see how long each tutor has spent providing feedback to each task.** + +- Unit chairs should be able to see the time spent by each tutor on specific tasks on the Tutor's + Marking Progress Page. + +## 5. Design Mockups + +- Link will be provided to the design mockups for the Tutor's Marking Progress Page. + +## 6. Testing Requirements + +## 6.1 Unit Testing + +- Develop unit tests to ensure the correctness and reliability of frontend components, including + timers, manual input, and notifications. + +## 6.2 User Acceptance Testing + +- Conduct user acceptance testing to verify that the "Tutor Times" feature meets the requirement and + user expectations. diff --git a/src/content/docs/Products/OnTrack/Projects/Tutor Times/UML Diagrams/uml-diagram.md b/src/content/docs/Products/OnTrack/Projects/Tutor Times/UML Diagrams/uml-diagram.md new file mode 100644 index 00000000..8e845235 --- /dev/null +++ b/src/content/docs/Products/OnTrack/Projects/Tutor Times/UML Diagrams/uml-diagram.md @@ -0,0 +1,21 @@ +--- +title: UML diagram:New feature 'Tutor Times' in OnTrack +--- + +Author: Devanshi Patel + +Company: Thoth Tech + +## Introduction + +This Document outlines the flow of the new feature 'Tutor Time' into Ontrack. + +## Use Case Diagram + +- [UML - Tutor Time] + () + +## UML Diagram + +- [UML - Tutor Time] + () diff --git a/src/content/docs/Products/OnTrack/images/clickingonlocalhost.PNG b/src/content/docs/Products/OnTrack/images/clickingonlocalhost.PNG new file mode 100644 index 00000000..0c48ce17 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/clickingonlocalhost.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/confirmation.PNG b/src/content/docs/Products/OnTrack/images/confirmation.PNG new file mode 100644 index 00000000..52fda15b Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/confirmation.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/git-workflow.png b/src/content/docs/Products/OnTrack/images/git-workflow.png new file mode 100644 index 00000000..c636b41e Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/git-workflow.png differ diff --git a/src/content/docs/Products/OnTrack/images/imag-21.PNG b/src/content/docs/Products/OnTrack/images/imag-21.PNG new file mode 100644 index 00000000..d7ada252 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/imag-21.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-12.PNG b/src/content/docs/Products/OnTrack/images/image-12.PNG new file mode 100644 index 00000000..04e8c65f Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-12.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-13.PNG b/src/content/docs/Products/OnTrack/images/image-13.PNG new file mode 100644 index 00000000..5f8672e3 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-13.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-14.PNG b/src/content/docs/Products/OnTrack/images/image-14.PNG new file mode 100644 index 00000000..6f51978e Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-14.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-15.PNG b/src/content/docs/Products/OnTrack/images/image-15.PNG new file mode 100644 index 00000000..5246c903 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-15.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-16.PNG b/src/content/docs/Products/OnTrack/images/image-16.PNG new file mode 100644 index 00000000..41db5ba8 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-16.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-17.PNG b/src/content/docs/Products/OnTrack/images/image-17.PNG new file mode 100644 index 00000000..ff50cd3d Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-17.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-18.PNG b/src/content/docs/Products/OnTrack/images/image-18.PNG new file mode 100644 index 00000000..b6f4688e Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-18.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-19.PNG b/src/content/docs/Products/OnTrack/images/image-19.PNG new file mode 100644 index 00000000..cdbb0198 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-19.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-20.PNG b/src/content/docs/Products/OnTrack/images/image-20.PNG new file mode 100644 index 00000000..409ee457 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-20.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-22.PNG b/src/content/docs/Products/OnTrack/images/image-22.PNG new file mode 100644 index 00000000..33a404e7 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-22.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-23.PNG b/src/content/docs/Products/OnTrack/images/image-23.PNG new file mode 100644 index 00000000..f534872b Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-23.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-24.PNG b/src/content/docs/Products/OnTrack/images/image-24.PNG new file mode 100644 index 00000000..3daa30d8 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-24.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-25.PNG b/src/content/docs/Products/OnTrack/images/image-25.PNG new file mode 100644 index 00000000..94cd791e Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-25.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-26.PNG b/src/content/docs/Products/OnTrack/images/image-26.PNG new file mode 100644 index 00000000..424c1c42 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-26.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-27.PNG b/src/content/docs/Products/OnTrack/images/image-27.PNG new file mode 100644 index 00000000..d9f21c22 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-27.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-28.PNG b/src/content/docs/Products/OnTrack/images/image-28.PNG new file mode 100644 index 00000000..72daa296 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-28.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-29.PNG b/src/content/docs/Products/OnTrack/images/image-29.PNG new file mode 100644 index 00000000..c7017b52 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-29.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-eight.PNG b/src/content/docs/Products/OnTrack/images/image-eight.PNG new file mode 100644 index 00000000..d84d9369 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-eight.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-eleven.PNG b/src/content/docs/Products/OnTrack/images/image-eleven.PNG new file mode 100644 index 00000000..3cb04747 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-eleven.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-five.PNG b/src/content/docs/Products/OnTrack/images/image-five.PNG new file mode 100644 index 00000000..e8ca2644 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-five.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-four.PNG b/src/content/docs/Products/OnTrack/images/image-four.PNG new file mode 100644 index 00000000..e6b0dd94 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-four.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-nine.PNG b/src/content/docs/Products/OnTrack/images/image-nine.PNG new file mode 100644 index 00000000..29d094df Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-nine.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-one.PNG b/src/content/docs/Products/OnTrack/images/image-one.PNG new file mode 100644 index 00000000..ba09c870 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-one.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-seven.PNG b/src/content/docs/Products/OnTrack/images/image-seven.PNG new file mode 100644 index 00000000..f8766d41 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-seven.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-six.PNG b/src/content/docs/Products/OnTrack/images/image-six.PNG new file mode 100644 index 00000000..ea7b13c0 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-six.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-ten.PNG b/src/content/docs/Products/OnTrack/images/image-ten.PNG new file mode 100644 index 00000000..3dddd366 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-ten.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-three.PNG b/src/content/docs/Products/OnTrack/images/image-three.PNG new file mode 100644 index 00000000..6f2084dc Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-three.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image-two.PNG b/src/content/docs/Products/OnTrack/images/image-two.PNG new file mode 100644 index 00000000..08dbfe69 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image-two.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/image21-correct.PNG b/src/content/docs/Products/OnTrack/images/image21-correct.PNG new file mode 100644 index 00000000..8c526ef0 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/image21-correct.PNG differ diff --git a/src/content/docs/Products/OnTrack/images/label.png b/src/content/docs/Products/OnTrack/images/label.png new file mode 100644 index 00000000..e69de29b diff --git a/src/content/docs/Products/OnTrack/images/labels.jpg b/src/content/docs/Products/OnTrack/images/labels.jpg new file mode 100644 index 00000000..b9493939 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/labels.jpg differ diff --git a/src/content/docs/Products/OnTrack/images/moving.avif b/src/content/docs/Products/OnTrack/images/moving.avif new file mode 100644 index 00000000..cff3742a Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/moving.avif differ diff --git a/src/content/docs/Products/OnTrack/images/moving.png b/src/content/docs/Products/OnTrack/images/moving.png new file mode 100644 index 00000000..920c627e Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/moving.png differ diff --git a/src/content/docs/Products/OnTrack/images/overview.png b/src/content/docs/Products/OnTrack/images/overview.png new file mode 100644 index 00000000..e69de29b diff --git a/src/content/docs/Products/OnTrack/images/overvieww.png b/src/content/docs/Products/OnTrack/images/overvieww.png new file mode 100644 index 00000000..8e462794 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/overvieww.png differ diff --git a/src/content/docs/Products/OnTrack/images/sprint.png b/src/content/docs/Products/OnTrack/images/sprint.png new file mode 100644 index 00000000..d32371c4 Binary files /dev/null and b/src/content/docs/Products/OnTrack/images/sprint.png differ diff --git a/src/content/docs/Products/OnTrack/images/workflow.png b/src/content/docs/Products/OnTrack/images/workflow.png new file mode 100644 index 00000000..e69de29b diff --git a/src/content/docs/Products/OnTrack/index.mdx b/src/content/docs/Products/OnTrack/index.mdx new file mode 100644 index 00000000..4a8e617b --- /dev/null +++ b/src/content/docs/Products/OnTrack/index.mdx @@ -0,0 +1,129 @@ +--- +title: "OnTrack: Transforming Learning Through Feedback" +description: The landing page for OnTrack. +sidebar: + label: Getting Started + order: 0 +--- + +import { Card, LinkCard, CardGrid, Icon } from "@astrojs/starlight/components"; + + + OnTrack is an advanced platform designed to streamline assignment submissions and feedback + management for students and educators. As a flagship product of Thoth Tech, OnTrack redefines how + students engage with assignments and feedback, making the learning experience more efficient, + transparent, and impactful. + + + + + + + +## thoth-tech GitHub repos + + + + + + + +## About Us + +This team is working on the production of an innovative Learning Management System that is designed +for a skill-based course delivery model. + +Students will gain real experience thourgh regular practice receive rapid feedback on their work on +a weekly basis. This platform is used to connect tutors and students at Deakin university as well as +other universities around the world. + +## What is OnTrack? + +OnTrack is a powerful learning tool built to simplify and enhance the academic process. It empowers +students to submit assignments with ease, receive meaningful feedback, and monitor their progress +throughout their academic journey. OnTrack bridges the gap between students and educators, fostering +collaboration and continuous improvement. + +By addressing the inefficiencies in traditional assignment workflows, OnTrack ensures that students +and educators can focus on what truly matters: learning and teaching. + +## Key Features + +### 1. Simplified Assignment Submissions + +- A seamless and intuitive interface for uploading assignments. +- Automated notifications to remind students of deadlines. +- Real-time submission tracking for added transparency. + +### 2. Comprehensive Feedback Management + +- A centralized system for receiving and reviewing feedback. +- Clear and structured input from educators to guide improvements. +- A repository of feedback history for easy access during revisions. + +### 3. Progress Monitoring and Analytics + +- Visual performance insights to track growth over time. +- Tools to identify strengths and areas for improvement. +- Exportable progress reports for personal records or academic reviews. + +### 4. Collaboration Tools + +- Transparent communication channels between students and reviewers. +- Team-based project tracking to improve coordination in group work. +- Role-specific features for educators to streamline grading and feedback. + +## Why OnTrack? + +### For Students + +- Ensures a stress-free workflow by automating repetitive tasks like deadline reminders and + submission confirmations. +- Promotes accountability by maintaining a record of submissions and feedback. +- Helps students stay focused on learning with clear, actionable insights. + +### For Educators + +- Simplifies the grading process, saving time and effort. +- Provides structured feedback tools for consistent evaluation. +- Enhances communication with students, ensuring queries are resolved efficiently. + +## Integration with Thoth Tech + +OnTrack is a cornerstone of Thoth Tech, a student-led initiative under the guidance of senior +professors. As part of the ecosystem, it shares Thoth Tech's vision of creating innovative solutions +that address real-world challenges in education. OnTrack complements other Thoth Tech products by +fostering a feedback-driven culture in learning environments. + +## Why OnTrack for Team Project A? + +OnTrack is an ideal choice for students participating in Team Project A. It offers a unique +opportunity to contribute to a project that directly impacts education while gaining valuable +skills. + +### Key Benefits for Team Project A + +- **Real-World Relevance:** Work on an active product solving critical challenges in education. +- **Skill Building:** Gain hands-on experience in software development, user experience design, and + project management. +- **Scalable Impact:** Contribute to a tool with the potential for adoption beyond your university, + leaving a lasting legacy. +- **Creative Freedom:** Innovate within a flexible framework, focusing on improving the student and + educator experience. + +## How OnTrack Stands Out + +OnTrack distinguishes itself from other projects with its: + +- **Student-Centric Design:** Built for students, shaped by their input, and continuously improved + based on their feedback. +- **Holistic Learning Approach:** Encourages students to think beyond technical skills, + incorporating design thinking and collaboration. +- **Tangible Outcomes:** Delivers measurable benefits to users, ensuring every contribution has a + lasting impact. + +By joining OnTrack, students in Team Project A can make a meaningful contribution to education while +building the skills they need for their future careers. diff --git a/src/content/docs/Products/SplashKit/01-overview.mdx b/src/content/docs/Products/SplashKit/01-overview.mdx new file mode 100644 index 00000000..9b7ca022 --- /dev/null +++ b/src/content/docs/Products/SplashKit/01-overview.mdx @@ -0,0 +1,119 @@ +--- +title: Onboarding Overview +description: Learn about the onboarding process for the Splashkit. +sidebar: + label: Getting Started with SplashKit + order: 1 +--- + +import { LinkCard, Tabs, TabItem } from "@astrojs/starlight/components"; + +Welcome to the SplashKit onboarding section! This set of guides will help you get started with +using, contributing to, and maintaining all things SplashKit. The onboarding materials are designed +to be useful both as a step-by-step walkthrough for newcomers and as a reference for ongoing tasks. + +## Getting Started + +If you're new to SplashKit, start with these foundational guides: + + + + + +## Contributing to the SplashKit + +Ready to contribute? These guides cover how to make your own contributions to your SplashKit team + + + + + + + + + + + + + + +--- + +When you have made your first contribution and are ready for feedback follow these guides on how to +make a pull request + + + + +## Reviewing and Collaborating + +Collaboration is key to maintaining high standards. These guides cover how to conduct peer reviews, +including the things to look for and how to provide constructive feedback: + + + + + +## Additional Resources + +As you settle into your role, you'll need to understand how to use the team's planner board +effectively. This guide provides guidelines for using the planner board to track tasks, manage the +planner cards and work efficiently: + + diff --git a/src/content/docs/Products/SplashKit/02-setting-up.mdx b/src/content/docs/Products/SplashKit/02-setting-up.mdx new file mode 100644 index 00000000..fca07457 --- /dev/null +++ b/src/content/docs/Products/SplashKit/02-setting-up.mdx @@ -0,0 +1,150 @@ +--- +title: Get Your Environment Set Up +description: This is a step-by-step guide on how to get started within the SplashKit Starlight repo. +sidebar: + label: "- Setting Up Your Environment" + order: 2 +--- + +import { Steps, Aside, Tabs, TabItem } from "@astrojs/starlight/components"; + +## Install Necessary Tools + +First things first, you'll need to install the necessary tools to get started working within +SplashKit.io. + +### 1. Install GIT + +Git is essential for version control, allowing you to clone repositories, commit changes, and +collaborate. Before you start, ensure you have Git installed on your system. + +- Windows: Download Git from [here](https://git-scm.com/download/win) and run the installer `.exe` + file. +- macOS: Git should already be installed, but you can install it with [homebrew](https://brew.sh/) + using the following command in your terminal: + + ```shell + brew install git + ``` + +- Linux: Install using the package manager. For example, on Ubuntu or Debian, run the following + command: + + ```shell + sudo apt-get install git + ``` + +After installation, verify the installation with: + +```shell +git --version +``` + +### 2. Download and Install VS Code + +- Download VS Code: Visit the official + [VS Code download page](https://code.visualstudio.com/download) and select the appropriate + installer for your operating system (Windows, macOS, or Linux). + +- Install VS Code: + - Windows: Run the downloaded `.exe` file and follow the installation wizard. + - macOS: Open the `.dmg` file and drag the Visual Studio Code icon to the Applications folder. + - Linux: Install using the appropriate package manager or by downloading the `.deb` or `.rpm` + package from the website. + +- Launch VS Code: Once installed, launch Visual Studio Code. + +### 3. Download and Install Node.js + +- Download Node.js: Go to the official + [Node.js website](https://nodejs.org/en/download/package-manager) and download the LTS version for + your operating system. +- Install Node.js: + - Windows: Run the downloaded `.msi` file and follow the installation wizard. + - macOS: Open the `.pkg` file and follow the instructions. + - Linux: You can use a package manager or install it via NodeSource. + +- Verify Installation: Open a terminal (or command prompt) and check if Node.js is installed + correctly by running the following command: + + ```shell + node -v + ``` + + This should return the version number of Node.js. + + Also, verify the installation of npm (Node Package Manager) by running the following command: + + ```shell + npm -v + ``` + + This should return the version of npm installed. + +### 4. Install SplashKit + +Head to the [SplashKit.io](https://splashkit.io/) website and follow the instructions for your +specific operating system to install SplashKit. + +### 5. Install Docker + +Head to [Docker](https://docs.docker.com/engine/install/) and install Docker for your specific +operating system. + +### 6. Install Extensions for VS Code + +- Node.js Extension: Install the Node.js extension in VS Code for better integration: + - Open VS Code and go to the Extensions sidebar. + - Search for "Node.js Extension Pack" and install it. + +- GitHub Extension: This allows you to interact with GitHub directly from VS Code.: + - In the Extensions sidebar, search for "GitHub Pull Requests and Issues" and install it. + +### 7. Install Dependencies + +- Once the project is cloned, navigate to the Project Directory: In the terminal, change into the + cloned project directory: + + ```shell + cd + ``` + + Replace `` with your actual folder name. + +- Install Node Dependencies: + + ```shell + npm install + ``` + +This will install all the necessary packages listed in the `package.json` file. + +--- + +### 8. Installing WSL + + +WSL is a built-in Linux distribution virtual machine for Windows. splashkit-core will be installed +to the Linux distribution. The official SplashKit installation instructions can be found here: +[Windows (WSL) Installation Overview](https://splashkit.io/installation/windows-wsl). + +### 9. Installing Windows Terminal (optional) + +Windows Terminal is an updated Command Prompt with many useful features. It is not mandatory to +install, however it is recommended due to its ease of use. More information about Windows Terminal +can be found here: [Windows Terminal](https://learn.microsoft.com/en-us/windows/terminal/).It can be +installed through the Microsoft Store. + +By default, new tabs will open as a Command Prompt, with WSL terminals being accessible with the +down-arrow. Since WSL will be used so frequently, there is the option to change the default tab to +WSL. Open the settings by clicking the down arrow and selecting β€˜Settings’. In the β€˜Startup’ tab, +β€˜Default profile’ allows you to change the default tab type to WSL. + +## Contributing + +You are should now be ready to start contributing to your team project. Make sure you head over to +the [Planner board etiquette](/products/splashkit/07-planner-board) page and familiarize yourself +with how to correctly interact with the Microsoft Teams Planner board and then get started. + +If you are unfamiliar with how to start contributing through GitHub, check out the +[GitHub guide.](/products/splashkit/03-github-guide) diff --git a/src/content/docs/Products/SplashKit/03-github-guide.mdx b/src/content/docs/Products/SplashKit/03-github-guide.mdx new file mode 100644 index 00000000..1b3b27d4 --- /dev/null +++ b/src/content/docs/Products/SplashKit/03-github-guide.mdx @@ -0,0 +1,497 @@ +--- +title: "splashkit.io GitHub Guide" +sidebar: + label: "- Contributing with GitHub" + order: 3 +--- + +import { Steps, Aside, Tabs, TabItem } from "@astrojs/starlight/components"; + +## Set up a Working Environment for SplashKit + +Here's a step-by-step guide on how to set up a working environment for SplashKit with GitHub + +### 1. Install Git + +First step is to ensure you have the necessary tools installed on your workspace. Follow the guide +in the [setting up](/products/splashkit/02-setting-up) section and then proceed to step 2 + +### 2. Fork a GitHub Repository + +- Log in to GitHub: Go to [GitHub](https://github.com/) and log in with your details. + +- Find the Repository: + + Navigate to the appropriate repo for your team: + - [SplashKit Website repository](https://github.com/thoth-tech/splashkit.io-starlight). + - [SplashKit Online repository](https://github.com/thoth-tech/splashkit-online). + - [SplashKit Core repository](https://github.com/thoth-tech/splashkit-core). + - [Thoth-Tech Documentation Site repository](https://github.com/thoth-tech/ThothTech-Documentation-Website). + + ![splashkit repo](./images/starlightrepo.png) + +- Fork the Repo: Click the "Fork" button at the top right of the repository page and create a new + fork of the repository. ![splashkit fork](./images/splashkitfork.png) + +### 3. Clone the Forked Repository + + + + + + + + + +1. Open a terminal on your machine and run the following commands, making sure to replace `USERNAME` + with your own GitHub username: + + ```shell + git clone https://github.com/USERNAME/splashkit.io-starlight.git + ``` + +2. Then, navigate into the directory: + + ```shell + cd splashkit.io-starlight + git remote add upstream https://github.com/thoth-tech/splashkit.io-starlight.git + ``` + +3. Now you're all set up to start working on the SplashKit.io repo. + + + + + + + + +1. Open a new VSCode window. +2. Open the command palette by pressing `cmd + shift + p` (or `ctrl + shift + p` on Windows/Linux). +3. Type `git clone` and paste the URL of your forked repo. + + ![splashkit repo](./images/gitclone.gif) + +4. When prompted, select the folder location where you want to clone the repo. + + ![splashkit repo](./images/cloningrepo.png) + +5. Once the repo is cloned, VSCode will prompt you to open the repo folder location. + + ![splashkit repo](./images/openrepo.png) + + + +Now you're all set up to start working on the SplashKit.io repo in VSCode. + + + + + + +1. Open GitHub Desktop and click on the `File` tab in the top-left corner, then select + `Clone Repository`. + + ![splashkit repo](./images/clonegitdesk.png) + +2. Here you can either filter via your existing repositories, find the forked repo, or paste the URL + of the forked repo. + + ![splashkit repo](./images/cloneurlgitdesk.png) + +3. Once the repo is cloned, you can open the repo in your preferred code editor. + + + + + + + +Open a WSL terminal and change directory to your home with: + +```shell +cd splashkit-core +``` + +Note that this guide clones the repository to the home directory, but feel free to move its +location. Now initiate the clone process of your fork with: + +```shell +git clone --recursive -j2 https://github.com/{user name}/splashkit-core.git +``` + +splashkit-core contains multiple submodules (separate repositories which splashkit-core depends +upon). The `--recursive` argument ensures that the submodules are also downloaded when calling +clone. Wait for the download to complete before continuing to the next step. + + + + + +### 6. Create a Branch for Your Work + +To start contributing to the SplashKit.io repo, you'll need to create a new branch for each +contribution. This will keep your changes separate from the main branch. You can create a new branch +in a few different ways: + + + +Move into the SplashKit.io directory and create a new branch: + +```shell +git checkout -b your-branch-name +``` + +Then, push the branch to your fork: + +```shell +git push origin your-branch-name +``` + +Now you're all set up to start working on your new branch. + + + + +Open source control by clicking on the icon on the left-hand side of the VSCode window. Then click +on the three dots, go down to `Branch`, and select `Create Branch from`. + +![splashkit repo](./images/newbranch-vscode.png) + +Then, select to make the new branch from `master` and name your branch. + +![splashkit repo](./images/addbranch-vscode.png) ![splashkit repo](./images/namebranch-vscode.png) + +Next, push the branch to your fork by clicking on the `Publish Branch` button in source control. + +![splashkit repo](./images/publishbranch-vscode.png) + +Now you're all set up to start working on your new branch. + + + + +Select the Starlight repo in GitHub Desktop, then click on the `Current Branch` tab and select +`New Branch`. + +![splashkit repo](./images/addbranch-gitdesk.png) + +Name your branch and then click `Create Branch`. + +![splashkit repo](./images/namebranch-gitdesk.png) + +Then push the branch to your fork by clicking on the `Publish Branch` button. + +![splashkit repo](./images/publishbranch-gitdesk.png) + +Now you're all set up to start working on your new branch. + + + + +By creating a new branch for each contribution, you can keep your changes separate from the main +branch. + +### 7. Make Changes and Test + +Open the files in VS Code, make your changes, and test them locally by running or building your +project. You can use the integrated terminal in VS Code to run commands, compile the code, or start +the local server. + +### 8. Commit and Push Changes to GitHub + +After you've made changes, save the files and commit them to your local repository. + +- Check the Status of Your Changes: + + ```shell + git status + ``` + + This will show the current state of your working directory, including staged, unstaged, and + untracked files. + +- Stage your changes for commit: + + ```shell + git add . + ``` + +- Commit Changes: Once your changes are staged, commit them with a meaningful message: + + ```shell + git commit -m "Added my new feature" + ``` + +- Pull Any Remote Changes: Before pushing, ensure your local repository is up-to-date with the + latest changes from the main branch: + + ```shell + git pull origin main + ``` + +- Push the changes to your forked repository: + + ```shell + git push origin + ``` + + Replace `` with the name of your branch. + +### 9. Create a Pull Request (PR) + +After pushing your changes, you can create a Pull Request to propose your changes to the original +repository. + +- Navigate to your forked repository on GitHub. +- Create a Pull Request: There should be an option to "Compare & pull request." Click it, review + your changes, and submit the pull request. + +Please refer to the [Pull Request Guide](/products/splashkit/04-pull-request/) for more information +on creating a pull request. + +### Contributing + +You should now have everything you need to begin contributing to you team. + +Be sure to check out the CONTRIBUTE.md for your team: + +- [Website](https://github.com/thoth-tech/splashkit.io-starlight/blob/main/CONTRIBUTE.md) +- [Online](https://github.com/thoth-tech/splashkit-online/blob/main/README.md) +- [Core](https://github.com/thoth-tech/splashkit-core/blob/develop/CONTRIBUTING.md) + +--- + +## Troubleshooting + +A lot can go wrong when working within repositories, the following guide contains a few +troubleshooting steps you can take to resolve the most common issues. + + + +### How to rebase your branch + + + +1. #### Fetch the Latest Changes from Upstream + + First, fetch the latest changes from the upstream repository to ensure your local copy is + up-to-date. + + ```shell + git fetch upstream + ``` + + This command fetches the latest branches and commits from the upstream repository without + modifying your local working directory. + +2. #### Check Out the Branch You Want to Rebase + + Make sure you’re on the branch that you want to rebase. Use the following command to switch to + your branch: + + ```shell + git checkout + ``` + + Replace `` with the name of your branch. + +3. #### Rebase Your Branch onto the Latest `main` (or another target branch) + + To rebase your branch onto the latest changes from the upstream `main` branch (or whatever branch + you want to base your changes on): + + ```shell + git rebase upstream/main + ``` + + This command applies your branch’s commits on top of the latest changes from the upstream `main` + branch. If you are rebasing onto a different branch (like `development`), replace `main` with the + appropriate branch name. + +4. #### Resolve Conflicts (if necessary) + + If there are any conflicts, Git will pause the rebase process and prompt you to resolve them. To + see which files are in conflict, run: + + ```shell + git status + ``` + + Manually resolve conflicts in your files, then add them to the staging area: + + ```shell + git add + ``` + + Once all conflicts are resolved, continue the rebase process: + + ```shell + git rebase --continue + ``` + + If you want to abort the rebase and return to the state before the rebase began: + + ```shell + git rebase --abort + ``` + +5. #### Push the Rebasing Changes to Your Fork + + Once the rebase is complete, you need to force push the changes to your fork, as the history has + been rewritten: + + ```shell + git push --force-with-lease origin + ``` + + The `--force-with-lease` option ensures that you don't accidentally overwrite someone else’s + changes in case they pushed while you were rebasing. + +6. #### Verify the Rebasing + + You can now verify that your branch is rebased and up to date with the upstream changes: + + ```shell + git log + ``` + + This will show the commit history, allowing you to confirm that your commits are on top of the + latest upstream changes. + + By following these steps, you will have successfully rebased your branch onto the latest `main` + branch (or whichever branch you're targeting) from the upstream repository. + + + +### How to resolve conflicts during a rebase or merge + +--- + + + +1. #### Identify Conflicts + + During a rebase or merge, if Git detects conflicts that it cannot resolve automatically, it will + pause the process and display a message indicating which files have conflicts. You can check the + status to identify which files are in conflict: + + ```shell + git status + ``` + + Git will show the files that are in conflict and need your attention. Conflicted files will + appear under the `both modified` section. + +2. #### Open the Conflicted Files + + Open the conflicted files in your preferred text editor (e.g., vscode). In the file, you will see + conflict markers that look like this: + + ```plaintext + <<<<<<< HEAD + // Code from your current branch + ======= + /* Code from the branch you are rebasing or merging */ + >>>>>>> branch-name + ``` + + - **`HEAD`** contains the changes from your current branch. + - The **`=======`** separates the two conflicting versions. + - The text below the `=======` represents changes from the branch you are merging or rebasing + onto. + +3. #### Manually Resolve the Conflicts + + To resolve the conflict, decide whether to keep your changes, the incoming changes, or a + combination of both. + - **Keep your changes**: Delete the lines between `=======` and `>>>>>>>` and remove the conflict + markers. + - **Keep the incoming changes**: Delete the lines between `<<<<<<< HEAD` and `=======` and remove + the conflict markers. + - **Combine both changes**: Modify the conflicting section to include both sets of changes, based + on your needs, and then remove the conflict markers. + + After resolving the conflicts, the file should look clean and without any conflict markers. + +4. #### Mark the Conflicts as Resolved + + Once you have resolved the conflicts in a file, you need to add the file to the staging area to + let Git know that the conflict has been resolved: + + ```shell + git add + ``` + + Repeat this for all the conflicted files. + +5. #### Continue the Rebase or Merge Process + + Once all conflicts are resolved and staged, you can continue the process. + - If you are in the middle of a **rebase**, continue with: + + ```shell + git rebase --continue + ``` + + - If you are in the middle of a **merge**, finalize the merge with: + + ```shell + git merge --continue + ``` + + If at any point you want to abort the rebase or merge due to complications, you can use the + following command: + + ```shell + git rebase --abort + ``` + + or + + ```shell + git merge --abort + ``` + +6. #### Push the Resolved Changes + + After resolving the conflicts and completing the rebase or merge, you will need to push the + changes back to your remote repository. If you performed a rebase, you will need to force-push + the branch since the commit history has been rewritten: + + ```shell + git push --force-with-lease origin + ``` + + If it was a merge, a normal push will suffice: + + ```shell + git push origin + ``` + +7. #### Verify Everything + + After pushing, you can verify that everything is resolved and the history is clean: + + ```shell + git log + ``` + + This will show the commit history, confirming that your conflicts were successfully resolved. + + diff --git a/src/content/docs/Products/SplashKit/04-pull-request.mdx b/src/content/docs/Products/SplashKit/04-pull-request.mdx new file mode 100644 index 00000000..6a2ac5c2 --- /dev/null +++ b/src/content/docs/Products/SplashKit/04-pull-request.mdx @@ -0,0 +1,219 @@ +--- +title: How to Create a Pull Request +description: This is a step-by-step guide on how to create a pull request for SplashKit. +sidebar: + label: "- Pull Request Guide" + order: 4 +--- + +import { Steps, Aside } from "@astrojs/starlight/components"; + +## How to Create a Pull Request + +This guide provides a step-by-step process for creating a pull request (PR) in the SplashKit +Starlight repository, PRs are the primary way to contribute changes to the project. By following +these steps, you can submit your own PRs and collaborate with other team members effectively. + + + +1. ### Check for Upstream Branches + + Before creating a pull request, it's important to ensure that your local repository is connected + to the correct upstream repository. The upstream repository is the original repository from which + your fork was created. You need this connection to pull in the latest changes from the main + project. + + To check if upstream branches are already linked to your local repository, run the following + command: + + ```shell + git remote -v + ``` + + This will display a list of remote repositories linked to your local repository. If the + `upstream` branch is not listed, you will need to add it in the next step. + +2. ### Add Upstream Branches (if not present) + + If the upstream branch is not already added, you can manually add it to your local repository. + This ensures you can fetch and merge changes from the main repository whenever necessary. + + To add the upstream branch, run the following command, replacing `` with the actual + name of the repository you're working with (e.g., `splashkit.io-starlight`). + + ```shell + git remote add upstream https://github.com/thoth-tech/.git + ``` + + #### Examples + - For the `splashkit.io-starlight` repository, the command will look like this: + + ```shell + git remote add upstream https://github.com/thoth-tech/splashkit.io-starlight.git + ``` + + - For the `splashkit-core` repository, the command will look like this: + + ```shell + git remote add upstream https://github.com/thoth-tech/splashkit-core.git + ``` + +3. ### Verify Upstream Branches + + After adding the upstream branch, verify that it has been added correctly by running the + following command again: + + ```shell + git remote -v + ``` + + You should see something like this: + + ```shell + origin https://github.com/YOUR-USERNAME/splashkit.io-starlight.git (fetch) + origin https://github.com/YOUR-USERNAME/splashkit.io-starlight.git (push) + upstream https://github.com/thoth-tech/splashkit.io-starlight.git (fetch) + upstream https://github.com/thoth-tech/splashkit.io-starlight.git (push) + ``` + + If the upstream branch is correctly listed, you are now ready to create your pull request. + + + +## Sync Your Fork (Optional but Recommended) + +Before creating a pull request, it's good practice to sync your local fork with the upstream +repository to ensure you're working with the latest version. Run the following commands to fetch and +merge the latest changes from the upstream repository: + +```shell +git fetch upstream +git checkout main +git merge upstream/main +``` + +This ensures that your pull request will not conflict with the latest updates made by others. + +## Creating a Pull Request + +There are two primary ways to create a pull request: using the GitHub website or the GitHub Pull +Requests extension in VSCode. + +### Using the GitHub Website + + + +1. #### Open GitHub to Review the Pull Request + + Head to GitHub and navigate to your forked repository. Once there, click on the **Pull requests** + tab at the top of the page, and then click the **New pull request** button. + + ![pull request](./images/pull-request-fig1.png) + +2. #### Select the Correct Repository and Branches + + Next, make sure you're comparing the correct branches: + - **Base Repository**: This should be set to `thoth-tech/repo_name` (the original + - repository you're contributing to). + - **Base Branch**: Select `main` as the branch to merge into. + + :::caution[Usage Examples Base Branch] + + For usage example tasks, the base branch (destination branch) needs to be changed to be + **usage-examples**. + + ::: + + The other dropdown should show your forked repository and the branch you want to merge from. + + ![pull request](./images/pull-request-fig2.png) + + Ensure these settings are correct to avoid submitting changes to the wrong branch or repository. + +3. #### Review Your Changes + + GitHub will display a comparison of the changes between your branch and the `main` branch of the + upstream repository. This is your opportunity to double-check the modifications you're proposing + to merge. + + Make sure everything looks correct before proceeding. + + :::caution[Usage Example Files] + + Ensure you have the files listed below added, with their names updated to the python signature of + the function you are demonstrating. + - For **standard** Usage Example PRs: + + ```plaintext + write_line-1-example-oop.cs + write_line-1-example-top-level.cs + write_line-1-example.cpp + write_line-1-example.py + write_line-1-example.png or .gif + write_line-1-example.txt + ``` + + ::: + +4. #### Add Pull Request Details + + When you create a pull request, you'll need to provide some additional information using a pull + request template. This helps reviewers understand the context of your changes. Make sure to: + - Provide a clear and descriptive title for your pull request. + - Fill out the required fields in the template, such as the purpose of the changes, testing + steps, and any additional notes. + + ![pull request](./images/pull-request-fig4.png) + + Be as detailed as possible. This makes it easier for reviewers to understand your contribution + and provide feedback. + +5. #### Submit the Pull Request + + Once you've filled out the template and confirmed your changes, click the **Create pull request** + button. Your pull request will now be submitted and visible to the repository maintainers and + reviewers for feedback. + + + +### Using the GitHub Pull Requests Extension in VSCode + +Alternatively, you can use the +[GitHub Pull Requests extension](https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github) +for VSCode. This allows you to create pull requests directly from your code editor. + + + +1. #### Open the Extension + + In VSCode, click on the GitHub Pull Requests icon in the sidebar. If you don't see it, you can + install it from the Extensions Marketplace. + +2. #### Create the Pull Request + + Click the **Create Pull Request** button, which will give you the option to select the branch you + want to merge from (your working branch) and the branch you want to merge into (usually `main`). + + Follow the same steps as on the GitHub website to review your changes, fill out the pull request + template, and submit it. + + ![pull request](./images/prinvscode.gif) + + + +## Next Steps After Submitting a Pull Request + +Once your pull request is submitted, move the associated Planner card to the **First Peer Review** +column in your project management tool, and share both the pull request and the Planner card with +your team or peer reviewers. Follow the information on the +[Planner Board Etiquette](/products/splashkit/07-planner-board) page to ensure a smooth review +process. + +Keep an eye out for feedback from the reviewer, and be prepared to make changes if necessary. + +### Useful Links + +- [Pull Request Template](/products/splashkit/05-pull-request-template): The template for creating a + pull request for SplashKit team. +- [Peer Review Guide](/products/splashkit/06-peer-review): The guide on how to perform a peer review + within the SplashKit team. diff --git a/src/content/docs/Products/SplashKit/05-pull-request-template.mdx b/src/content/docs/Products/SplashKit/05-pull-request-template.mdx new file mode 100644 index 00000000..d3ba99b4 --- /dev/null +++ b/src/content/docs/Products/SplashKit/05-pull-request-template.mdx @@ -0,0 +1,182 @@ +--- +title: Pull Request Template +description: This is a template for creating a pull request for SplashKit Website. +sidebar: + label: "- Pull Request Template" + order: 5 +--- + +import { Tabs, TabItem } from "@astrojs/starlight/components"; + +Most SplashKit repos have a default pull request template that you can use. Usage Example PRs will +need to use the template below. + +:::note + +The templates all include checklists of items that you need to complete before submitting your pull +request, some of which may not be relevant to your specific pull request. + +Please ensure that you complete all the relevant items before submitting your pull request. + +::: + +See the templates in the tabs below: + + + + + +Remove the default template in the pull request, and instead, use the following template: + +{/* prettier-ignore-start */} + +```markdown +# Description + +**Splashkit Function:** `function_name` + +**Overview of example functionality:** _Describe the example and how it demonstrates the function._ + +**Example Output:** _Add an image, or gif (or relevant demo file) of the example code running._ + +# Files Included + +- [ ] C++ code +- [ ] C# code (Top-Level statements) +- [ ] C# code (Object-Oriented Programming) +- [ ] Python code +- [ ] Relevant title for the example (.txt) +- [ ] Screenshot + +# Usage Example Checks (READ CAREFULLY) + +- [ ] Code uses Splashkit function above +- [ ] Code does not use non-Splashkit functions +- [ ] Code does not use extra function declarations or extra classes +- [ ] Code does not violate any of the Thoth Tech SplashKit Style Guide rules +- [ ] Simple, clear demonstration of the function +- [ ] Tested in Chrome and Firefox +``` + +{/* prettier-ignore-end */} + + + + + +{/* prettier-ignore-start */} + +```markdown +# Description + +_Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change._ + +## Type of change + +_Please delete options that are not relevant._ + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as + expected) +- [ ] Documentation (update or new) + +## How Has This Been Tested? + +_Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration._ + +## Testing Checklist + +- [ ] Tested in latest Chrome +- [ ] Tested in latest Firefox +- [ ] npm run build +- [ ] npm run preview + +## Checklist + +_Please delete options that are not relevant._ + +### If involving code + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings + +### If modified config files + +- [ ] I have checked the following files for changes: + - [ ] package.json + - [ ] astro.config.mjs + - [ ] netlify.toml + - [ ] docker-compose.yml + - [ ] custom.css + +## Folders and Files Added/Modified + +_Please list the folders and files added/modified with this pull request and delete options that are not relevant._ + +- Added: + - [ ] folder/folder + - [ ] folder/folder +- Modified: + - [ ] folder/file + - [ ] folder/file + +## Additional Notes + +_Please add any additional information that might be useful for the reviewers._ +``` + +{/* prettier-ignore-end */} + + + + + +{/* prettier-ignore-start */} + +```markdown +# Description + +_Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change._ + +Fixes # (issue) + +## Type of change + +_Please delete options that are not relevant._ + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as + expected) +- [ ] Documentation (update or new) + +## How Has This Been Tested? + +_Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration_ + +## Testing Checklist + +- [ ] Tested with sktest +- [ ] Tested with skunit_tests + +## Checklist + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] I have requested a review from ... on the Pull Request +``` + +{/* prettier-ignore-end */} + + + + +Once submitted, move the associated planner card to peer review and link the pull request. Follow +the [Planner Board Etiquette](/products/splashkit/07-planner-board) for more details on the process. diff --git a/src/content/docs/Products/SplashKit/06-peer-review.mdx b/src/content/docs/Products/SplashKit/06-peer-review.mdx new file mode 100644 index 00000000..e6f17e38 --- /dev/null +++ b/src/content/docs/Products/SplashKit/06-peer-review.mdx @@ -0,0 +1,382 @@ +--- +title: A Guide to Doing Peer Reviews +description: A guide on how to do a peer review within the SplashKit team. +sidebar: + label: "- Peer Review Guide" + order: 6 +--- + +import { Tabs, TabItem, Steps, Aside } from "@astrojs/starlight/components"; + + + + + +In SplashKit, peer reviews are an essential part of maintaining high-quality code. The Peer-Review +Checklist provided below is required for every pull request and ensures that all contributions meet +a consistent standard across the project. This checklist covers essential aspects like code quality, +functionality, and testing. + +However, we recognize that every feature or task is different, and it’s difficult to capture all +potential review points in a single checklist. That’s why we’ve also included a set of Peer-Review +Prompts. These prompts are not mandatory but serve as a resource to guide the peer-review +discussion. Since peer reviews should always be collaborative, these prompts help ensure that the +review process is conversational and thorough, encouraging reviewers to think critically and explore +areas that may not be immediately obvious. + +Remember, the goal of peer reviews is not only to verify the quality of the code but also to foster +a collaborative environment where we improve together. + + + +## How to Perform a Peer Review + +To maintain code quality and ensure smooth integration of new features, it’s essential to follow +these steps when reviewing a PR in the SplashKit Starlight repository. + + + +1. ### Check for Upstream Branches + + Start by verifying whether the upstream branches are already added to your local repository. This + is necessary to ensure that you can fetch PRs from the original repository for review. + + ```shell + git remote -v + ``` + + If the output does not show `upstream` linked to the main repository, you’ll need to add it in + the next step. + +2. ### Add Upstream Branches (if not present) + + If the upstream branch is missing, add it manually. Replace `` with the exact name of + the repository. + + ```shell + git remote add upstream https://github.com/thoth-tech/.git + ``` + + #### Example: Adding the `splashkit.io-starlight` Repository + + For the `splashkit.io-starlight` repository, the command will be: + + ```shell + git remote add upstream https://github.com/thoth-tech/splashkit.io-starlight.git + ``` + +3. ### Verify Upstream Branches + + Confirm that the upstream branch has been added correctly by running: + + ```shell + git remote -v + ``` + + You should see both `origin` (your fork) and `upstream` (the main project repository) listed. + +4. ### Pull the PR into a New Branch + + To review a PR, you will fetch it into a new local branch. Locate the ID/number of the PR on + GitHub, and use this number in the following command. Replace `ID` with the PR number and + `PR-branch-name` with a name that represents the PR purpose. + + ```shell + git fetch upstream pull/ID/head:PR-branch-name + ``` + + #### Example: Fetching PR #7 that Adds a "New Feature" + + ```shell + git fetch upstream pull/7/head:test-new-feature + ``` + +5. ### Checkout the New Branch + + Switch to the newly created branch to start reviewing the PR. + + ```shell + git checkout PR-branch-name + ``` + +6. ### Review the Code + + Now that you are on the PR branch, start by reviewing the code to check for: + - **Code Quality**: Confirm that the code aligns with the project’s coding standards and + guidelines. Look for clean, well-organised, and readable code. + - **Functionality**: Verify that the changes achieve the intended purpose and work as described. + - **Testing**: Check for the presence of adequate tests, including unit and integration tests + where necessary. + - **Documentation**: Ensure any new features or updates are documented, with clear comments for + any complex sections. + + Refer to the pull request template as you go through these checks to confirm that all required + fields are covered. + + ### SplashKit Pull Request Templates + + Use this checklist as a reference to ensure you’re covering all necessary areas in your review. + + + + + + ```markdown + # Description + + Please include a summary of the changes and the related issue. Please also include relevant + motivation and context. List any dependencies that are required for this change. + + ## Type of change + + - [ ] Bug fix (non-breaking change which fixes an issue) + - [ ] New feature (non-breaking change which adds functionality) + - [ ] Breaking change (fix or feature that would cause existing functionality to not work as + expected) + - [ ] Documentation (update or new) + + ## How Has This Been Tested? + + Please describe the tests that you ran to verify your changes. Provide instructions so we can + reproduce. Please also list any relevant details for your test configuration. + + - [ ] Tested in latest Chrome + - [ ] Tested in latest Firefox + - [ ] npm run build + - [ ] npm run preview + + ## Checklist + + ### If involving code + + - [ ] My code follows the style guidelines of this project + - [ ] I have performed a self-review of my own code + - [ ] I have commented my code in hard-to-understand areas + - [ ] I have made corresponding changes to the documentation + - [ ] My changes generate no new warnings + + ### If modified config files + + - [ ] I have checked the following files for changes: + - [ ] package.json + - [ ] astro.config.mjs + - [ ] netlify.toml + - [ ] docker-compose.yml + - [ ] custom.css + + ## Folders and Files Added/Modified + + Please list the folders and files added/modified with this pull request. + + - Added: + - [ ] folder/folder + - [ ] folder/folder + - Modified: + - [ ] folder/file + - [ ] folder/file + + ## Additional Notes + + Please add any additional information that might be useful for the reviewers. + ``` + + + + + + ```md + ## General Information + + - [ ] Type of Change: Clearly indicate the type of change (choose one): + - [ ] Bug fix + - [ ] New feature + - [ ] Breaking change + - [ ] Documentation update + + ## Code Quality + + - [ ] Repository: Is this Pull Request is made to the correct repository? (Thoth-Tech NOT + SplashKit) + - [ ] Readability: Is the code easy to read and follow? If not are there comments to help + understand the code? + - [ ] Maintainability: Can this code be easily maintained or extended in the future? + + ## Functionality + + - [ ] Correctness: Does the code meet the requirements of the task? + - [ ] Impact on Existing Functionality: Has the impact on existing functionality been considered + and tested? + + ## Testing + + - [ ] Test Coverage: Are unit tests provided for new or modified code? + - [ ] Test Results: Have all tests passed? + + ## Documentation + + - [ ] Documentation: Are both inline and applicable external documentation updated and clear? + + ## Pull Request Details + + - [ ] PR Description: Is the problem being solved clearly described? + - [ ] Checklist Completion: Have all relevant checklist items been reviewed and completed? + ``` + + + + + + #### Splashkit Review Prompts + - **Type of Change**: Does this Pull Request correctly identify the type of change (bug fix, new + feature, breaking change, or documentation update)? Is it aligned with the stated issue or + task? + + - **Code Readability**: Is the code structure clean and easy to follow? Could it benefit from + clearer variable names, additional comments, or better organization? Would this code be + understandable for a new developer joining the project? + + - **Maintainability**: How maintainable is the code? Is it modular and easy to extend in the + future? Does it avoid creating technical debt? Is the codebase as simple as possible while + still accomplishing the task? + + - **Code Simplicity**: Are there any overly complex or redundant sections in the code? Could they + be refactored for better simplicity or clarity? Does the code follow established design + patterns and best practices? + + - **Edge Cases**: Does the implementation consider potential edge cases? What could go wrong with + this code in unusual or unexpected scenarios? Are there any cases that haven’t been fully + addressed? + + - **Test Thoroughness**: Are all key scenarios (including edge cases and failure paths) covered + by tests? Could additional tests help ensure the reliability of the code? Has the code been + tested across different environments (e.g., multiple browsers or platforms)? + + - **Backward Compatibility**: Does this change break any existing functionality? If so, has + backward compatibility been handled or documented appropriately? Are there any warnings or + notes in the documentation regarding compatibility? + + - **Performance Considerations**: Could this code have a negative impact on performance? Have any + performance concerns been documented and tested? Could the code be optimized for better + efficiency without sacrificing readability? + + - **Security Concerns**: Could this change introduce security vulnerabilities, especially in + terms of input validation or sensitive data handling? Have security best practices been + followed? Does this code ensure proper user data handling? + + - **Dependencies**: Are the new dependencies truly necessary? Could they create conflicts or + issues down the line, particularly during upgrades or with other libraries in the project? Is + there a simpler way to achieve the same functionality without adding new dependencies? + + - **Documentation**: Is the documentation clear and complete for both internal developers and + external users? Could a new developer understand how to use or modify this feature from the + documentation provided? Does it cover any API or external interface changes? + +7. ### Test the Changes Locally + + After the code review, run the project locally to verify that the new feature or bug fix works as + expected. This can include: + - Running any test suites that come with the project. + - Manually checking if the new functionality behaves correctly and does not introduce any bugs. + - Ensuring the changes do not break other parts of the project. + +8. ### Provide Constructive Feedback + + After reviewing and testing, leave constructive feedback directly on the PR on GitHub. Highlight + both positive aspects and areas for improvement. + - Use specific comments on code lines or sections where changes are required. + - Make sure to explain why a change is needed to help the author learn and understand. + - Be courteous and professional, focusing on improving the code and maintaining high project + standards. + +9. ### Approve or Request Changes + + Once you’ve completed your review: + - **Approve** if everything meets the project’s standards and the code works as expected. + - **Request Changes** if the code requires adjustments before it can be merged. Clearly outline + the changes required. + + In both cases, document your decision and leave detailed notes to assist the author. + +10. ### Update Planner Board Status + + Following the [Planner Board Etiquette](/products/splashkit/07-planner-board), move the + associated Planner card to the next column based on the review outcome. If the PR is approved, + update the card’s status accordingly, and if you requested changes, mark it for revision. + + By following this guide, you’ll ensure a thorough and professional review process, helping + maintain the quality and reliability of the SplashKit Starlight project. + + + +### Review Guidelines for Specific File Types + +Different file types require different levels of attention during the review process. Here's what to +look for when reviewing each type of file: + +#### `.mdx` Files + +- **Content Accuracy**: Ensure that the content is clear and accurate. Double-check for any errors + in the documentation or guides. +- **Frontmatter**: Ensure the frontmatter (`title`, `description`, etc.) is correctly filled out. +- **Component Usage**: Verify that components such as `LinkCard`, `CardGrid`, or others are being + used appropriately within the `.mdx` files. + +#### `.css` Files + +- **Consistency**: Check that the styles align with the **Styling Guide** and maintain a consistent + use of variables (e.g., colours, fonts, spacing). +- **Accessibility**: Review for accessibility considerations, such as whether animations are + disabled for users who prefer reduced motion, and whether contrast ratios meet **WCAG 2.1 AA** + standards. +- **Naming Conventions**: Ensure that CSS class names follow a consistent naming pattern. + +#### `.jsx`/`.tsx` Files + +- **Functionality**: Make sure the interactive components (e.g., sliders, forms) work as expected + and meet the requirements of the task. +- **Performance**: Look for unnecessary re-renders or other performance concerns. +- **Code Style**: Ensure the code follows **React/JSX** best practices and any project-specific + linting rules. + +#### `.astro` Files + +- **Structure**: Ensure the page or component is well-structured and follows the **Astro standards** + for component and page creation. +- **Reusability**: Look for opportunities to refactor repetitive code into reusable components. + +--- + +## Useful Resources for Reviewers + +- **Starlight Documentation**: [Starlight Docs](https://starlight.astro.build/getting-started/) +- **Astro Documentation**: [Astro Docs](https://docs.astro.build/en/getting-started/) +- **WCAG 2.1 AA Guidelines**: [W3C Accessibility Standards](https://www.w3.org/WAI/WCAG21/quickref/) +- **MDN CSS Documentation**: [MDN CSS Guide](https://developer.mozilla.org/en-US/docs/Web/CSS) +- **React Documentation**: [React Official Docs](https://reactjs.org/docs/getting-started.html) +- **Usage Example Styling Guide**: + [Style Guide](/products/splashkit/documentation/splashkit-website/usage-examples/05-usage-example-style-guide) + +--- + +By following these guidelines, you'll ensure that the SplashKit website project maintains high +standards of code quality, performance, and accessibility. Remember, peer reviews are not only about +verifying the code but also about learning and improving together as a team. diff --git a/src/content/docs/Products/SplashKit/07-planner-board.mdx b/src/content/docs/Products/SplashKit/07-planner-board.mdx new file mode 100644 index 00000000..2b1954b9 --- /dev/null +++ b/src/content/docs/Products/SplashKit/07-planner-board.mdx @@ -0,0 +1,69 @@ +--- +title: Planner Board Ettiquete +description: Tips on planner board ettiquete. +sidebar: + label: "- Planner Board Ettiquete" + order: 7 +--- + +import { Steps } from "@astrojs/starlight/components"; + +## Proper Planner Board Etiquete + +The planner board is where all tasks are tracked. You can find tasks to claim and work on, or add +your own tasks that you will complete. Here are some guidelines to ensure smooth teamwork and +efficient use of the planner board. + + + +1. ### Claiming a Task + - **Commit to work:** Only claim a task if you are ready to work on it. + - **Unclaim if needed:** If you are unable to proceed with a task you've claimed, unclaim it so + others can take over. + - **Update status:** Once you claim a task, move it to the "Doing" column to signal that it's + being actively worked on. + +2. ### Adding a Task + - **Be clear and concise:** When adding a task, provide a meaningful title and a detailed + description. + - **Add checklists:** If the task involves multiple steps, include a checklist to outline them + clearly. + - **Use appropriate tags:** Tag the task with relevant labels to categorise it properly, such as + `Tutorials` if it's tutorial based, or `usage examples` if it's a usage example. + +3. ### Moving Tasks + - **Include relevant links:** When completing a task, attach links to the pull request (PR) and + any other relevant information. + - **Add a completion comment:** Leave a comment on the task card with the date you completed the + task. + - **Move to Peer Review:** After completing a task, move it to the "First Peer Review" column so + a team member can review it. + + > **Need help with pull requests?** + > Follow the [How to Create a Pull Request](/products/splashkit/04-pull-request) guide for + > detailed instructions. + +4. ### First Peer Review + - **Follow the review process:** Adhere to the steps outlined in the + [Peer Review Guide](/products/splashkit/06-peer-review). + - **Request changes if needed:** Provide feedback and request changes if required. + - **Approval:** Once the task meets the standards, approve it and the PR, then move the task to + the "Second Peer Review" column. + - **Leave a comment:** Add a comment with the date and confirmation that you've approved the + task. + +5. ### Second Peer Review + - **Follow similar steps:** Conduct the second peer review following the same guidelines as the + first. + - **Mentor Review:** After approving the PR, move it to the appropriate "Mentor Review" column. + - **Comment on approval:** As before, leave a comment with the date and a note indicating you've + approved the task for mentor review. + +6. ### Mentor Review + - **Final review:** The mentor will review the task and provide feedback. + - **Request changes:** If changes are needed, the mentor will request them and move the task back + to the "doing" column. + - **Approval:** Once the mentor approves the task, they will merge the PR and move the task to + the "completed" column. + + diff --git a/src/content/docs/Products/SplashKit/08-tips-and-tricks.mdx b/src/content/docs/Products/SplashKit/08-tips-and-tricks.mdx new file mode 100644 index 00000000..bfcc3e3b --- /dev/null +++ b/src/content/docs/Products/SplashKit/08-tips-and-tricks.mdx @@ -0,0 +1,114 @@ +--- +title: Tips and Tricks +description: Some tips and tricks that can improve user experience when contributing to SplashKit +sidebar: + label: "- Tips and Tricks" + order: 8 +--- + +import { Steps } from "@astrojs/starlight/components"; + +## General tips and tricks to make your life easier + +This guide will provide some useful tips and tricks that have been useful for me while working on +SplashKit. + +## Setting Git Bash terminal as default in VS Code + +By setting the terminal to Git Bash in VS Code you can compile and run your code without having to +open a new terminal and changing directory to your working directory. + +To do this: + + + +1. Open VS Code +2. Open a new terminal by pressing `` Ctrl + Shift + ` `` or Terminal tab -> new terminal + ![newterminal](./images/newterminal.png) +3. In the terminal, locate the small drop down arrow to the top right + ![dropdown](./images/dropdown.png) +4. In the drop down menu click "Select Default Profile" ![defaultprofile](images/defaultprofile.png) +5. You should see a drop down menu at the top of the window with a list of terminals where you can + select Git Bash or your terminal of choice. ![selectTerminal](images/selectterminal.png) +6. Select the terminal you would like as the default terminal within VS Code. I recommend Git Bash + + + +By following these steps, VS Code will automatically open an embedded terminal in your working +directory. No more alt-tabbing when building your SplashKit projects. + +## Setting up aliases in your Bash terminal + +Constantly typing the same lengthy commands can become tedious so by setting up aliases you can save +yourself a bunch of time. Whether it is shortened git commands or a compilation command for C++ +aliases are a great time saver. + +To create Aliases: + + + +1. Open a new terminal +2. Enter the command `nano ~/.bashrc` +3. In the text editor create the alias you want to use as such: + - `alias name='command'` + +4. Once you have added the aliases you wish to use, to exit the nano editor and save changes press + `Ctrl + X` +5. When prompted to save changes press `Y` and then `enter`. This should close the editor and take + you back to the terminal +6. Now to apply the changes enter the command `source ~/.bashrc` or restart your terminal + + + +Now when you enter your alias it should run the command you have set. Some Aliases I use are: + +| Aliases | Purpose | +| ------------------------------------------------- | --------------------------------------------------------------- | +| `alias gc='git checkout'` | allows gc branchname for easier branch switching | +| `alias gcm='git checkout main'` | quickly get to main branch | +| `alias skcompile='skm clang++ \*.cpp -o a && ./a` | quickly compiles and runs C++ SplashKit projects in one command | + +These are some example aliases but you can do pretty much anything. If there are any commands you +find yourself typing and think "Man this is tedious" just make a new alias for it! + +## Useful VS Code Extensions + +These are some helpful extensions that you can add to VS Code that may help with your workflow + +| Extension | Description | +| ------------------- | --------------------------------------------------------------------------- | +| C/C++ and C# | Syntax highlighting, IntelliSense, and debugging tools. | +| IntelliCode | Offers tools like line autocomplete and code suggestions | +| GitHub Pullrequests | Lets you work on existing pull requests in your local developer environment | +| GitLens | Better Git history and inline blame tools. | +| Prettier | Automatically Formats your code (doesn't work on all languages) | +| Code Spell Checker | Spell checks your code | + +## Enable format on save + +Enabling format on save will allow your formatting extensions like Intellisense or prettier to +format your code automatically when you save the document. + +To enable this: + + + +1. Go to File -> Preferences -> Settings or `Ctrl + ,` +2. In the search bar type "Format on save" +3. Enable the Format on save box ![FormatOnSave](images/FormatOnSave.png) + + + +## Common Git Commands + +| Command | Purpose | +| ------------------------ | ------------------------------------------------------------------------------------------------------------------------- | +| `git pull upstream main` | Pulls changes from the main branch of the upstream repo – great to run at the start of the day | +| `git clean -df` | Removes untracked files and directories - helpful if you forget a branch name | +| `git branch` | Lists all branches in your repo - good if you have forgotten the name of a branch | +| `git stash` | Temporarily stores uncommitted changes so you can switch branches or pull updates | +| `git checkout -b ` | Allows the creation and checkout of branch in 1 command | +| `git add .` | Stages all changed files in the current directory and below | +| `git status` | Shows staging area - Useful to see what will be committed | +| `git commit -m "message` | Commits and creates messages in 1 command | +| `git reset --hard` | Resets your working directory to last commit - Useful if you make some breaking changes and cannot fix. **use with care** | diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Bugs/car-race-clipping-bug.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Bugs/car-race-clipping-bug.md new file mode 100644 index 00000000..7585542b --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Bugs/car-race-clipping-bug.md @@ -0,0 +1,26 @@ +--- +title: Car Race Clipping with Non-Player Cars +--- + +## Bug Description + +While palying the game, multiple (non- player) cars can spawn in the same lane, and bnecomes +noticeable when the (non-player) cars have different movement speeds. The faster (non-player) car +will then phase through the slower car. + +## Testing Environment + +This bug was found while on a windows 10 laptop. + +## Reproduction + +Play Car Race untile you identify an instance of multiple non player cars sharing the same lane, +with one phasing through the other. + +## Expected Results + +Non-Player cars do not phase through or collide with eachother. + +## Actual Results + +Non-Player cars can phase through eachother if multiple cars spawn in the same lane. diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Bugs/dxball-game-controls-bug.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Bugs/dxball-game-controls-bug.md new file mode 100644 index 00000000..c32c1833 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Bugs/dxball-game-controls-bug.md @@ -0,0 +1,27 @@ +--- +title: DXBallGame Unable to Interact With User Interface Bug +--- + +## Bug Description + +While attempting to play DXBallGame, the user inteface does not respond to any key presses. The game +does react to keys 1, 8, 9, and 0, though these are likely intended to be used only for testing and +debugging purposes, as they move/skip the user to specific screens, which are still static screens, +as the user interface does not respond to any other key presses. + +## Testing Environment + +This bug was found while on a windows 10 laptop. + +## Reproduction + +Build and attempt to play the DXBallGame. The user interface will not respond to key presses. + +## Expected Results + +The user is able to properly inteact with the user interface through the use of their controls. + +## Actual Results + +The user is unable to interact with te user interface, as the game does not react to the key presses +of the user. diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Bugs/pingpong-paddle-collisions-bug.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Bugs/pingpong-paddle-collisions-bug.md new file mode 100644 index 00000000..70ab543c --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Bugs/pingpong-paddle-collisions-bug.md @@ -0,0 +1,31 @@ +--- +title: Pingpong Problematic Paddle and Puck Collisions Bug +--- + +## Bug Description + +The collision between the player paddles and the puck do not always work as intended and will +sometimes allow the puck to phase through the players paddle. This is most common when the puck +impacts the top or bottom of the players paddle, as the puck will phase/move through the entire +length of the paddle as if it were a pipe. The puck can also phase through the paddles when +impacting the side of the paddle, though i have not been able to identify any trend. + +## Testing Environment + +This bug was found while on a windows 10 laptop. + +## Reproduction + +Play a pingpong game and attempt to have the puck impact to top or bottom edge of the paddle. If the +collision is right, the puck should phase through the height of the paddle. It is also possible, +though much less common, for the puck to impact the side of the paddle and still phase through. + +## Expected Results + +The paddle acts as a wall that will redirect the puck such that the puck will bounce off the paddle +andtravel back in the direction it came from. + +## Actual Results + +The puck will intermittently phase through the paddle, while playing the collision sound on repeat +while the puck is still inside the paddle. diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Bugs/pingpong-playspace-collision-bug.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Bugs/pingpong-playspace-collision-bug.md new file mode 100644 index 00000000..6f04d90c --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Bugs/pingpong-playspace-collision-bug.md @@ -0,0 +1,26 @@ +--- +title: Pingpong Incorrect Play Area Boundary Bug +--- + +## Bug Description + +The collision boundary of the play area does not match the visal boundary for the play area. Player +1 is unable to access the last centimeter or so of their (visual) play space closest to their goal, +while player 2 is able to access the last centimeter of their play space closest to their goal. + +## Testing Environment + +This bug was found while on a windows 10 laptop. + +## Reproduction + +Play a pingpong game and have player 1 move towards their goal, as far as the game allows. Have +player 2 do the same and compare their visual distance to their goals. + +## Expected Results + +Both players are able to move within the last centimeter of play space closest to their goals. + +## Actual Results + +Only player two is able to move within the last centimeter of play space closest to their goal. diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Improvement Suggestions/below-the-surface-enemy-recolour.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Improvement Suggestions/below-the-surface-enemy-recolour.md new file mode 100644 index 00000000..b43bac91 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Improvement Suggestions/below-the-surface-enemy-recolour.md @@ -0,0 +1,21 @@ +--- +title: Below the Surface Enemy Colours +--- + +## Improvement Suggestion Description + +The colour scheme of the cockroach enemy should be changed to a brighter colour. The colour scheme +of the giant rat final boss should also be reconsidered. + +## Reasoning + +Currently, the cockroach emeny has a dark brown colour scheme, which makes it difficult to identify +because the background is a combination of a dark grey bottom half and a somewhat lighter shad of +grey for the top half. The dark brown colour of the cockroach has very little contrast with the dark +grey of the background and is thus extremely difficult to spot. + +While the lighter grey of the top half of the background does alleviate this issue slightly, the +cockroach is still very difficult to identify. + +The rat final boss suffers from a similar issue, as the vast majority of the boss is a dark brown, +though the teeth, tip of the tail, and hands/feet are a different, more easily identifed colour. diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Improvement Suggestions/runner-dash-enemy-movement-changes.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Improvement Suggestions/runner-dash-enemy-movement-changes.md new file mode 100644 index 00000000..5e96229e --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Improvement Suggestions/runner-dash-enemy-movement-changes.md @@ -0,0 +1,24 @@ +--- +title: Runner Dash Enemy Movement Changes +--- + +## Improvement Suggestion Description + +There should be a set of options regarding enemy movement, to allow for difficulty adjustment and +player choice. These options should include whether the enemy has 8 movement directions (north, +south east, west, and diagonals) or 4 (north, south east, and west), whether the enemy can skip its +turn, how the game decides when the enemy will skip its turn (random chance vs predictable pattern), +and enemy count. + +## Reasoning + +Currently, the enemy will always outmaneuver the player due to it having 8 movement directions +(north, south east, west, and diagonals), while the player only has 4 (north, south east, and west). +This means that the only way to survive is to flee the enemy in a straight line until the enemy +skips a turn. + +Only when the enemy skips a turn, can the player stop to plan their apprach for collecting gems. + +Reducing the enemy movement directions to match the players options can be a fix, but must be +implemened alongside other changes, because this change alone would mean that the enemy can nver +catch up to the player. diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Improvement Suggestions/venture-adventure-restart-level-option.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Improvement Suggestions/venture-adventure-restart-level-option.md new file mode 100644 index 00000000..1d2e2f03 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/Improvement Suggestions/venture-adventure-restart-level-option.md @@ -0,0 +1,19 @@ +--- +title: Venture Adventure Restart Level Option +--- + +## Improvement Suggestion Description + +Implement an option for the player to restart or exit the level. + +## Reasoning + +There should be an option of the player to restart or exit the level, as it is currently possible +for the player to move the boxes to locations that render it impossible for the player to collect +one or more gems. + +Since you must collect all gems to move onto the next level, the player is then unable to progress +to the next level. + +Currently, the only way to restart or exit the level while being in a situation where you are unable +to collect one or more gems is to exit out of the game entirely and reopen the program. diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/arcade-game-bug-testing-spike-plan.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/arcade-game-bug-testing-spike-plan.md new file mode 100644 index 00000000..db37513e --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/Bugs and Improvements/arcade-game-bug-testing-spike-plan.md @@ -0,0 +1,25 @@ +--- +title: Arcade Game Bug Testing Spike Plan +--- + +## Context + +The team needs information regarding the issues and areas for improvement regarding the arcade +games, as there is limited information regarding bugs and flaws in the various arcade games. + +## Goals/Deliverables + +The goals/deliverables are as follows + +1. Play the various arcade games and identify any bugs and flaws that should be improve on. +2. Write out the various bugs and improvements in written documents. + +Planned Start Date 20/11/2023 + +Deadline 24/11/2023 + +## Planning Notes + +1. Build and play the arcade games, one at a time. +2. When a bug or issue is encountered, attempt to gather information regarding the bug/issue. +3. Write down the details regarding the bugs/issues in separate documents. diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/games-contribution-guide.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/games-contribution-guide.md new file mode 100644 index 00000000..942c2bd3 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/games-contribution-guide.md @@ -0,0 +1,157 @@ +--- +title: Guide to Contribute a Game to the Arcade Machine +--- + +This guide takes you through the steps required for your game to be added into the arcade-machine +library. + +- [Coding](#coding) + - [Quit Request](#quit-request) + - [Window Size](#window-size) + - [Window Border](#window-border) +- [Controls](#controls) +- [Compiling](#compiling) +- [Artwork](#artwork) +- [Configuration](#configuration) +- [Content](#content) +- [Contributing](#contributing) + +## Coding + +To make the game accessible and controllable by the arcade machine, some additional code or changes +are required. + +### Quit Request + +Your game must be able to be exited using the escape key. This can be achieved by including the +following command in your main loop. + +```cpp +int main() +{ + while(!key_down(ESCAPE_KEY)) + { + // game play + } +} +``` + +### Window Size + +The window size of your game cannot exceed 1600 x 900, this is to allow your game to sit neatly +inside the arcade-machine itself. Similarly, there is a minimum window size of 640 x 480, to ensure +visibility for the user. + +The window size of your game cannot exceed 1600 x 900, this is to allow your game to sit neatly +inside the arcade-machine itself. Similarly, but mainly for aesthetic purposes, a minimum window +size of 640 x 480 is expected. + +### Window Border + +We ask that you remove the border before compiling your game. The Arcade Machine provides a more +immersive experience for the user if there is no border. To remove the border of your game window, +use SplashKit’s `window_toggle_border();` function after the `open_window()` function like so: + +```cpp +int main() +{ + open_window("my game", width, height); + window_toggle_border("my game"); +} +``` + +## Controls + +(TBA - Missing content) + +## Compiling + +Only Windows compiled games are supported at the moment. + +(TBA - Brief windows compilation explanation) + +## Artwork + +A preview of your game will be shown in the Arcade Machine games menu. + +(TBA - Please include an image of your game) + +This image must be sized as 600px x 540px so it will be displayed correctly in the games menu. The +supported formats are `png`, `jpg` and `bmp`. + +If you don’t have access to image editing software such as Adobe Illustrator/Photoshop, we suggest +you use a browser-based tool such as [resizeimage](https://resizeimage.net/) to resize, crop or +format a screenshot of your game. + +## Configuration + +Each game must have a configuration file containing information about the game. There is a +`config.txt` file located in the base directory of the repository, copy this file into the base +directory of your game file and fill it with your game information. It must match the example +configuration file shown below, but with your game information. + +![image](images/config-data.png) + +The configuration file **must** be in text (`.txt`) format, and it must be named `config.txt`. This +must be located in your games root directory, alongside your `program.cpp` (example below). + +![image](images/dir-breakdown.png) + +## Content + +(TBA - explanation of content requirements) + +## Contributing + +Congratulations! + +You have now completed all the steps required to have your game showcased on the Arcade Machine. + +To contribute your game, go to the +[Thoth Tech arcade-games repository](https://github.com/thoth-tech/arcade-games). Click the **Fork** +button at the top right of the screen and create a fork of this repository. + +![image](images/fork-repo.png) + +You will now have the arcade-games repository in your personal Git. + +![image](images/forked.png) + +On your local, navigate to a desired file path and clone this repository using the bash command: + +```shell +git clone https://github.com//arcade-games.git +``` + +Add your game to the directory and stage a commit to the remote repository: + +```shell +git add . +``` + +In your commit message, include your name and the name of the game: + +```shell +git commit -m ”Anthony George - Venture Adventure” +git push +``` + +You will now see your game in the remote fork. + +![image](images/commit.png) + +Now create a Pull request to have your game added to the arcade-machine. + +Click the **Pull requests** tab, then click **New pull request** button, then click **Create pull +request** + +![image](images/pull-request.png) + +Write a message for the Arcade Machine and hit **Create pull request** + +![image](images/pull-request-2.png) + +You will see that merging is blocked until a member of the Arcade-Machine team has reviewed your +game. We will be sure to get in contact with you once it has been approved! + +![image](images/review.png) diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/commit.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/commit.png new file mode 100644 index 00000000..b69e0a7a Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/commit.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/config-data.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/config-data.png new file mode 100644 index 00000000..d541717f Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/config-data.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/dir-breakdown.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/dir-breakdown.png new file mode 100644 index 00000000..4d3d4a66 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/dir-breakdown.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/fork-repo.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/fork-repo.png new file mode 100644 index 00000000..c69b3da4 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/fork-repo.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/forked.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/forked.png new file mode 100644 index 00000000..2b94b5cf Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/forked.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/pull-request-2.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/pull-request-2.png new file mode 100644 index 00000000..8545383a Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/pull-request-2.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/pull-request.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/pull-request.png new file mode 100644 index 00000000..b86480b4 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/pull-request.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/review.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/review.png new file mode 100644 index 00000000..71e2909d Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Games/images/review.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/01-adding-games-to-arcade-machine.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/01-adding-games-to-arcade-machine.md new file mode 100644 index 00000000..ecd090bc --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/01-adding-games-to-arcade-machine.md @@ -0,0 +1,187 @@ +--- +title: Adding Games to Arcade Machine +--- + +> many of these steps are eser to perform via the GUI all commands below are for CLI but can start +> the GUI by typing `startx` in the terminal + +## C++ Programs + +> If you have a complied arm program skip to step 7 + +1. Open Terminal +2. Change to the Games Source Folder in the home directory + + ``` + cd GameSource + ``` + +3. Create a new folder for your Game and change into the folder (Optional) + + ``` + mkdir mygame + cd mygame + ``` + +4. Git Clone your code into the directory + + ``` + git clone https://github.com/Thoth-Tech/MyGame.git + ``` + +5. Compile your game + + ``` + skm g++ program.cpp -o MyGame + ``` + +6. Test Your game is running correctly (optional) + + ``` + ./MyGame + ``` + +7. Copy your Complied game to the Games directory\ + + ``` + cp -r ~/GamesSource/MyGame ~/Games + ``` + +8. Create a Launch Script for your game + + ``` + nano ~Games/LaunchScript/MyGame.sh + ``` + + - Add the following + + ``` + #!/bin/bash + ~/Games/MyGame/MyGame + ``` + + - > Note: Some C++ programs may not run correctly when executed from a remote directory in which + > case make the script chagne to the program directory first + + ``` + #!/bin/bash + cd ~/Games/MyGame/ + ./MyGame + ``` + +- save by pressing `ctrl-o` and exit by pressing `ctrl-x` + +9. Make the script executable + +``` +sudo chmod +x MyGame.sh +``` + +10. Add the game to the emulation station game list. + +``` +nano ~/.emulationstation/gamelist/pc/gamelist.xml +``` + +11. Create new entire for your game. + +``` + + ./MyGame.sh + My Game + ~/Games/MyGame/TitleImage.png + +``` + +## C# Programs + +1. Open Terminal +2. Change to the Games Source Folder in the home directory + +``` +cd GameSource +``` + +3. Create a new folder for your Game and change into the folder (Optional) + +``` +mkdir mygame +cd mygame +``` + +4. Git Clone your code into the directory + +``` +git clone https://github.com/Thoth-Tech/MyGame.git +``` + +5. Compile your game (--sc complies it as standard alone) + + - you may need to change into a sub directory first + + > Compiling as a standalone program is presently required for C# games as dotnet and splashkit + > paths are not loaded on CLI boot, paths are presently loaded by bashrc which only run on + > interactive login shells. i.e. when you login to the desktop. + +``` +skm dotnet publish --sc +``` + +6. Copy libsplashkit.dll and libsplashkit.so to your published project directory + +``` +cp ~/.splaskkit/lib/linux/libsplashkit.dll ~/GamesSource/MyGame/bin/Debug/netcoreapp7.0/publish +cp ~/.splaskkit/lib/linux/libsplashkit.so ~/GamesSource/MyGame/bin/Debug/netcoreapp7.0/publish +``` + +7. Test Your game is running correctly (optional) + - change into the publish directory + - If you are using a Resources folder copy that into the Publish directory + `cp -r ~/GamesSource/MyGame/Resources ~/GamesSource/MyGame/bin/Debug/netcoreapp7.0/publish` + +``` +./MyGame +``` + +8. Copy your Complied game to the Games directory + +``` +cp -r ~/GamesSource/MyGame/bin/Debug/netcoreapp7.0/publish/ ~/Games/MyGame +``` + +9. Create a Launch Script for your game + +``` +nano ~Games/LaunchScript/MyGame.sh +``` + +- Add the following + +``` +#!/bin/bash +~/Games/MyGame/MyGame +``` + +- save by pressing `ctrl-o` and exit by pressing `ctrl-x` + +10. Make the script executable + +``` +sudo chmod +x MyGame.sh +``` + +11. Add the game to the emulation station game list. + +``` +nano ~/.emulationstation/gamelist/pc/gamelist.xml +``` + +12. Create new entire for your game. + +``` + + ./MyGame.sh + My Game + ~/Games/MyGame/TitleImage.png + +``` diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/02-setup-arcade-machine.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/02-setup-arcade-machine.md new file mode 100644 index 00000000..a176ff52 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/02-setup-arcade-machine.md @@ -0,0 +1,399 @@ +--- +title: How to setup Arcade Machine +--- + +## Existing Image + +Download current arcade Image from here (accessible to Thoth-Tech Team Members): + + +SHA256 Hash `31f0ea11c8492000d003108bf84afbb261ad6ee7c1be989f52a2b4add9d8821e` + +Use a program like [etcher](https://etcher.balena.io/) to create a bootable USB or SD card with the +Arcade image. + +1. Open etcher +2. Select image +3. select target USB or SD Card +4. Click FLASH + ![Image of the program etcher](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/ScreenShotEtcher.png) + + +These are the Credentials setup on the image + +1. Local User Name: `deakin` Password: `qwerty` +2. SSH Uses Local user name and password +3. SMB Share uses Name `deakin` password `deakin` +4. WiFi SSID `Arcade1` Password `GamesAreFun` + +## Manual Setup + +### Load OS + +1. Install Raspberry Pi OS + - See + [Raspberry Pi OS Installation Instructions](https://pimylifeup.com/raspberry-pi-boot-from-usb/). +2. Plug USB into PI or Arcade Machine and follow the setup wizard + - Current username and password are `deakin` and `qwerty` +3. Update all Software to the latestes version + +## Connect to eduroam + +Two changes need to be made to allow the Pi to access the eduroam network. One to network interfaces +and one to wpa_supplicant: + +1. Modify /etc/network/interfaces to bring the wlan0 interface up automatically, use DHCP and read + from the wpa_supplicant config + - From the console open the interfaces file: + + ```shell + sudo nano /etc/network/interfaces + ``` + + - Copy the following text to the **bottom** of the interfaces file + + ```plaintext + allow-hotplug wlan0 + iface wlan0 inet manual + wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf + iface wlan0 inet dhcp + ``` + + - Press Ctrl+X to exit and press **y** when prompted to save your changes + +2. Modify the wpa_supplicant with the custom eduroam config + - From the console open the wpa_supplicant config file: + + ```shell + sudo nano /etc/wpa_supplicant/wpa_supplicant.conf + ``` + + - Copy the following text into the wpa_supplicant file + + ```plaintext + ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev + update_config=1 + + network={ + ssid="eduroam" + priority=1 + proto=RSN + key_mgmt=WPA-EAP + pairwise=CCMP + auth_alg=OPEN + eap=PEAP + identity="YOURUSERNAME@deakin.edu.au" + password="YOURPASSWORD" + phase1="peaplabel=0" + phase2="auth=MSCHAPV2" + } + ``` + + - Replace **YOURUSERNAME** and **YOURPASSWORD** with the arcade machine's eduroam login + credentials. Ensure you include the domain I.E. "" + - Press Ctrl+X to exit and press **y** when prompted to save your changes. + +3. Reboot and test network connectivity + - Reboot the Raspberry Pi by issuing the below command: + + ```shell + sudo reboot + ``` + + - Test network connectivity by pinging an external site, for example Google's DNS: + + ```shell + ping 8.8.8.8 + ``` + +## Install Software + +### 1. Install SplashKit + +- Follow the [Linux (Ubuntu) Installation Guide](https://splashkit.io/installation/linux/) on the + SplashKit website. +- Primarly perform steps 1 and 2, VS code is optional unless you whish to adjust programming on the + PI directly. + +### 2. Install .NET (dotnet) + +- You can refer to [this page](https://learn.microsoft.com/en-us/dotnet/iot/deployment) but these + are the core commands: + 1. Run this install script + + ```shell + curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --channel STS + ``` + + 2. Add the following to the end of the file `~/.bashrc` with these commands + + ```shell + echo 'export DOTNET_ROOT=$HOME/.dotnet' >> ~/.bashrc + echo 'export PATH=$PATH:$HOME/.dotnet' >> ~/.bashrc + source ~/.bashrc + ``` + + 3. Verify the insalation with this command + + ```shell + dotnet --version + ``` + +### 3. Install Git + +- Run the following command + + ```shell + sudo apt update + sudo apt install git + ``` + +### 4. Install Emulation Station (using RetroPi) + +1. git clone retroPI setup + + ```shell + git clone --depth=1 https://github.com/RetroPie/RetroPie-Setup.git + ``` + +2. Run the setup script + + ```shell + cd RetroPie-Setup + sudo ./retropie_setup.sh + ``` + +3. Select manage packages + + ![RetorPie setup Main scree](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/ManagePackage.png) + +4. Select core + + ![RetorPie setup Manage Packages scree](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/CorePackage.png) + +5. Select emulationstation + + ![RetorPie setup Manage Packages scree](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/EmulationStation.png) + +6. Exit retroPie setup +7. Create Emulation Station es_systems.cfg file + + ```shell + nano ~/.emulationstation/es_systems.cfg + ``` + +8. Add the following configuration code to the `es_systems.cfg` file: Or, you can download a copy + from here: + Click + to Download + + ```xml + + + + + + + + pc + + + PC + + + /home/deakin/Games/LaunchScripts + + + .exe .sh + + + %ROM% + + + PC + + + N64 + + + ``` + +9. Create a folder for the games + + ```shell + mkdir ~/Games + ``` + +10. Create a folder for the launch scripts + + ```shell + mkdir ~/Games/LaunchScripts + ``` + +## Configure Software + +### Configure Emulation Station + +1. Start Emulation Station enter the following command: + + ```shell + emulationstation + ``` + +2. First time setup you will need to configure the controller + 1. Hold Down any key to start + + ![EmulationStation Configure Input Screen](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/ConfigureInput.png) + + 2. Press any key to configure input + + Recommend the Following for the Arcade Machine the rest can be skipped + - up = up arrow + - down = down arrow + - left = left arrow + - right = right arrow + - start = escape + - select = enter + - A = left control + - B = left alt + + ![Input Selection Screen](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/SetKeys.png) + + 3. It will note a hotkey was not selected say yes to accept using select + +3. Press Escape to bring up the menu +4. Select UI Settings +5. Scroll down to start on system and set it to PC + + ![UI Settings Screen](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/StartOnSystem.png) + +6. Go back and Quit Emulation Station + +### Configure Start CLI on Boot and Network Manager + +1. Launch Rasberry Pi Configuration + + ```shell + sudo raspi-config + ``` + +2. Select System Options + + ![Rasberry Pi Configuration Screen](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/SystemOptions.png) + +3. Select Boot / Auto Login + + ![Rasberry Pi system Option Screen](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/BootAutoLogin.png) + +4. Select Console Autologin + + ![Rasberry Pi Boot Option Screen](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/ConsoleAutoLogin.png) + +5. Return to main menu +6. Select Advanced Options + + ![Rasberry Pi Configuration Screen](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/AdvancedOptions.png) + +7. Select Network Config + + ![Rasberry Pi Configuration Screen](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/NetworkConfig.png) + +8. Select Network Manager + + ![Rasberry Pi Configuration Screen](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/NetworkManager.png) + +9. Select OK +10. Select Interface Options + + ![Rasberry Pi Configuration Screen with interface options selected](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/InterfaceOptions.png) + +11. Select SSH + + ![Rasberry Pi Configuration Screen with SSH selected](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/EnableSSH.png) + +12. Select Yes + + ![Rasberry Pi Configuration Screen with Yes selected](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/SSHEnableScreen.png) + +13. Select Ok and Finshed to exit Rasberry Pi Configuration +14. You can reboot now or later + +### Setup WiFi Access Point (Optional) + +This will set the PI up as a WiFi Access Point so you can SSH in when the USB ports are not +accessible. + +[Basic Guide Availble Here](https://gist.github.com/narate/d3f001c97e1c981a59f94cd76f041140) + +Enter the following commands, the SSID is set to Arcade1 - change the number for the machine you are +working on. + +```shell +nmcli con add type wifi ifname wlan0 con-name Hostspot autoconnect yes ssid Arcade1 +nmcli con modify Hostspot 802-11-wireless.mode ap 802-11-wireless.band bg ipv4.method shared +nmcli con modify Hostspot wifi-sec.key-mgmt wpa-psk +nmcli con modify Hostspot wifi-sec.psk "GamesAreFun" +nmcli con up Hostspot +``` + +The Pi will now be broadcasting a WiFi network called Arcade1 with the password GamesAreFun + +- The IP address of the Pi will be 10.42.0.1/24 this current setup does not allow for DHCP so any +- connecting client will need to manually set an IP address in use the following settings: + + IP Address: 10.42.0.2 Subnet Mask: 255.255.255.0 Gateway: 10.42.0.1 + +### Set Emulation Station as the Default Shell + +1. Change to the Retro Pi Setup Folder + + ```shell + cd ~/RetroPie-Setup + ``` + +2. Run the Retro Pi Setup Script + + ```shell + sudo ./retropie_setup.sh + ``` + +3. Select Configuration / Tools + + ![RetroPi Config Screen with Configuration / Tools selected](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/RetroPiConfigTools.png) + +4. Select Autostart + + ![RetroPi Config Screen with Autostart selected](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/RetroPiConfigAutostart.png) + +5. Select Start Emulation Station at boot + + ![RetroPi Config Screen with Start Emulation Station at boot selected](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/RetroPiConfigStartEmulationStation.png) + +6. Select Ok +7. Select Finish +8. Select Perform Reboot + +## Installing the Splashkit Theme + +1. Download the Themes folder located at: docs/Splashkit/Applications/Arcade Machines/Arcade Machine + Setup/Files + +2. Copy the Themes folder into your .emulationstation folder, located at ~/.emulationstation on the + Raspberry Pi or at %HOMEPATH%/.emulationstation on windows devices. + +3. In the es_systems.cfg file, located in the file paths mentioned in step 2, you will need to + change the XML code for the theme to be "sk." + + ![es_systems.cfg file open showing where to change the theme](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/SystemThemeSetup.jpg) + +4. Launch EmulationStation, open the start menu, and under UI settings change Theme set to + "Splashkit." + + ![Theme Set selection in EmulationStation](/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Images/SettingsThemeSelection.png) diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/03-create-pi-image.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/03-create-pi-image.md new file mode 100644 index 00000000..4a873719 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/03-create-pi-image.md @@ -0,0 +1,83 @@ +--- +title: Creating Raspberry Pi Image +--- + +This document will outline how to create a compressed disk image of the Rasberry Pi that can then be +burnt to new SD cards using the [Raspberry Pi imager](https://www.raspberrypi.com/software/) or a +program like [etcher](https://etcher.balena.io/). Using this process, you can make new Gold Images +and backups of the running software for the Arcade Machines. This process uses a script called +PiShirnk + +The process was derived from this article: + + +### Current Compressed Gold Image + + + +The current Compressed Gold Image is on the Thoth Tech Teams SharePoint Site. This is persistent but +only accessible to Thoth Tech team members. + +## Requirements + +- USB Key larger capacity than current SD Card in Pi +- Raspberry Pi with Arcade image + +Note it is possible to change the partition sizes on the Pi to use a smaller USB key, but I have not +tested that process, and it is beyond the scope of this document. If you need that process, please +refer to the Toms Hardware article above, and if successful, please update this document with the +additional optional process. + +## Create Disk Image + +1. Format USB key + - Format the USB Key as either NTFS (if using Windows) or EXT4 (if using Linux); I'm not sure + what is best for Mac OS. (This Wiki How Article explains how to format a key on Windows + ) +1. Connect the USB key to the Pi + + ![Image of Pi with a USB key](images/PI_USB.jpg) + +1. On the Pi, open a terminal and run the following to install pishrink.sh and move it to + /usr/local/bin + + ``` + wget https://raw.githubusercontent.com/Drewsif/PiShrink/master/pishrink.sh + sudo chmod +x pishrink.sh + sudo mv pishrink.sh /usr/local/bin + ``` + +1. Check the mount point of the USB Key with this command + + ``` + lsblk + ``` + + ![Screen shot of the output of the lsblk command](images/Command_lsblk.png) + + You should be able to see the mount point for the USB ours has been mounted at + `/media/deakin/Spare` (Spare is the volume name set during formatting) + +1. Copy the current SD card to the USB as an image file, i.e. my command was + `sudo dd if=/dev/mmcblk0 of=/media/deakin/Spare/ArcadeImage-19.08.2023.img bs=1M` Set the + filename as you see fit but if updating the gold image suggest using a date or version number. + + ``` + sudo dd if=/dev/mmcblk0 of=[mount point]/myimg.img bs=1M + ``` + +1. Move to the USB root directory, i.e. my command `cd /media/deakin/Spare` + + ``` + cd cd /media/pi/[volume] + ``` + +1. Run pishrink with -z option; this will zip the image with gzip. + + ``` + sudo pishrink.sh -z ArcadeImage-19.08.2023.img + ``` + +You should now have a compressed image file, i.e. `ArcadeImage-19.08.2023.img.gz` refer to +[Setup Arcade Machine](/products/splashkit/documentation/arcade-machine/arcade-machine-setup/02-setup-arcade-machine) +for instructions on burning the image to a new SD card or USB. diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/AdvancedOptions.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/AdvancedOptions.png new file mode 100644 index 00000000..f18b0ceb Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/AdvancedOptions.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ArcadeControls.jpg b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ArcadeControls.jpg new file mode 100644 index 00000000..90d3f6b7 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ArcadeControls.jpg differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/BootAutoLogin.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/BootAutoLogin.png new file mode 100644 index 00000000..8522a8cf Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/BootAutoLogin.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/Command_lsblk.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/Command_lsblk.png new file mode 100644 index 00000000..ca31e838 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/Command_lsblk.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ConfigureInput.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ConfigureInput.png new file mode 100644 index 00000000..daf80c1b Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ConfigureInput.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ConsoleAutologin.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ConsoleAutologin.png new file mode 100644 index 00000000..1b3fba78 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ConsoleAutologin.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/CorePackage.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/CorePackage.png new file mode 100644 index 00000000..c624986d Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/CorePackage.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/EmulationStation.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/EmulationStation.png new file mode 100644 index 00000000..80b3261a Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/EmulationStation.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/EnableSSH.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/EnableSSH.png new file mode 100644 index 00000000..86edf5b5 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/EnableSSH.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/InterfaceOptions.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/InterfaceOptions.png new file mode 100644 index 00000000..55716170 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/InterfaceOptions.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ManagePackage.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ManagePackage.png new file mode 100644 index 00000000..57e56029 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ManagePackage.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/NetworkConfig.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/NetworkConfig.png new file mode 100644 index 00000000..7c167b2c Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/NetworkConfig.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/NetworkManager.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/NetworkManager.png new file mode 100644 index 00000000..99fbf4fa Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/NetworkManager.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/PI_USB.jpg b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/PI_USB.jpg new file mode 100644 index 00000000..a7ecbd2d Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/PI_USB.jpg differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/RetroPiConfigAutostart.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/RetroPiConfigAutostart.png new file mode 100644 index 00000000..23e6720c Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/RetroPiConfigAutostart.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/RetroPiConfigStartEmulationStation.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/RetroPiConfigStartEmulationStation.png new file mode 100644 index 00000000..f6921629 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/RetroPiConfigStartEmulationStation.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/RetroPiConfigTools.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/RetroPiConfigTools.png new file mode 100644 index 00000000..47ecf1cb Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/RetroPiConfigTools.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SSHEnableScreen.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SSHEnableScreen.png new file mode 100644 index 00000000..a369e69f Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SSHEnableScreen.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ScreenShotEtcher.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ScreenShotEtcher.png new file mode 100644 index 00000000..c0131cd4 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/ScreenShotEtcher.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SetKeys.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SetKeys.png new file mode 100644 index 00000000..67241ee6 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SetKeys.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SettingsThemeSelection.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SettingsThemeSelection.png new file mode 100644 index 00000000..7fee2492 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SettingsThemeSelection.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/StartOnSystem.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/StartOnSystem.png new file mode 100644 index 00000000..67d3e4f3 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/StartOnSystem.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SystemOptions.png b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SystemOptions.png new file mode 100644 index 00000000..a7f11771 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SystemOptions.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SystemThemeSetup.jpg b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SystemThemeSetup.jpg new file mode 100644 index 00000000..c6380630 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Arcade Machine Setup/images/SystemThemeSetup.jpg differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Research and Findings/01-emulation-station-script-research.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Research and Findings/01-emulation-station-script-research.md new file mode 100644 index 00000000..f102cd5f --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Research and Findings/01-emulation-station-script-research.md @@ -0,0 +1,52 @@ +--- +title: Emulation Station Script Research +--- + +## How to Setup A Script + +1. In your ~homepath/.emulationstation folder create a new folder named scripts + +2. within the scripts folder, using the table from + (Under scripting > 2. Event + directories), create a new folder with the name of the event you want the script to run for. + +3. Within the event folder, you can place Shell Script files that you want to run on the event. + +### Notes + +The scripts will need testing on either a raspberry pi or a Linux pc, as windows doesn't natively +support running shell scripts. + +As shown by the table on , depending on +the event, certain bits of data get passed along to the script. + +## Ten Minute Idle Timer + +For creating the idle timer you will most likely need to have a script running from the game-start +event, which passes down the %rom_path%, %rom_name%, and %game_name% arguments. The arcade machine +isn't using emulators testing would need to see which of these arguments can call a close on the +opened game. + +### Test Hello World Script + +Below is a test script that will create a file containing the words HELLO WORLD, the `#!/bin/bash` +line, known as a "shebang", gives the script elevated permissions. + +```shell +#!/bin/bash + +FILE="YOUR-FILEPATH-HERE" +echo before +echo HELLO WORLD >> "$FILE" +echo "$\*" >> "$FILE" +echo after +``` + +## Useful Links + + +This is a stack exchange question looking into detecting inputs on a linux/unix device. The answers +talk about the file paths for devices and gives a sample code using C. + + A forum post asking +about some issues regarding a game-start script. diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Research and Findings/02-add-second-controller-findings.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Research and Findings/02-add-second-controller-findings.md new file mode 100644 index 00000000..84f8d125 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Research and Findings/02-add-second-controller-findings.md @@ -0,0 +1,137 @@ +--- +title: Emulation Station - Allow both users to control emulationstation menus +--- + +## Background + +The arcade machine uses a bespoke controller for input. The controller hardware uses JoyToKey to +remap joypad inputs to a emulated keyboard. Both players have separate physical controls, but the +arcade sees this as a single unified keyboard. + +The user interface uses a program called emulationstation, which is in turn integrated into +RetroPie. + +This has the effect of only allowing a single user to control the menu outside of games (in +emulationstation). An enhancement request has been raised to add functionality where both players +can control menus. + +### Findings + +- Linux is only able to interact with a single keyboard. It is not possible to have two hardware + keyboards, and use both for input. + +- The desired functionality **is** possible with two discrete controllers. If the user connects and + configures two controllers to the arcade machine, both players will be able to interact with menus + independent of each other. This has been tested locally with me using a PlayStation 4 & + PlayStation 5 controller connected via USB. + - It is also possible to use one keyboard and one controller, and have each device represent input + for each player + +- RetroPie & EmulationStation handle input differently. + - Emulationstation configs do not discriminate between player 1 and player 2 (or any number of + players). Rather the config is just a series of buttons mapped to inputs. + - Config file: `/home/$username/.emulationstation/es_input.cfg` + + - RetroPie **does** discriminate between players. Inputs are named player1_up, player1_down etc. + - Creating additional lines in the config file for player2 controls does not affect + Emulationstation I.E. + - `player1_button_up="a", player2_button_up="z"` + - Config file: `/opt/retropie/configs/all/retroarch.cfg` + +- Modifying the Retropie config file directly does not change the Emulationstation controls. +- Modifying the EmulationStation config directly breaks input when the program is next started. + - This can be fixed by resetting the config + - Running the script declared in this config file does not appear to update the config either + - Shell script path: + `/opt/retropie/supplementary/emulationstation/scripts/inputconfiguration.sh` + - In order to actually update the config it seems necessary to use the input confg wizard in the + GUI. + +### Emulationstation input config file + +Emulationstation holds configuration settings for user input devices in a file located here: +`/home/$username/.emulationstation/es_input.cfg`. This is an XML formatted file. Each device type +creates it's own "inputConfig" section. The `id` refers to the decimal +[ASCII character code](https://www.ascii-code.com/). E.G lowercase "a" has a decimal value of 97 +(0x61). + +An example config file looks like this: + +```xml + + + + /opt/retropie/supplementary/emulationstation/scripts/inputconfiguration.sh + + + + + + + + + + + + + + +``` + +The section for controller iput looks like this: + +```xml + + + + +``` + +Adding multiple "inputConfig" sections for keyboards does not work. I.E: + +```xml + + + + + + +``` + +### Outcome + +It does not appear to be possible to implement this functionality given the current state of +constituent systems & hardware limitations of the Linux kernel without significantly reworking other +aspects of the Arcade Machine's hardware & software configuration. + +#### Main limiting factors are + +- Inability to address two keyboards concurrently - This is extremely unlikely to change, and very + difficult to work around +- Limitations in ability to modify EmulationStation configs to suit arcade machine needs +- System configuration is brittle - manually editing many of RetroPie (or constituent) configs will + silently break functionality +- Existing dependence on handling Arcade Machine input as an emulated keyboard + +### Recommendations + +I would assess this enhancement as "low priority" in the grander scheme of the project. To be clear, +dual user input is currently supported within SplashKit games themselves. This limitation only +affects the EmulationStation overlay. Which essentially means that only player 1 has control over +this menu. + +If this is deemed to be a requirement then I would recommend removing JoyToKey from the arcade +machine and handling input directly as a joypad. This would also require bifurcating the two joypads +into two discrete devices. As mentioned above, this would require a rework of several other systems +to accommodate this change. In addition many SplashKit games would need to be reworked to handle +joypad input, as most currently use Keyboard input only. + +### Links + +[Thoth-Tech doc on Arcade Machine setup](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Arcade%20Machines/Arcade%20Machine%20Setup/Setup%20Arcade%20Machine.md) + +[RetroPie controller documentation](https://retropie.org.uk/docs/RetroArch-Configuration/#hardcoded-configurations) + +[Configuring controls in Retropie](https://retropie.org.uk/docs/Controller-Configuration/) + +[Example EmulationStation es_input_cfg file](https://gist.github.com/neolao/e4d5960c4ee1e8ed5291) diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Research and Findings/03-below-the-surface-game-test-report-20Aug2023.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Research and Findings/03-below-the-surface-game-test-report-20Aug2023.md new file mode 100644 index 00000000..d8cff8a3 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Research and Findings/03-below-the-surface-game-test-report-20Aug2023.md @@ -0,0 +1,88 @@ +--- +title: Below The Surface Game Test Report +author: Wenxuan Song +--- + +Date of Testing: [20/08/2023] + +## Executive Summary + +This test report outlines findings from testing the arcade game "Below the Surface." The game +exhibited a critical issue when played with two players, where the movement of one player caused the +screen to move, leading to the other player's death when they moved off-screen. Additionally, a +suggestion was made to restrict player movements when they are positioned beyond the screen's +boundaries. The report discusses the problem's impact, provides reproduction steps, and suggests +potential solutions. + +## Testing Goals + +- The primary objective of testing was to assess the gameplay experience of the arcade game "Below + the Surface" when played with two players simultaneously. +- The focus was on evaluating the game's screen movement behaviour on the arcade machine and + identifying any issues that arise as a result. + +## Testing Environment + +- Testing Tool: Arcade machine + +## Test Cases + +The following test cases were executed during the testing phase: + +### Test Case 1: 2 players movement + +- Description: Play in pairs to experience the effects of player movements in 2 players mode + +1. Launch the game on the arcade machine with two players. +2. Begin gameplay, with both players moving in different directions. +3. Observe what happens when two players move on the screen at the same time + +## Bugs/Issues + +### Issue: Screen Movement Causing Player Deaths + +- Description: When playing with two players, the movement of one player causes the screen to shift, + resulting in the other player's death if they move off-screen. + +1. Launch the game on the arcade machine with two players. +2. Begin gameplay, with both players moving in different directions. +3. Observe the screen movement causing one player to be left off-screen and subsequently dying. + +**Impact:** The issue severely hampers multiplayer gameplay, rendering it frustrating and +unplayable. + +**Proposed Solution:** The movement of the screen needs to be adjusted, and deaths should not occur +because of the movement of two players when playing. This ensures the core gameplay and fun of the +game. + +- Improved Dual-Screen Mode: Modify the game's screen behaviour to split into two distinct views + when two players move in opposite directions. This would allow each player to move independently + without affecting the other's gameplay. However, this solution may require significant technical + adjustments and testing. +- Player Respawning Mechanism: Implement a respawning mechanism that triggers when a player moves + off-screen. Upon detection of off-screen movement, the player would respawn at a safe location, + ensuring they are not unfairly penalized for screen movement. +- Restrict Movement Beyond Screen Boundaries: Restrict player movements when they are positioned + beyond the screen's boundaries. This would prevent screen movement caused by one player's actions + and allow both players to remain on the same screen. + +## Suggestions and Feedback + +To address this issue and provide a seamless multiplayer experience, the following potential +solutions are recommended: + +- When the player reaches full health, he cannot pick up heart-shaped items to increase health, but + can instead increase score. +- The colour of the cockroach shaped monster is too dim, and the dark background is easy to cause + the player to lose sight of it. +- The jump rate is too fast, making the player's countermeasures against the monsters too difficult. + +## Conclusion + +The critical issue of screen movement affecting multiplayer gameplay in the arcade game "Below the +Surface" significantly detracts from the intended cooperative experience. The recommended solutions +aim to resolve this issue and restore the game's multiplayer functionality. Implementing these +solutions, along with the provided suggestions, will greatly enhance the overall enjoyment and +engagement of players. + +--- diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Research and Findings/04-asteroids-game-test-report-20Aug2023.md b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Research and Findings/04-asteroids-game-test-report-20Aug2023.md new file mode 100644 index 00000000..56acfc83 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/Research and Findings/04-asteroids-game-test-report-20Aug2023.md @@ -0,0 +1,106 @@ +--- +title: Asteroids Game Test Report +author: Wenxuan Song +--- + +Date of Testing: [20/08/2023] + +## Executive Summary + +This report outlines the findings from the testing of the Asteroids. The testing process aimed to +identify and address potential issues affecting gameplay, graphics, performance, user interface, and +overall user experience. One significant issue identified is the excessive speed of meteorites, +which has a notable impact on the game's difficulty and player engagement. + +## Testing Goals + +- Evaluate gameplay mechanics and balance. +- Assess graphics quality and performance. +- Test user interface design and intuitiveness. +- Identify and report bugs and usability issues. + +## Testing Environment + +- Testing Tools: Arcade machine + +## Test Cases + +The following test cases were executed during the testing phase: + +### Test Case 1: Meteorite Speed + +- Description: Evaluate the speed of meteorites during gameplay. +- Steps to Reproduce: + +1. Launch the game. +2. Start a new game session. +3. Observe the speed at which meteorites move across the screen. + +- Expected Result: Meteorite speed is challenging yet manageable, allowing players to navigate + effectively. +- Actual Result: Meteorites move at an excessive speed, making it difficult for players to react and + avoid collisions. + +## Bugs/Issues + +### Issue: Excessive Meteorite Speed + +- Description: During gameplay, it was observed that the meteorites move at an excessively high + speed, leading to an increase in game difficulty beyond the intended level. +- Steps to Reproduce: + +1. Launch the game. +2. Start a new game session. +3. Observe the speed at which meteorites move across the screen. + +- Notes: The rapid movement of meteorites makes it challenging for players to react and navigate + effectively, impacting the overall gameplay experience. This issue is particularly noticeable on + higher levels, where it becomes nearly impossible to avoid collisions due to the meteorites' + speed. + +**Proposed Solution:** The meteorite speed needs to be adjusted to provide players with a fair and +engaging gameplay experience. By reducing the speed to a more manageable level, players will have +better control over their ship's movements and can effectively strategize to avoid collisions. This +adjustment will maintain a challenging aspect while not compromising the core enjoyment of the game. + +**Testing Required:** + +1. Implement adjustments to meteorite speed. +2. Conduct thorough playtesting to ensure the new speed level provides an appropriate balance of + challenge and enjoyment. +3. Gather player feedback to validate the changes and assess whether the meteorite movement feels + more balanced. + +**Impact:** This issue significantly affects the game's playability and enjoyment. Addressing the +meteorite speed will enhance the overall experience and encourage players to engage with the game +for longer periods. Failure to address this issue could result in player frustration, leading to +reduced player retention and potential negative reviews. + +## Performance Evaluation + +Performance evaluation revealed no significant issues. The game maintained a stable frame rate even +during intense gameplay moments, and load times were within acceptable limits. + +## User Experience (UX) Evaluation + +The overall user experience was positive. However, the excessive meteorite speed issue has +negatively impacted the user experience by making the game overly challenging. + +## Suggestions and Feedback + +- Address the excessive meteorite speed issue to enhance gameplay balance. +- Visual Feedback: Provide clearer visual cues when the player's ship is hit by a meteorite. This + can include visual effects, screen shakes, or sound effects to enhance the impact and improve + feedback to the player. +- Power-ups and Abilities: Consider introducing power-ups or special abilities that the player can + acquire during gameplay. These could include temporary shields, slow motion, or increased + firepower, adding variety and strategic depth to the gameplay. + +## Conclusion + +The testing process has revealed several strengths of the Asteroids, including its intuitive +controls and engaging gameplay. However, the issue of excessive meteorite speed poses a significant +challenge to player enjoyment and needs to be promptly addressed. By implementing the proposed +solution, the game can provide a more balanced and enjoyable experience for players. + +--- diff --git a/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/index.mdx b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/index.mdx new file mode 100644 index 00000000..8abf246a --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Arcade Machine/index.mdx @@ -0,0 +1,33 @@ +--- +title: Arcade Machines and Arcade Games +sidebar: + label: Overview + order: 10 +--- + +:::note[Arcade Machines] + +See the [Arcade Machines](/products/splashkit/#arcade-machines) section of the overview page for +more information. + +::: + +:::note[Arcade Games Development] + +See the [Game Development](/products/splashkit/#game-development) section of the overview page for +more information. + +::: + +:::caution + +The files and folders in the Arcade Games section have been moved here from the "documentation" +repo, and may be out of date. + +We hope to be able to improve the documentation on this site, related to the Arcade Machine and +Games Development, in the near future. + +Join the team and come help improve the documentation a development processes for the Arcade +Machine! + +::: diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/01-unit-testing-guide.mdx b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/01-unit-testing-guide.mdx new file mode 100644 index 00000000..d627659d --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/01-unit-testing-guide.mdx @@ -0,0 +1,329 @@ +--- +title: Unit Testing Guide +--- + +import { FileTree, Steps, Tabs, TabItem } from "@astrojs/starlight/components"; + +## Introduction + +SplashKit uses [Catch2 2.x](https://github.com/catchorg/Catch2/tree/v2.x) as a framework for unit +tests. + +Tests are written in C++ with the aid of macros from Catch2. Test files are located at: + + + +- coresdk + - src + - test + - unit_test_main.cpp + - `unit_test_.cpp` + + + +`unit_test_main.cpp` is the entry point for all unit tests. You do not need to modify this to write +your own tests or update existing ones. + +The `unit_test_.cpp` files contain tests for related parts of SplashKit. For example, +`unit_test_utilities.cpp` has tests for SplashKit's utility functions. A test file must include the +Catch2 header file along with any other includes required: + +```cpp +#include "catch.hpp" +``` + +## Writing a Unit Test + +At a minimum, a unit test consists of a `TEST_CASE` and an assertion (usually `REQUIRE`): + +```cpp +TEST_CASE("gets the number of milliseconds that have passed since the program was started", "[current_ticks]") +{ + unsigned int result = current_ticks(); + REQUIRE(result >= 0); +} +``` + +`TEST_CASE(name, [,tags])` defines a test case with the given name and, optionally, one or more +tags. + +`REQUIRE` evaluates an expression and aborts the test as a failure if the result is false. +`REQUIRE_FALSE` is similar but fails if the expression evaluates true. There are +[other assertion macros](https://github.com/catchorg/Catch2/blob/v2.x/docs/assertions.md#top) but +these are the most common. + +A test may contain multiple assertions: + +```cpp +TEST_CASE("random number float between 0 and 1 is generated", "[rnd]") +{ + float result = rnd(); + REQUIRE(result >= 0); + REQUIRE(result <= 1); +} +``` + +You may write tests that have some common steps, such as defining a variable. You can define one or +more `SECTION(name)` inside a `TEST_CASE`. The `TEST_CASE` is run from the start for each `SECTION`. + +```cpp +TEST_CASE("return a SplashKit resource of resource_kind with name filename as a string", "[file_as_string]") +{ + const resource_kind RESOURCE = resource_kind::BUNDLE_RESOURCE; + const string RESOURCE_PATH = "blah.txt"; + + SECTION("filename is a valid file") + { + string result = file_as_string(RESOURCE_PATH, RESOURCE); + string expected = "BITMAP,ufo,ufo.png\n"; + REQUIRE(result == expected); + } + SECTION("filename is an empty string") + { + string result = file_as_string("", RESOURCE); + string expected = ""; + REQUIRE(result == expected); + } + SECTION("filename is an invalid file") + { + string result = file_as_string("invalid.txt", RESOURCE); + string expected = ""; + REQUIRE(result == expected); + } +} +``` + +This test has three `SECTION`s, so the `TEST_CASE` will run three times. Each time, the `RESOURCE` +and `RESOURCE_PATH` variables will be defined. + +## Building the test project + + + + + +1. Open a terminal and install prerequisites with these commands: + + ```shell + sudo apt-get update + sudo apt-get upgrade -y + sudo apt-get install -y \ + git build-essential cmake g++ libpng-dev libcurl4-openssl-dev libsdl2-dev \ + libsdl2-mixer-dev libsdl2-gfx-dev libsdl2-image-dev libsdl2-net-dev libsdl2-ttf-dev \ + libmikmod-dev libbz2-dev libflac-dev libvorbis-dev libwebp-dev libfreetype6-dev + ``` + +2. Install the CMake Tools extension from the VS Code extension browser or + [here](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools). + +3. Configure the extension: + Select `${workspaceFolder}/projects/cmake/CMakeLists.txt` + ![Select CMake Lists](images/build-unit-tests/1-select-cmakelists.png) + Select the Linux preset + ![Select Linux preset](images/build-unit-tests/2-select-preset-linux.png) + Select the Default configure preset + ![Select Default preset](images/build-unit-tests/2-select-preset-default.png) + In the CMake Tools extension click the button + ![Build target button](images/build-unit-tests/select-target.png) next to Build and select + skunit_tests + ![Select build target](images/build-unit-tests/3-target-unit-tests.png) + Click the button ![Select Default preset](images/build-unit-tests/select-target.png) next to + Debug and select skunit_tests + ![Select debug/launch target](images/build-unit-tests/4-debug-target.png) + +4. Build test project: + From the command line: + + ```shell + cd projects/cmake + cmake --preset Linux + cmake --build build/ + ``` + + Or in VS Code: + In the CMake Tools extension, click the Build button. The test project will also be built when + you refresh tests on the Testing tab of VS Code. + ![Build tests](images/build-unit-tests/5-build.png) + + + + + + +1. Install the CMake Tools extension from the VS Code extension browser or + [here](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools). + +2. Configure the extension: + Select `${workspaceFolder}/projects/cmake/CMakeLists.txt` + ![Select CMake Lists](images/build-unit-tests/1-select-cmakelists.png) + Select the macOS preset + ![Select macOS preset](images/build-unit-tests/2-select-preset-mac.png) + Select the Default configure preset + ![Select Default preset](images/build-unit-tests/2-select-preset-default.png) + In the CMake Tools extension click the button + ![Build target button](images/build-unit-tests/select-target.png) next to Build and select + skunit_tests + ![Select build target](images/build-unit-tests/3-target-unit-tests.png) + Click the button ![Select Default preset](images/build-unit-tests/select-target.png) next to + Debug and select skunit_tests + ![Select debug/launch target](images/build-unit-tests/4-debug-target.png) + +3. Build test project: + From the command line: + + ```shell + cd projects/cmake + cmake --preset macOS + cmake --build build/ + ``` + + Or in VS Code: + In the CMake Tools extension, click Build. The test project will also be built when you refresh + tests on the Testing tab of VS Code. + ![Build tests](images/build-unit-tests/5-build.png) + + + + + + +1. Open the MINGW64 terminal and install prerequisites with these commands: + + ```shell + pacman -Syu + pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb mingw-w64-x86_64-cmake mingw-w64-x86_64-make + ``` + +2. Install the CMake Tools extension from the VS Code extension browser or + [here](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools). + +3. Configure the extension: + Select `${workspaceFolder}/projects/cmake/CMakeLists.txt` + ![Select CMake Lists](images/build-unit-tests/1-select-cmakelists.png) + Select the Windows preset + ![Select Windows preset](images/build-unit-tests/2-select-preset-windows.png) + Select the Default configure preset + ![Select Default preset](images/build-unit-tests/2-select-preset-default.png) + In the CMake Tools extension click the button + ![Build target button](images/build-unit-tests/select-target.png) next to Build and select + skunit_tests + ![Select build target](images/build-unit-tests/3-target-unit-tests.png) + Click the button ![Select Default preset](images/build-unit-tests/select-target.png) next to + Debug and select skunit_tests + ![Select debug/launch target](images/build-unit-tests/4-debug-target.png) + +4. Build test project: + From the command line: + + ```shell + cd projects/cmake + cmake --preset Windows + cmake --build build/ + ``` + + Or in VS Code: + In the CMake Tools extension, click Build. The test project will also be built when you refresh + tests on the Testing tab of VS Code. + ![Build tests](images/build-unit-tests/5-build.png) + + + + + +## Running unit tests + +### From the command line + + + + +- It's a good idea to run the unit tests in a random order so that you can confirm that they run + indepedently of one another: + + ```shell + cd ../../bin + ./skunit_tests --order rand + ``` + + By default, this will only show reports for failed tests. To show reports for successful tests as + well, use the option `--success`. More command line options can be found in + [Catch2's documentation](https://github.com/catchorg/Catch2/blob/v2.x/docs/command-line.md). + +- If you want to run a specific test, or group of tests, you can do so: + + ```shell + ./skunit_tests + ``` + + The `test spec` can be a test name or tags and supports wildcards. For example, `*string*` would + run all of the tests with "string" in the name. + + + + +- It's a good idea to run the unit tests in a random order so that you can confirm that they run + indepedently of one another: + + ```shell + cd ../../bin + ./skunit_tests --order rand + ``` + + By default, this will only show reports for failed tests. To show reports for successful tests as + well, use the option `--success`. More command line options can be found in + [Catch2's documentation](https://github.com/catchorg/Catch2/blob/v2.x/docs/command-line.md). + +- If you want to run a specific test, or group of tests, you can do so: + + ```shell + ./skunit_tests + ``` + + The `test spec` can be a test name or tags and supports wildcards. For example, `*string*` would + run all of the tests with "string" in the name. + + + + +- It's a good idea to run the unit tests in a random order so that you can confirm that they run + indepedently of one another: + + ```shell + cd ../../bin + ./skunit_tests.exe --order rand + ``` + + By default, this will only show reports for failed tests. To show reports for successful tests as + well, use the option `--success`. More command line options can be found in + [Catch2's documentation](https://github.com/catchorg/Catch2/blob/v2.x/docs/command-line.md). + +- If you want to run a specific test, or group of tests, you can do so: + + ```shell + ./skunit_tests.exe + ``` + + The `test spec` can be a test name or tags and supports wildcards. For example, `*string*` would + run all of the tests with "string" in the name. + + + + +### In VS Code + +You can run tests from the Testing tab in VS Code +![Testing tab](images/run-unit-tests/1-testing-tab.png) + +- Running all tests: + Click Run Tests. Each test will be run and the status of each can be seen in the test list after a + test runs. + ![Run Tests](images/run-unit-tests/2-run-tests.png) +- Running a specific test: + Click Run Test next to any test on the test list to run it + ![Run Test](images/run-unit-tests/3-run-test.png) + ![Test status](images/run-unit-tests/4-test-status.png) + +## See Also + +- [Catch2 tutorial](https://github.com/catchorg/Catch2/blob/v2.x/docs/tutorial.md) +- [Catch2 reference](https://github.com/catchorg/Catch2/blob/v2.x/docs/Readme.md) diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/02-onboarding-guide.mdx b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/02-onboarding-guide.mdx new file mode 100644 index 00000000..8e2419a1 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/02-onboarding-guide.mdx @@ -0,0 +1,242 @@ +--- +title: SplashKit Expansion Onboarding Guide +sidebar: + label: "Onboarding Guide" +--- + +:::note + +This guide is the original onboarding guide that was created for this project, but this information +has been moved to the SplashKit-wide [GitHub Guide](/products/splashkit/03-github-guide), which may +be more up-to-date. + +This guide is here as well in case it is easier to use. + +::: + +## Introduction + +This guide will cover all the steps required to get contributing to the splashkit-core repository. +Feel free to skip steps which you have already completed or are familiar with. + +## Installing WSL + +WSL is a built-in Linux distribution virtual machine for Windows. splashkit-core will be installed +to the Linux distribution. The official SplashKit installation instructions can be found here: +[Windows (WSL) Installation Overview](https://splashkit.io/installation/windows-wsl). This guide has +been tested with the default Ubuntu distribution, but others may also work. + +### Installing Visual Studio Code + +Once WSL has been installed to Windows, Visual Studio Code needs to be installed to WSL. The +SplashKit documentation explains the process: +[Install Visual Studio Code](https://splashkit.io/installation/windows-wsl/step-3) + +### Installing Git + +Now Git must be installed to WSL. Follow the Microsoft installation instructions: +[Install Git](https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-git). GitHub's Git Cheat +Sheet is useful for both installation and usage of Git: +[GitHub Git Cheat Sheet](https://education.github.com/git-cheat-sheet-education.pdf) + +### Installing Windows Terminal (optional) + +Windows Terminal is an updated Command Prompt with many useful features. It is not mandatory to +install, however it is recommended due to its ease of use. More information about Windows Terminal +can be found here: [Windows Terminal](https://learn.microsoft.com/en-us/windows/terminal/).It can be +installed through the Microsoft Store. + +By default, new tabs will open as a Command Prompt, with WSL terminals being accessible with the +down-arrow. Since WSL will be used so frequently, there is the option to change the default tab to +WSL. Open the settings by clicking the down arrow and selecting β€˜Settings’. In the β€˜Startup’ tab, +β€˜Default profile’ allows you to change the default tab type to WSL. + +## Setting Up splashkit-core + +Now that WSL is fully configured, it is time to install the splashkit-core repository. + +### Forking splashkit-core Repository + +A fork is a copy of a repository which allows for independent development without interfering with +the primary repository itself. To create a personal fork of splashkit-core, navigate to +[GitHub splashkit-core](https://github.com/splashkit/splashkit-core) and click β€˜Fork’. On the next +page, keep the default name and click β€˜Create fork’. + +The following guide for the SplashKit Website has useful information regarding forks and branches +which can be adjusted for splashkit-core by substituting repository names: +[Get Your Environment Set Up](/products/splashkit/02-setting-up). + +### Cloning splashkit-core Repository + +Open a WSL terminal and change directory to your home with: + +```shell +cd +``` + +Note that this guide clones the repository to the home directory, but feel free to move its +location. Now initiate the clone process of your fork with: + +```shell +git clone --recursive -j2 https://github.com/{user name}/splashkit-core.git +``` + +splashkit-core contains multiple submodules (separate repositories which splashkit-core depends +upon). The `--recursive` argument ensures that the submodules are also downloaded when calling +clone. Wait for the download to complete before continuing to the next step. + +## Contributing to splashkit-core + +It is now time to start fixing bugs and adding functionality to splashkit-core. + +### Creating Branch + +When modifying the repository, changes should be logically grouped together onto separate branches. +To create a branch, open a WSL terminal and navigate to the `splashkit-core` folder with: + +```shell +cd splashkit-core +``` + +Check the current branch with: + +```shell +git branch +``` + +Create a new branch using the current branch as a base: + +```shell +git branch {new branch name} +``` + +Swap to new branch with: + +```shell +git checkout {new branch name} +``` + +Now that a new branch is created and active, development can begin. + +### Building the Test Programs + +You cannot create new programs with splashkit-core as you do when using the traditional SplashKit +library. Instead, two programs are generated which can be configured to test its functionality: +`sktest` and `skunit_tests`. They are built with CMake using a preconfigured `CMakeLists.txt` file. +Open a WSL terminal and enter: + +```shell +cd +cd splashkit-core/projects/cmake +cmake -G "Unix Makefiles" . +make +``` + +The associated macOS and Linux commands can be found here: +[CONTRIBUTING](https://github.com/thoth-tech/splashkit-core/blob/develop/CONTRIBUTING.md) + +### Running the Test Programs + +To run the test programs, open a WSL terminal and enter: + +```shell +cd +cd splashkit-core/bin +``` + +Then for sktest: + +```shell +./sktest +``` + +Or for skunit_tests: + +```shell +./skunit_tests +``` + +### Making Changes + +`sktest` is built with the .cpp files from `~/splashkit-core/coreskd/src/test/`. To add your own +tests, modify one or more of the files such as `test_animation.cpp`. + +`skunit_tests` is built with the .cpp files from `~/splashkit-core/coreskd/src/test/unit_tests/`. +When it runs, all unit tests from all files in this folder are executed. Additional files can be +added to this folder if necessary. If adding a new file, copy the structure from one of the existing +unit test files. Critically, `#include "catch.hpp"` must be present in the file for it to be +compiled into `skunit_tests`. Beyond that, the hierarchy of, `TEST_CASE > SECTION > ASSERTION` +should be followed to improve readability and tracing of errors. + +### Testing Changes + +If a change is made to the code, the test programs need to be rebuilt. In a WSL terminal enter: + +```shell +cd +cd splashkit-core/projects/cmake +make +``` + +If any files were created or deleted, the CMake files need to be regenerated. In that case use: + +```shell +cd +cd splashkit-core/projects/cmake +cmake -G "Unix Makefiles" . +make +``` + +### Documenting Changes + +Local changes can be tested by building and running the test programs. However, once changes are to +be submitted for review, they need to be staged, committed and pushed. It is good practice to +perform multiple smaller commits with meaningful descriptions rather than a single monolithic +commit. In addition, pushing commits to GitHub provides a layer of backup in case of local machine +failure. + +### Creating a Pull Request + +Once you have completed work on a particular branch, a pull request (PR) can be made. At this point +there are now three relevant splashkit-core repositories at play: splashkit-core itself, +thoth-tech’s fork, and your personal fork. During trimester, PRs should be made against the +thoth-tech fork. The PR template provides a framework for how to structure the associated PR +documentation. + +The following guide details how to create PRs for the SplashKit Website. The same instructions can +be used for splashkit-core by simply changing the repository name: +[How to Create a Pull Request](/products/splashkit/04-pull-request). + +### Responding to Peer Reviews + +If changes are requested during a PR review, pushing further commits to the same branch will +automatically be added to the PR. + +### Performing Peer Reviews + +A critical component to SplashKit development is the process of reviewing your peers' PRs and +providing constructive feedback. This process has been detailed in the following guide: +[A Guide to Doing Peer Reviews](/products/splashkit/06-peer-review) + +### Planner Board + +The planner board is used to coordinate tasks while they are being completed and reviewed. The +following guide details the procedure and etiquette which is expected while using the planner board: +[Planner Board Ettiquete](/products/splashkit/07-planner-board) + +## Troubleshooting + +Solutions for common issues can be found below. Be sure to also check the following page for help +troubleshooting: +[Guide to resolving Common Issues](/products/splashkit/03-github-guide/#troubleshooting) + +### Empty Translator folder + +If the translator folder is empty, it may be due to an issue with the submodules. In an WSL +terminal, enter the following: + +```shell +cd +cd splashkit-core +git submodule update --init --recursive +``` diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/03-improvement-suggestion-add-oop-collision-resolution.mdx b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/03-improvement-suggestion-add-oop-collision-resolution.mdx new file mode 100644 index 00000000..ebb084d6 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/03-improvement-suggestion-add-oop-collision-resolution.mdx @@ -0,0 +1,745 @@ +--- +title: "Suggested Improvement: Adding OOP Principles to Shape Types" +description: + This page is about adding OOP principles to SplashKit's Shape types to simplify the collision + classification and resolution functions +sidebar: + label: "Suggested Improvement for Shape Types" +--- + +## Description + +This document outlines the refactoring of a previous PR: +[Pull Request 83](https://github.com/thoth-tech/splashkit-core/pull/83). The goal was to eliminate +the need for void and function pointers by having sprites, rectangles, circles, triangles and quads +inherit from the abstract class shape. Unfortunately, I was unable to get the program to compile. I +am fairly certain that it is due to circular dependencies. + +The major issue is that `_sprite_data` is abstracted entirely from students by being declared in +`sprite.cpp`. However, moving `_sprite_data` from `sprites.cpp` to `sprites.h` leads to circular +dependencies between `collision.h`, `types.h`, `sprites.h` and `backend_types.h`. + +I am sure that the compilation errors could be resolved, however it would be a difficult process. My +plan would be to split larger header files such as `types.h` into smaller files for each struct. +There would be then be a `rectangle.h`, `circle.h` and so on. + +Similarly, `backend_types.h` would be split into many smaller header files for each enum. This would +allow for fine-grain control of includes which will make diagnosing and rectifying the circular +dependencies easier. + +By moving to an OOP approach, the code can be more understood, debugged and maintained. + +## Code + +### `types.cpp` Additions + +```cpp +bool shape::intersects(const shape* other) const +{ + switch (other->get_shape_type()) + { + case shape_type::SPRITE: + return other->intersects(*this); + case shape_type::RECTANGLE: + return this->intersects(*dynamic_cast(other)); + case shape_type::CIRCLE: + return this->intersects(*dynamic_cast(other)); + case shape_type::TRIANGLE: + return this->intersects(*dynamic_cast(other)); + case shape_type::QUAD: + return this->intersects(*dynamic_cast(other)); + }; + + return false; +} + +bool shape::intersects(const shape& other) const +{ + return this->intersects(&other); +} + +bool shape::AABB_intersects(const shape* other) const +{ + return this->get_bounding_box().intersects(other->get_bounding_box()); +} + +rectangle::rectangle() +{ + x = 0.0; + y = 0.0; + width = 0.0; + height = 0.0; +} + +rectangle::rectangle(double x, double y, double width, double height) +{ + this->x = x; + this->y = y; + this->width = width; + this->height = height; +} + +rectangle rectangle::get_bounding_box() const +{ + return *this; +} + +shape_type rectangle::get_shape_type() const +{ + return shape_type::RECTANGLE; +} + +bool rectangle::intersects(const _sprite_data& other) const +{ + return other.intersects(*this); +} + +bool rectangle::intersects(const rectangle& other) const +{ + return rectangles_intersect(*this, other); +} + +bool rectangle::intersects(const circle& other) const +{ + return rectangle_circle_intersect(*this, other); +} + +bool rectangle::intersects(const triangle& other) const +{ + return triangle_rectangle_intersect(other, *this); +} + +bool rectangle::intersects(const quad& other) const +{ + return quads_intersect(quad_from(*this), other); +} + +void rectangle::move_by(const vector_2d& amount) +{ + x += amount.x; + y += amount.y; +} + +quad::quad() +{ + for (int i = 0; i < 4; i++) + { + points[i] = {0.0, 0.0}; + } +} + +quad::quad(const point_2d& top_left, const point_2d& top_right, + const point_2d& bottom_left, const point_2d& bottom_right) +{ + points[0] = top_left; + points[1] = top_right; + points[2] = bottom_left; + points[3] = bottom_right; +} + +rectangle quad::get_bounding_box() const +{ + return rectangle_around(*this); +} + +shape_type quad::get_shape_type() const +{ + return shape_type::QUAD; +} + +bool quad::intersects(const _sprite_data& other) const +{ + return other.intersects(*this); +} + +bool quad::intersects(const rectangle& other) const +{ + return other.intersects(*this); +} + +bool quad::intersects(const circle& other) const +{ + return other.intersects(*this); +} + +bool quad::intersects(const triangle& other) const +{ + return other.intersects(*this); +} + +bool quad::intersects(const quad& other) const +{ + return other.intersects(*this); +} + +void quad::move_by(const vector_2d& amount) +{ + for (int i = 0; i < 4; i++) + { + points[i].x += amount.x; + points[i].y += amount.y; + } +} + +circle::circle() +{ + center = {0.0, 0.0}; + radius = 0.0; +} + +circle::circle(const point_2d& center, double radius) +{ + this->center = center; + this->radius = radius; +} + +rectangle circle::get_bounding_box() const +{ + return rectangle_around(*this); +} + +shape_type circle::get_shape_type() const +{ + return shape_type::CIRCLE; +} + +bool circle::intersects(const _sprite_data& other) const +{ + return other.intersects(*this); +} + +bool circle::intersects(const rectangle& other) const +{ + return other.intersects(*this); +} + +bool circle::intersects(const circle& other) const +{ + return circles_intersect(*this, other); +} + +bool circle::intersects(const triangle& other) const +{ + return circle_triangle_intersect(*this, other); +} + +bool circle::intersects(const quad& other) const +{ + return circle_quad_intersect(*this, other); +} + +void circle::move_by(const vector_2d& amount) +{ + center.x += amount.x; + center.y += amount.y; +} + +triangle::triangle() +{ + for (int i = 0; i < 3; i++) + { + points[i] = {0.0, 0.0}; + } +} + +triangle::triangle(const point_2d& p1, const point_2d& p2, const point_2d& p3) +{ + points[0] = p1; + points[1] = p2; + points[2] = p3; +} + +rectangle triangle::get_bounding_box() const +{ + return rectangle_around(*this); +} + +shape_type triangle::get_shape_type() const +{ + return shape_type::TRIANGLE; +} + +bool triangle::intersects(const _sprite_data& other) const +{ + return other.intersects(*this); +} + +bool triangle::intersects(const rectangle& other) const +{ + return other.intersects(*this); +} + +bool triangle::intersects(const circle& other) const +{ + return other.intersects(*this); +} + +bool triangle::intersects(const triangle& other) const +{ + return triangles_intersect(*this, other); +} + +bool triangle::intersects(const quad& other) const +{ + return triangle_quad_intersect(*this, other); +} + +void triangle::move_by(const vector_2d& amount) +{ + for (int i = 0; i < 3; i++) + { + points[i].x += amount.x; + points[i].y += amount.y; + } +} +``` + +### `collisions.cpp` Modified Methods + +```cpp +collision_direction _calculate_object_collision_direction(const shape* collider, const shape* collidee) +{ + if (!collider->intersects(collidee)) + { + return collision_direction::NONE; + } + + return _rectangle_rectangle_collision_direction(collider->get_bounding_box(), collidee->get_bounding_box()); +} + +bool _resolve_object_collision(shape* collider, const shape* collidee, collision_direction direction) +{ + // check if the sprites are colliding + if (direction == collision_direction::NONE || !collider->intersects(collidee)) + { + return false; + } + + if (_get_collision_test_kind(collider) == AABB_COLLISIONS && _get_collision_test_kind(collidee) == AABB_COLLISIONS) + { + _resolve_object_AABB_collision(collider, collidee, direction); + } + else // one or both of the sprites are using pixel collision + { + //bracket_func(collider, collidee, _direction_from_collision(direction), BRACKET_ITERATIONS); + _bracket_object_collision_generic(collider, collidee, _direction_from_collision(direction), BRACKET_ITERATIONS); + } + + return true; +} + +collision_test_kind _get_collision_test_kind(const shape* s) +{ + shape_type type = s->get_shape_type(); + + if (type == shape_type::RECTANGLE) + { + return AABB_COLLISIONS; + } + else if (type == shape_type::SPRITE) + { + const _sprite_data* sprite_data = dynamic_cast(s); + if (sprite_data && sprite_collision_kind(const_cast(sprite_data)) == AABB_COLLISIONS) + { + return AABB_COLLISIONS; + } + } + + return PIXEL_COLLISIONS; +} + +void _resolve_object_AABB_collision(shape* collider, const shape* collidee, collision_direction direction) +{ + // get the intersection rectangle + rectangle inter = intersection(collider->get_bounding_box(), collidee->get_bounding_box()); + vector_2d amount = vector_to(inter.width, inter.height); + + _move_object_by_direction(collider, _direction_from_collision(direction), amount); +} + +void _move_object_by_direction(shape* obj, _sprite_movement_direction direction, const vector_2d& amount) +{ + if (amount.x == 0.0 && amount.y == 0.0) + { + return; + } + + switch (direction) + { + case _sprite_movement_direction::UP: + obj->move_by(vector_to(0.0, -amount.y)); + break; + case _sprite_movement_direction::DOWN: + obj->move_by(vector_to(0.0, amount.y)); + break; + case _sprite_movement_direction::LEFT: + obj->move_by(vector_to(-amount.x, 0.0)); + break; + case _sprite_movement_direction::RIGHT: + obj->move_by(vector_to(amount.x, 0.0)); + break; + case _sprite_movement_direction::UP_LEFT: + obj->move_by(vector_to(-amount.x, -amount.y)); + break; + case _sprite_movement_direction::UP_RIGHT: + obj->move_by(vector_to(amount.x, -amount.y)); + break; + case _sprite_movement_direction::DOWN_LEFT: + obj->move_by(vector_to(-amount.x, amount.y)); + break; + default: // _sprite_movement_direction::DOWN_RIGHT: + obj->move_by(vector_to(amount.x, amount.y)); + break; + }; +} + +bool _bracket_object_collision_generic(shape* collider, const shape* collidee, + _sprite_movement_direction collider_direction, int iterations) +{ + rectangle collider_aabb = collider->get_bounding_box(); + + for (int i = 1; i <= iterations; i++) + { + if (!_bracket_object_collision(collider->intersects(collidee), i, collider, collider_direction)) + { + return false; + } + } + return true; +} + +bool _bracket_object_collision(bool colliding, int i, shape* collider, _sprite_movement_direction collider_direction) +{ + rectangle collider_aabb = collider->get_bounding_box(); + + if (colliding) + { + _move_object_by_direction_relative_to_size(collider, collider_direction, + 1.0 / pow(ITERATION_POWER, static_cast(i))); + } + else if (i == 1) // no collision in the first iteration + { + return false; + } + else + { + _move_object_by_direction_relative_to_size(collider, _opposite_direction(collider_direction), + 1.0 / pow(ITERATION_POWER, static_cast(i))); + } + return true; +} + +void _move_object_by_direction_relative_to_size(shape* obj, _sprite_movement_direction direction, double relative_amount = 1.0) +{ + rectangle obj_aabb = obj->get_bounding_box(); + + double relative_width = obj_aabb.width * relative_amount; + double relative_height = obj_aabb.height * relative_amount; + + switch (direction) + { + case _sprite_movement_direction::UP: + _move_object_by_direction(obj,_sprite_movement_direction::UP, vector_to(0.0, relative_height)); + break; + case _sprite_movement_direction::DOWN: + _move_object_by_direction(obj, _sprite_movement_direction::DOWN, vector_to(0.0, relative_height)); + break; + case _sprite_movement_direction::LEFT: + _move_object_by_direction(obj, _sprite_movement_direction::LEFT, vector_to(relative_width, 0.0)); + break; + case _sprite_movement_direction::RIGHT: + _move_object_by_direction(obj, _sprite_movement_direction::RIGHT, vector_to(relative_width, 0.0)); + break; + case _sprite_movement_direction::UP_LEFT: + _move_object_by_direction(obj, _sprite_movement_direction::UP_LEFT, vector_to(relative_width, relative_height)); + break; + case _sprite_movement_direction::UP_RIGHT: + _move_object_by_direction(obj, _sprite_movement_direction::UP_RIGHT, vector_to(relative_width, relative_height)); + break; + case _sprite_movement_direction::DOWN_LEFT: + _move_object_by_direction(obj, _sprite_movement_direction::DOWN_LEFT, vector_to(relative_width, relative_height)); + break; + default: // _sprite_movement_direction::DOWN_RIGHT: + _move_object_by_direction(obj, _sprite_movement_direction::DOWN_RIGHT, vector_to(relative_width, relative_height)); + break; + }; +} +``` + +### `sprites.h` First Section With New Declaration + +```cpp +/** + * @header sprites + * @author Andrew Cain + * @brief SplashKit Sprites allows you to create images you can easily + * move and animate. + * + * SplashKit sprites are game elements that can be moved, and animated. Sprites + * are located at a position in the game, have a velocity, and an animation. + * The sprite can also have arbitary data associated with it for game specific + * purposes. + * + * @attribute group sprites + * @attribute static sprite + */ + +#ifndef sprites_h +#define sprites_h + +#include "matrix_2d.h" +#include "types.h" +namespace splashkit_lib +{ + /** + * This enumeration contains a list of all of the different kinds of + * events that a Sprite can raise. When the event is raised the assocated + * sprite_event_kind value passed to the event handler to indicate the + * kind of event that has occurred. + * + * @constant SPRITE_ARRIVED_EVENT The sprite has arrived at the end of a move + * @constant SPRITE_ANIMATION_ENDED_EVENT The Sprite's animation has ended. + * @constant SPRITE_TOUCHED_EVENT The Sprite was touched + * @constant SPRITE_CLICKED_EVENT The Sprite was touched + */ + enum sprite_event_kind + { + SPRITE_ARRIVED_EVENT, + SPRITE_ANIMATION_ENDED_EVENT, + SPRITE_TOUCHED_EVENT, + SPRITE_CLICKED_EVENT + }; + + /** + * This enumeration can be used to set the kind of collisions a sprite will check for. + * + * @constant PIXEL_COLLISIONS The sprite will check for collisions with its collision bitmap. + * @constant AABB_COLLISIONS The sprite will check for collisions with a bounding box around the sprite. + */ + enum collision_test_kind + { + PIXEL_COLLISIONS, + AABB_COLLISIONS + }; + + /** + * Sprites combine an image, with position and animation details. You can + * create a sprite using `create_sprite`, draw it with `draw_sprite`, move it + * using the `sprite_velocity` with `update_sprite`, and animate it using an + * `animation_script`. + * + * @attribute class sprite + */ + typedef struct _sprite_data *sprite; + + /** + * The sprite_event_handler function pointer is used when you want to register + * to receive events from a Sprite. + * + * @param s The `sprite` raising the event. + * @param evt The `sprite_event_kind` being raised. + */ + typedef void (sprite_event_handler) (void *s, int evt); + + /** + * sprite_function is used with SpritePacks to provide a procedure to be + * called for each of the Sprites in the SpritePack. + * + * @param s The `sprite` being passed to the sprite function. + */ + typedef void (sprite_function)(void *s); + + /** + * The sprite single function is used with sprite packs to provide a + * procedure to be called for each of the Sprites in the sprite pack, + * where a float value is required. + * + * @param s The `sprite` being passed to the sprite function. + * @param f The value to be passed to the function. + */ + typedef void (sprite_float_function)(void *s, float f); + + std::vector ¤t_pack(); + + struct _sprite_data : public shape + { + pointer_identifier id; + std::string name; // The name of the sprite for resource management + + std::vector layers; // Layers of the sprites + std::map layer_names; + std::vector visible_layers; // The indexes of the visible layers + std::vector layer_offsets; // Offsets from drawing the layers + + std::map values; // Values associated with this sprite + + + animation animation_info; // The data used to animate this sprite + animation_script script; // The template for this sprite"s animations + + point_2d position; // The game location of the sprite + vector_2d velocity; // The velocity of the sprite + + collision_test_kind collision_kind; //The kind of collisions used by this sprite + bitmap collision_bitmap; // The bitmap used for collision testing (default to first image) + + point_2d anchor_point; + bool position_at_anchor_point; + bool draw_at_anchor_point; + + bool is_moving; // Used for events to indicate the sprite is moving + point_2d destination; // The destination the sprite is moving to + vector_2d moving_vec; // The sprite"s movement vector + float arrive_in_sec; // Amount of time in seconds to arrive at point + int last_update; // Time of last update + + bool announced_animation_end; // Used to avoid multiple announcements of an end of an animation + + std::vector evts; // The call backs listening for sprite events + + std::vector &pack; // Points the the SpritePack that contains this sprite + + _sprite_data() : pack( current_pack() ) + { + } + + rectangle get_bounding_box() const override; + shape_type get_shape_type() const override; + bool intersects(const _sprite_data& other) const override; + bool intersects(const rectangle& other) const override; + bool intersects(const circle& other) const override; + bool intersects(const triangle& other) const override; + bool intersects(const quad& other) const override; + void move_by(const vector_2d& amount) override; + }; + + // ***** +} +``` + +### `sprites.cpp` First Section With New Member Functions + +```cpp +// +// sprites.cpp +// splashkit +// +// Created by Andrew Cain on 23/08/2016. +// Copyright Β© 2016 Andrew Cain. All rights reserved. +// + +#include "animations.h" +#include "backend_types.h" +#include "camera.h" +#include "collisions.h" +#include "geometry.h" +#include "images.h" +#include "mouse_input.h" +#include "sprites.h" +#include "timers.h" +#include "utility_functions.h" +#include "vector_2d.h" + +#include +#include +#include + +using std::map; +using std::vector; +using std::to_string; +using std::swap; + +namespace splashkit_lib +{ + timer _sprite_timer = nullptr; + vector _global_sprite_event_handlers; + + map _sprites; + + // Sprite pack data +#define INITIAL_PACK_NAME "default" + map> _sprite_packs; + string _current_pack = INITIAL_PACK_NAME; + + vector ¤t_pack() + { + return _sprite_packs[_current_pack]; + } + +#define SCALE_KEY "scale" +#define ROTATION_KEY "rotation" +#define MASS_KEY "mass" + + rectangle _sprite_data::get_bounding_box() const + { + return sprite_collision_rectangle(const_cast(this)); + } + + shape_type _sprite_data::get_shape_type() const + { + return shape_type::SPRITE; + } + + bool _sprite_data::intersects(const _sprite_data& other) const + { + return sprite_collision(const_cast(this), const_cast(&other)); + } + + bool _sprite_data::intersects(const rectangle& other) const + { + bool aabb_collision = this->AABB_intersects(&other); + + if (this->collision_kind == AABB_COLLISIONS || !aabb_collision) + { + return aabb_collision; + } + + return sprite_rectangle_collision(const_cast(this), other); + } + + bool _sprite_data::intersects(const circle& other) const + { + bool aabb_collision = this->AABB_intersects(&other); + + if (this->collision_kind == AABB_COLLISIONS || !aabb_collision) + { + return aabb_collision; + } + + return sprite_circle_collision(const_cast(this), other); + } + + bool _sprite_data::intersects(const triangle& other) const + { + bool aabb_collision = this->AABB_intersects(&other); + + if (this->collision_kind == AABB_COLLISIONS || !aabb_collision) + { + return aabb_collision; + } + + return sprite_triangle_collision(const_cast(this), other); + } + + bool _sprite_data::intersects(const quad& other) const + { + bool aabb_collision = quads_intersect( + quad_from(sprite_collision_rectangle(const_cast(this))), other); + + if (this->collision_kind == AABB_COLLISIONS || !aabb_collision) + { + return aabb_collision; + } + + return sprite_quad_collision(const_cast(this), other); + } + + void _sprite_data::move_by(const vector_2d& amount) + { + this->position.x += amount.x; + this->position.y += amount.y; + } + + // ***** +} +``` diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/04-nuget-package-guide.mdx b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/04-nuget-package-guide.mdx new file mode 100644 index 00000000..cbdf435d --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/04-nuget-package-guide.mdx @@ -0,0 +1,264 @@ +--- +title: "NuGet Package Guide" +description: "Guide to building and testing the SplashKit NuGet package for .NET" +--- + +import { FileTree, Steps } from "@astrojs/starlight/components"; + +## Introduction + +NuGet is the package manager for .NET. NuGet packages are essentially zip files containing reusable +code, libraries, and metadata. Packages can be distributed privately or publicly via NuGet +repositories. For more information, visit [nuget.org](https://www.nuget.org/). + +The SplashKit NuGet package has two primary purposes: + +- Provides C# bindings for SplashKit, translated from C++ using SplashKit Translator. The bindings + allow users to create SplashKit projects with C#. +- Provides SplashKit native libraries for Windows (x64) and macOS. These libraries allow Windows and + Mac users to create and run SplashKit projects in C# without installing the libraries separately + via SplashKit Manager (SKM). + +:::note + +**Prerequisite:** Ensure [.NET SDK](https://dotnet.microsoft.com/en-us/download) is installed. + +::: + +## Building the Package + + + +1. #### Download the SplashKit native libraries + + Download the latest stable libraries from [SKM](https://github.com/splashkit/skm.git). Libraries + should be placed in `/tools/scripts/nuget-pkg/Libraries/win64` and + `/tools/scripts/nuget-pkg/Libraries/macos` respectively. This step can be automated via the use + of the bash script found at `/tools/scripts/nuget-pkg/download-libraries.sh`. + + :::note + + SKM does not include pre-compiled libraries for Linux. It instead uses a script to install + dependencies and builds based on the detected distro. + + ::: + +2. #### Open the NuGet package directory + + Navigate to `/tools/scripts/nuget-pkg`. This directory contains configuration settings for the + package, along with the associated icon and description. + +3. #### Build the package + + Run one of the below commands, ensuring to replace _YOUR_VERSION_ with the relevant version + number (e.g. 1.3.0): + + **For debug** + + ```shell + dotnet build --configuration Debug -p:version=YOUR_VERSION-debug + ``` + + **For release** + + ```shell + dotnet build --configuration Release -p:version=YOUR_VERSION + ``` + + This will build the package and output to `tools/scripts/nuget-pkg/bin/` as detailed in + [Exploring the Output](#exploring-the-output). + +4. #### Check the output directories + Ensure both `Release` and `Debug` directories exist in `tools/scripts/nuget-pkg/bin/`. If either + is missing, create the empty directory as needed. This is to ensure the test programs run without + errors. + + + +### Exploring the Output + +In the `tools/scripts/nuget-pkg/bin/` directory, there will be a directory corresponding to the +built package - either `Debug` or `Release`. This directory contains the NuGet package itself +(`SplashKit.X.X.X.nupkg`), along with separate directories for each targeted .NET version. These +directories are for referencing/testing, and can be ignored - the package itself does not depend +upon them. + +## Testing + +A suite of test programs is provided in the form of a C# solution, with a separate project/directory +for each test. + + + +- tools + - scripts + - test + - Main/ + - Directory.Build.props + - Directory.Packages.props + - GlobalSettings.cs + - NuGet.config + - NuGetTests.sln + + + +The provided tests are translations of the SplashKit core integration tests. The tests can be run +individually from their respective folders, but are best launched using the test runner located in +the `Main` directory. + +:::note + +For more information on SplashKit core integration tests, see +[here](https://thoth-tech.netlify.app/products/splashkit/documentation/splashkit-expansion/#building-the-test-programs). + +::: + +### Running the Provided Tests + + + +1. #### Check local package sources + + `NuGet.config` sets the local NuGet package sources. If one of these directories does not exist, + either create it, or comment out the corresponding entry in `NuGet.config`. + +2. #### Set target package version + + `Directory.Packages.props` specifies the target NuGet package version. Update this file to match + the version being tested. + +3. #### Check target .NET versions + + `Directory.Build.props` specifies .NET versions for multi-targeting. These should match the .NET + versions being targeted by the package build. + + :::caution + + Ensure **every** listed version of .NET is installed. + + ::: + +4. #### Run the test runner + + Open the `Main` directory. Run the following command, replacing _TARGET_FRAMEWORK_ with the + framework to be tested, e.g. For .NET 9, use `dotnet run -f net9.0`. + + ```shell + dotnet run -f + ``` + + :::note + + To aid testing and ensure consistency, the test runner lists the target and runtime .NET + framework, along with the NuGet package version. These should be checked on every run to ensure + alignment with the intended targets: + + ![Run NuGet Tests](images/nuget-testing/1-test-runner.png) + + ::: + +5. #### Select test + + Input a number to build and run the corresponding test. + + :::caution + + **Known issue:** The included graphics test currently produces inconsistent results in a + MSYS2/Windows environment. This behaviour is consistent with SplashKit installed via SKM and is + being investigated. + + ::: + +6. #### Re-run as necessary + To ensure the package is fully functional, the tests should be re-run to cover each combination + of framework and architecture. Every test should produce the expected output. + + + +### Updating or Adding Tests + +As noted in [Running the Provided Tests](#running-the-provided-tests), the _NuGetTests_ solution +specifies the NuGet version and target frameworks in `Directory.Packages.props` and +`Directory.Build.props` respectively. These should be updated at a solution level, rather than +separate configurations for each test project. This ensures ease of use and reduces room for error. + +### Adding New Tests to the Solution + + + +1. Create a new directory in `/tools/scripts/test`, for example: + + ```shell + mkdir MyTest + ``` + +2. Inside the new directory, create a new project with + + ```shell + dotnet new console + ``` + +3. Edit the project's `.csproj` file to remove any `` tags, since this would + override the solution's multi-targeting. + +4. Write your new test in `Program.cs` + +5. If loading resources (e.g. images, fonts, etc.) use the following line to utilise existing + resources from the main SplashKit test suite. + + ```cs + SetResourcesPath(GlobalSettings.ResourcePath); + ``` + + + +:::note + +The test runner checks the solution directory for any `.csproj` files on input. Therefore, new tests +are detected by the runner automatically, and can even be added without closing the runner. + +::: + +### Updating Existing Tests + +Existing tests can be updated by editing `Program.cs` in the corresponding project's directory. +Since the test runner (`Main`) builds each project before running, there is no need to rebuild the +runner upon updating a test. The runner is designed to be left running during updates, to speed up +development. + +If loading resources (e.g. images, fonts, etc.) use the following line to utilise existing resources +from the main SplashKit test suite: + +```cs +SetResourcesPath(GlobalSettings.ResourcePath); +``` + +### Creating Tests Outside of the Provided Solution + +Normally, an end user would use `dotnet add package splashkit` to reference the SplashKit package. +However, this will default to the latest stable SplashKit version, skipping the locally built one. +Instead, do the following: + + + +1. Create a new project using + + ```shell + dotnet new console + ``` + +2. Create a `NuGet.config` file in the project (or solution) directory, specifying the path to the + target package. An example can be found in `/tools/scripts/test`. + +3. Add the following to the `.csproj`, replacing _TARGET_VERSION_ with the targeted NuGet package + version: + + ```xml + + + + ``` + +4. Add `using static SplashKitSDK.SplashKit;` to `Program.cs` + + diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/1-select-cmakelists.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/1-select-cmakelists.png new file mode 100644 index 00000000..7375a8b5 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/1-select-cmakelists.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/1-select-cmakelists.png~RF68bbeb9.TMP b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/1-select-cmakelists.png~RF68bbeb9.TMP new file mode 100644 index 00000000..fcd7242d Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/1-select-cmakelists.png~RF68bbeb9.TMP differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-default.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-default.png new file mode 100644 index 00000000..8780630e Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-default.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-default.png~RF68c3c45.TMP b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-default.png~RF68c3c45.TMP new file mode 100644 index 00000000..f5f2f3cb Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-default.png~RF68c3c45.TMP differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-linux.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-linux.png new file mode 100644 index 00000000..cc6f2024 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-linux.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-linux.png~RF68cb609.TMP b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-linux.png~RF68cb609.TMP new file mode 100644 index 00000000..79b810a7 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-linux.png~RF68cb609.TMP differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-mac.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-mac.png new file mode 100644 index 00000000..d1ec332b Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-mac.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-mac.png~RF68d15cd.TMP b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-mac.png~RF68d15cd.TMP new file mode 100644 index 00000000..11a39a2b Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-mac.png~RF68d15cd.TMP differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-windows.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-windows.png new file mode 100644 index 00000000..9388628f Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-windows.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-windows.png~RF68d762d.TMP b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-windows.png~RF68d762d.TMP new file mode 100644 index 00000000..5302a25a Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/2-select-preset-windows.png~RF68d762d.TMP differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/3-target-unit-tests.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/3-target-unit-tests.png new file mode 100644 index 00000000..03d4ffdc Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/3-target-unit-tests.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/3-target-unit-tests.png~RF68e32c6.TMP b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/3-target-unit-tests.png~RF68e32c6.TMP new file mode 100644 index 00000000..eddd739c Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/3-target-unit-tests.png~RF68e32c6.TMP differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/4-debug-target.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/4-debug-target.png new file mode 100644 index 00000000..aa3e4476 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/4-debug-target.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/4-debug-target.png~RF68e8be2.TMP b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/4-debug-target.png~RF68e8be2.TMP new file mode 100644 index 00000000..855f31d7 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/4-debug-target.png~RF68e8be2.TMP differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/5-build.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/5-build.png new file mode 100644 index 00000000..2cde00a3 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/5-build.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/5-build.png~RF68ecdcd.TMP b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/5-build.png~RF68ecdcd.TMP new file mode 100644 index 00000000..ebf01c1d Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/5-build.png~RF68ecdcd.TMP differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/select-target.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/select-target.png new file mode 100644 index 00000000..f2404425 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/select-target.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/select-target.png~RF68f1bce.TMP b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/select-target.png~RF68f1bce.TMP new file mode 100644 index 00000000..12802439 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/select-target.png~RF68f1bce.TMP differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/select-target.png~RF68fac56.TMP b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/select-target.png~RF68fac56.TMP new file mode 100644 index 00000000..33a9303e Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/build-unit-tests/select-target.png~RF68fac56.TMP differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/nuget-testing/1-test-runner.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/nuget-testing/1-test-runner.png new file mode 100644 index 00000000..6255fcec Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/nuget-testing/1-test-runner.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/1-testing-tab.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/1-testing-tab.png new file mode 100644 index 00000000..09ff2137 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/1-testing-tab.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/1-testing-tab.png~RF6894617.TMP b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/1-testing-tab.png~RF6894617.TMP new file mode 100644 index 00000000..c8b7a67e Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/1-testing-tab.png~RF6894617.TMP differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/2-run-tests.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/2-run-tests.png new file mode 100644 index 00000000..95d49f78 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/2-run-tests.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/3-run-test.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/3-run-test.png new file mode 100644 index 00000000..9a872080 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/3-run-test.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/4-test-status.png b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/4-test-status.png new file mode 100644 index 00000000..7b52b6b2 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/images/run-unit-tests/4-test-status.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/index.mdx b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/index.mdx new file mode 100644 index 00000000..d7f935ff --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/index.mdx @@ -0,0 +1,157 @@ +--- +title: SplashKit Expansion +sidebar: + label: Overview + order: 10 +--- + +import { Aside, Card, LinkCard, CardGrid, Icon } from "@astrojs/starlight/components"; + +## Contributing to splashkit-core + +This guide will cover all the steps required to get contributing to the splashkit-core repository. +Feel free to skip steps which you have already completed or are familiar with. + +If you haven't already, ensure you have setup your work environment by following the +[Setting up your environment guide](/products/splashkit/02-setting-up) + +### Creating Branch + +When modifying the repository, changes should be logically grouped together onto separate branches. +To create a branch, open a WSL terminal and navigate to the `splashkit-core` folder with: + +```shell +cd splashkit-core +``` + +Check the current branch with: + +```shell +git branch +``` + +Create a new branch using the current branch as a base: + +```shell +git branch {new branch name} +``` + +Swap to new branch with: + +```shell +git checkout {new branch name} +``` + +Now that a new branch is created and active, development can begin. + +### Building the Test Programs + +You cannot create new programs with splashkit-core as you do when using the traditional SplashKit +library. Instead, two programs are generated which can be configured to test its functionality: +`sktest` and `skunit_tests`. They are built with CMake using a preconfigured `CMakeLists.txt` file. +Open a WSL terminal and enter: + +```shell +cd +cd splashkit-core/projects/cmake +cmake -G "Unix Makefiles" . +make +``` + +The associated macOS and Linux commands can be found here: +[CONTRIBUTING](https://github.com/thoth-tech/splashkit-core/blob/develop/CONTRIBUTING.md) + +### Running the Test Programs + +To run the test programs, open a WSL terminal and enter: + +```shell +cd +cd splashkit-core/bin +``` + +Then for sktest: + +```shell +./sktest +``` + +Or for skunit_tests: + +```shell +./skunit_tests +``` + +### Making Changes + +`sktest` is built with the .cpp files from `~/splashkit-core/coreskd/src/test/`. To add your own +tests, modify one or more of the files such as `test_animation.cpp`. + +`skunit_tests` is built with the .cpp files from `~/splashkit-core/coreskd/src/test/unit_tests/`. +When it runs, all unit tests from all files in this folder are executed. Additional files can be +added to this folder if necessary. If adding a new file, copy the structure from one of the existing +unit test files. Critically, `#include "catch.hpp"` must be present in the file for it to be +compiled into `skunit_tests`. Beyond that, the hierarchy of, `TEST_CASE > SECTION > ASSERTION` +should be followed to improve readability and tracing of errors. + +### Testing Changes + +If a change is made to the code, the test programs need to be rebuilt. In a WSL terminal enter: + +```shell +cd +cd splashkit-core/projects/cmake +make +``` + +If any files were created or deleted, the CMake files need to be regenerated. In that case use: + +```shell +cd +cd splashkit-core/projects/cmake +cmake -G "Unix Makefiles" . +make +``` + +### Documenting Changes + +Local changes can be tested by building and running the test programs. However, once changes are to +be submitted for review, they need to be staged, committed and pushed. It is good practice to +perform multiple smaller commits with meaningful descriptions rather than a single monolithic +commit. In addition, pushing commits to GitHub provides a layer of backup in case of local machine +failure. + +### Creating a Pull Request + +Once you have completed work on a particular branch, a pull request (PR) can be made. At this point +there are now three relevant splashkit-core repositories at play: splashkit-core itself, +thoth-tech’s fork, and your personal fork. During trimester, PRs should be made against the +thoth-tech fork. The PR template provides a framework for how to structure the associated PR +documentation. + +The following guide details how to create PRs for the SplashKit Website. The same instructions can +be used for splashkit-core by simply changing the repository name: +[How to Create a Pull Request](/products/splashkit/04-pull-request). + +### Responding to Peer Reviews + +If changes are requested during a PR review, pushing further commits to the same branch will +automatically be added to the PR. + +### Performing Peer Reviews + +A critical component to SplashKit development is the process of reviewing your peers' PRs and +providing constructive feedback. This process has been detailed in the following guide: +[A Guide to Doing Peer Reviews](/products/splashkit/06-peer-review) + +### Planner Board + +The planner board is used to coordinate tasks while they are being completed and reviewed. The +following guide details the procedure and etiquette which is expected while using the planner board: +[Planner Board Ettiquete](/products/splashkit/07-planner-board) + +## Troubleshooting + +Solutions for common issues can be found below. Be sure to also check the following page for help +troubleshooting: +[Guide to resolving Common Issues](/products/splashkit/03-github-guide/#troubleshooting) diff --git a/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/peer-review-guide.mdx b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/peer-review-guide.mdx new file mode 100644 index 00000000..b7e34139 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/SplashKit Expansion/peer-review-guide.mdx @@ -0,0 +1,127 @@ +--- +title: Peer Review Guide +sidebar: + label: Peer Review Guide + hidden: true +--- + +import { Aside } from "@astrojs/starlight/components"; + +## Introduction + + + +In SplashKit, peer reviews are an essential part of maintaining high-quality code. The Peer-Review +Checklist provided below is required for every pull request and ensures that all contributions meet +a consistent standard across the project. This checklist covers essential aspects like code quality, +functionality, and testing. + +However, we recognize that every feature or task is different, and it’s difficult to capture all +potential review points in a single checklist. That’s why we’ve also included a set of Peer-Review +Prompts. These prompts are not mandatory but serve as a resource to guide the peer-review +discussion. Since peer reviews should always be collaborative, these prompts help ensure that the +review process is conversational and thorough, encouraging reviewers to think critically and explore +areas that may not be immediately obvious. + +Remember, the goal of peer reviews is not only to verify the quality of the code but also to foster +a collaborative environment where we improve together. + + + +### Splashkit Peer-Review Checklist + +```md +## General Information + +- [ ] Type of Change: Clearly indicate the type of change (choose one): + - [ ] Bug fix + - [ ] New feature + - [ ] Breaking change + - [ ] Documentation update + +## Code Quality + +- [ ] Repository: Is this Pull Request is made to the correct repository? (Thoth-Tech NOT SplashKit) +- [ ] Readability: Is the code easy to read and follow? If not are there comments to help understand + the code? +- [ ] Maintainability: Can this code be easily maintained or extended in the future? + +## Functionality + +- [ ] Correctness: Does the code meet the requirements of the task? +- [ ] Impact on Existing Functionality: Has the impact on existing functionality been considered and + tested? + +## Testing + +- [ ] Test Coverage: Are unit tests provided for new or modified code? +- [ ] Test Results: Have all tests passed? + +## Documentation + +- [ ] Documentation: Are both inline and applicable external documentation updated and clear? + +## Pull Request Details + +- [ ] PR Description: Is the problem being solved clearly described? +- [ ] Checklist Completion: Have all relevant checklist items been reviewed and completed? +``` + +### Splashkit Review Prompts + +- **Type of Change**: Does this Pull Request correctly identify the type of change (bug fix, new + feature, breaking change, or documentation update)? Is it aligned with the stated issue or task? + +- **Code Readability**: Is the code structure clean and easy to follow? Could it benefit from + clearer variable names, additional comments, or better organization? Would this code be + understandable for a new developer joining the project? + +- **Maintainability**: How maintainable is the code? Is it modular and easy to extend in the future? + Does it avoid creating technical debt? Is the codebase as simple as possible while still + accomplishing the task? + +- **Code Simplicity**: Are there any overly complex or redundant sections in the code? Could they be + refactored for better simplicity or clarity? Does the code follow established design patterns and + best practices? + +- **Edge Cases**: Does the implementation consider potential edge cases? What could go wrong with + this code in unusual or unexpected scenarios? Are there any cases that haven’t been fully + addressed? + +- **Test Thoroughness**: Are all key scenarios (including edge cases and failure paths) covered by + tests? Could additional tests help ensure the reliability of the code? Has the code been tested + across different environments (e.g., multiple browsers or platforms)? + +- **Backward Compatibility**: Does this change break any existing functionality? If so, has backward + compatibility been handled or documented appropriately? Are there any warnings or notes in the + documentation regarding compatibility? + +- **Performance Considerations**: Could this code have a negative impact on performance? Have any + performance concerns been documented and tested? Could the code be optimized for better efficiency + without sacrificing readability? + +- **Security Concerns**: Could this change introduce security vulnerabilities, especially in terms + of input validation or sensitive data handling? Have security best practices been followed? Does + this code ensure proper user data handling? + +- **Dependencies**: Are the new dependencies truly necessary? Could they create conflicts or issues + down the line, particularly during upgrades or with other libraries in the project? Is there a + simpler way to achieve the same functionality without adding new dependencies? + +- **Documentation**: Is the documentation clear and complete for both internal developers and + external users? Could a new developer understand how to use or modify this feature from the + documentation provided? Does it cover any API or external interface changes? diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Classes/execution-environment.md b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Classes/execution-environment.md new file mode 100644 index 00000000..f7fda184 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Classes/execution-environment.md @@ -0,0 +1,100 @@ +--- +title: ExecutionEnvironment - Code Documentation +description: An explanation of what ExecutionEnvironment is, its methods, members, and events. +--- + +[_executionEnvironment.js_](https://github.com/thoth-tech/SplashkitOnline/blob/main/Browser_IDE/executionEnvironment.js) + +ExecutionEnvironment is a class designed to abstract out running the user's code, and also handle +the environment itself (such as resetting variables, preloading files, etc). It contains functions +to 'compile' user code, run the main program, reset itself, and create directories/files inside the +environment. + +The actual implementation can be found inside `executionEnvironment.js`. Upon creation, it creates +an iFrame (which can be thought of as a page inside the page) - and this is where all the user's +code will be run. + +## Why create an iFrame? + +The iFrame it creates is sandboxed so that it cannot access anything inside the main page. This is +important, since while we can likely trust code the user writes themselves, we cannot trust code +they may receive from other people. If we ran the code the user writes directly inside the main +page, it could access and manipulate the IDE itself, along with accessing cookies and other things +it shouldn't have access to. By running it inside the iFrame, we can be sure it can't access +anything it shouldn't. + +It also makes it clear which files are part of the project (since those exist outside the iFrame), +and which parts are only transient, such as logs (that only exist inside the iFrame and are +destroyed on reloads). It means user code can not permanently overwrite resources. + +Additionally, it gives us a way to completely reset the environment the code is running in, as we +can destroy and recreate the iFrame without having to reload the main page itself. + +To communicate with the iFrame, we can only send and receive messages, which also limits the number +of potential escape routes from the iFrame. + +## Members + +- `hasRunOnce` - has the program been run yet? Is reset with `resetEnvironment()` +- `executionStatus` - current status of the program, can be: + - `ExecutionStatus.Unstarted` + - `ExecutionStatus.Running` + - `ExecutionStatus.Paused` + +## Methods + +- `constructor(container)` - takes a container element to load the iFrame inside. + +### Initializing user's code + +- `runCodeBlock(block, source)` - takes a code block (which has the block name `block`, and the + source code `source`, syntax checks it, and if it passes, sends the code to the iFrame via a + message. +- `runCodeBlocks(blocks)` - takes an array of dictionaries with the keys {name, code}, and calls + `runCodeBlock` for each one. + +### Running user's code + +- `runProgram()` - sends a message to the iFrame to run the user's `main` (if it exists). +- `pauseProgram()` - sends a message to pause the user's program - returns a `promise`, that + resolves once the program pauses, or fails after 2 seconds. +- `continueProgram()` - sends a message to continue the user's program (if it has been paused) +- `stopProgram()` - sends a message to stop the user's program completely - returns a `promise`, + that resolves once the program stops, or fails after 2 seconds. + +### Handling the environment + +- `resetEnvironment()` - completely resets the environment, by destroying and recreating the iFrame. + All files inside the environment will also be lost. +- `cleanEnvironment()` - Does a 'best-efforts' attempt to tidy the environment, such as removing + user created global variables. Much faster than `resetEnvironment()`, and does not reset the file + system. + +### Filesystem + +- `mkdir(path)` - sends a message to create a directory at `path` +- `writeFile(path, data)` - sends a message to write `data` to a file `path`, creating it if it does + not exist + +## Events + +The events can be listened to by attaching with `addEventListener(event, callback)` + +- `initialized` - the ExecutionEnvironment is setup and ready to execute code. +- `error` - an error has occurred in user code. Members: + - `message` - the error message + - `line` - the line number of the error + - `block` - the name of the code block the error occurred in. +- `programStarted` - the program has started running +- `programStopped` - the program has stopped running +- `programPaused` - the program has paused +- `programContinued` - the program has resumed running +- `onMovePath` - A file or directory has been moved. Members: + - `oldPath` - the original path + - `newPath` - the path it was moved to +- `onMakeDirectory` - A directory has been made. Members: + - `path` - the path to the new directory +- `onDeletePath` - A file or directory has been deleted. Members: - `path` - the path to the + file/directory +- `onOpenFile` - A file has been opened, possibly for reading or writing. Members: + - `path` - the path to the file diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Classes/idb-stored-project.md b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Classes/idb-stored-project.md new file mode 100644 index 00000000..062ebf8f --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Classes/idb-stored-project.md @@ -0,0 +1,100 @@ +--- +title: IDBStoredProject - Code Documentation +description: An explanation of what IDBStoredProject is, its methods, members, and events. +--- + +[_IDBStoredProject.js_](https://github.com/thoth-tech/SplashkitOnline/blob/main/Browser_IDE/IDBStoredProject.js) + +IDBStoredProject is a class that handles saving/loading the user's project within the browser +itself. It uses +[IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API/Using_IndexedDB) storage, +which allows it to store large amounts of data in a simplified database structure. + +It stores a single project inside a single database, creating a new one for each project. It has +functions to read and write files to a virtual filesystem saved inside the database (for storing +user code, and uploaded resources like sprites and sounds). It also has an area for config, and +keeps track of its lastWriteTime inside there. + +## Database layout + +There are two tables: + +- `project` - contains information about the project, such as the last write time. Simple key-value, + with the key's name being 'category'. +- `files` - stores all the user's files and directories. Each entry contains the following: + - `nodeID` - a numerical identifier for the node (file/directory), automatically increments. + - `name` - name of the file/directory + - `type` - either `"FILE"` or `"DIR"` - file or directory + - `data` - the file's contents - a binary blob of data. Or `null` if it's a directory. + - `parent` - the `nodeID` of the parent of the file/directory (what directory is it inside). -1 + means it is inside the root directory. + +## Members + +- `initializer` - a function that can be called to initialize the database - performs the equivalent + of `skm new` +- `projectName` - the name of the project (and therefore database) it is currently attached to. + `null` if detached. +- `lastKnownWriteTime` - the last time the project was written to within this tab. + +## Methods + +- `constructor(initializer)` - takes an initializer function, used when initializing a project's + database for the first time. +- `attachToProject(storeName)` - attaches it to a project with the name `storeName`. Initializes the + database, and emits an `attached` event. +- `detachFromProject()` - detaches itself from the project, resets its internal state and emits a + `detached` event. +- `deleteProject(storeName)` - deletes the project named `storeName`, and returns a promise which + resolves once the database is truly deleted. +- `checkForWriteConflicts()` - checks the `lastKnownWriteTime` against the actual `lastWriteTime` + inside the database - if they conflict in a way that suggests another tab has written to the + database, throws a `timeConflict` event. +- `access(func)` - a bit of a special function. This function is the only entry point to + reading/writing to the IDBStoredProject. It takes a function, which it will call, passing in a new + object (internally a `__IDBStoredProjectRW`), which has many more methods for reading/writing. + This is done, so that the opening/closing of the database can be wrapped around the user function, + without them having to handle it manually (and potentially leave open connections causing issues + later on). Here's an example of usage: + +```javascript +let storedProject = new StoredProject(...) +... +// we get passed a new object, which we called "project", and can use it to get the lastWriteTime. +// this is all performed asynchronously, so we need to "await" it to get the result +let storedTime = await storedProject.access((project)=>project.getLastWriteTime()); +// in non-lambda syntax +let storedTime = await storedProject.access(function(project){ return project.getLastWriteTime()}); +``` + +**The following functions are ones accessible from inside the callback to `access` only** + +- `getLastWriteTime()` - get the last write time. +- `updateLastWriteTime(time = null)` - set the last write time - defaults to the current time + (stored in unix time) +- `mkdir(path)` - make a directory at path, does nothing if it already exists. Emits + `onMakeDirectory` event. +- `writeFile(path, data)` - overwrites the data inside the file at `path` with `data` - creates the + file if it doesn't exist. Emits `onOpenFile` event. Also emits `onWriteToFile` event. +- `rename(oldPath, newPath)` - moves a file/directory to a new path and/or name. Emits `onMovePath` + event. +- `readFile(path)` - reads a file at `path` and returns the data inside. Returns `null` if the file + doesn't exist. +- `getFileTree()` - returns a complete tree of the file system, in a structure digestible by the + `TreeView`. + +## Events + +The events can be listened to by attaching with `addEventListener(event, callback)` + +- `attached` - Is attached and can be used. +- `detached` - Has been detached. +- `onMovePath` - A file or directory has been moved. Members: + - `oldPath` - the original path + - `newPath` - the path it was moved to +- `onMakeDirectory` - A directory has been made. Members: + - `path` - the path to the new directory +- `onDeletePath` - A file or directory has been deleted. Members: + - `path` - the path to the file/directory +- `onOpenFile` - A file has been opened, possibly for reading or writing. Members: + - `path` - the path to the file diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Classes/tree-view.md b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Classes/tree-view.md new file mode 100644 index 00000000..3bfb6691 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Classes/tree-view.md @@ -0,0 +1,83 @@ +--- +title: TreeView - Code Documentation +description: An explanation of what TreeView is, its methods, members, and events. +--- + +[_treeview.js_](https://github.com/thoth-tech/SplashkitOnline/blob/main/Browser_IDE/treeview.js) + +TreeView is a class used for displaying and updating a tree view, designed specifically around +file/directory manipulation. It allows viewing multiple filesystems at once in an overlapping +fashion (important since we have the files in the user's project that will be saved/loaded, and also +the live files inside the ExecutionEnvironment, which may be different). It allows files/folders to +be dragged around and organized, and folders to have a button on the side for uploading new files. + +The way it is intended to be used, is to make it listen to events from the target filesystems (such +as file moves/deletes), and update itself accordingly. When it is interacted with by the user, it +will emit its own events - these events should be listened to, and the target filesystem updated +accordingly. It should then look like this : + +1. A file is created in the target filesystem and an event is emitted +2. The TreeView reacts to this event and creates a node in its tree with the same name. +3. The user now drags that node to inside another node (directory), and the TreeView emits an event. + Note that it does _not_ change itself here. The node inside the tree has not actually moved yet. +4. A function is called back from this event, that then tells the target filesystem to move the + file. +5. The target filesystem moves the file, and an event is emitted. +6. The TreeView reacts to this event, and moves the node to inside the directory. + +See how the TreeView never updates itself - it relies on an event coming _back_ from the target +filesystem. This means that if the target filesystem fails to do the operation for whatever reason, +the TreeView also remains in the same state, meaning the two remain synchronized effectively. + +See example usage of it inside `fileview.js` +([here](https://github.com/thoth-tech/SplashkitOnline/blob/main/Browser_IDE/fileview.js)), where it +is attached to both the `IDBStoredProject` filesystem, and also the filesystem inside the +`ExecutionEnvironment`. + +### Limitations + +Currently there is no way to delete files/folders, or rename files/folders in the interface itself. +This shouldn't be hard to add, however. + +## Members + +None publicly available. + +## Methods + +- `constructor(container, FSes)` - takes a container to place the TreeView's elements into, and a + list of FSes, which are the filesystems it will support. An example list looks like this + `{"persistent":"node-persistent", "transient":"node-transient"}`, key-value pairs where the key is + the filesystems name, and the value is a css style to apply to nodes inside this filesystem. +- `moveNode(oldPath, newPath, index = -1, FS)` - moves a node to a new path and/or name. Allows one + to set the index the node will appear at, and also which filesystem(s) (a list) the move occurred + in. +- `deleteNode(path, FS)` - deletes a node from a set of filesystem(s) (a list) +- `addDirectory(path, FS)` - make a directory at path, does nothing if it already exists. Allows one + to set which filesystem(s) (a list) the directory add occurred in. +- `addFile(path, data)` - make a file at path, does nothing if it already exists. Allows one to set + which filesystem(s) (a list) the file was added in. +- `reset(path)` - Deletes all nodes. +- `populatefileView(files, FS)` - Populates the tree with a list of files in a particular structure + (the same one `IDBStoredProject.getFileTree()` returns). Allows one to set which filesystem(s) (a + list) the directory add occurred in. + +## Events + +The events can be listened to by attaching with `addEventListener(event, callback)` + +- `nodeMoveRequest` - A file or directory has been moved. Members: + - `treeView` - the TreeView object + - `oldPath` - the original path + - `newPath` - the path it was moved to + - `FS` - the filesystem(s) the change occurred in. + - `accept` - a function that can be called to announce that the change was successful - + **currently unused**. +- `folderUploadRequest` - The 'add file' button was clicked on a directory. Members: + - `treeView` - the TreeView object + - `path` - path to the directory + - `FS` - the filesystem(s) the directory exists in. +- `nodeDoubleClick` - A file node has been double clicked. Members: + - `treeView` - the TreeView object + - `path` - path to the file + - `FS` - the filesystem(s) the directory exists in. diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Other/folder-structure-overview.md b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Other/folder-structure-overview.md new file mode 100644 index 00000000..ad3454e6 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Other/folder-structure-overview.md @@ -0,0 +1,128 @@ +--- +title: Overview of SplashKit Online's Folders and Files +description: + An overview of what all of SplashKit Online's folders and files contain, and how they relate. +--- + +## Introduction + +This document is a brief overview of how SplashKit Online's folders are structured, with short +descriptions on what each file contains. If you're looking for a particular piece of code, maybe +this will help! + +## Structure + +### Browser_IDE + +This folder contains all the files relevant to the in-browser IDE. This includes front-end and +back-end Javascript, html, css, libraries, etc. + +#### Folders + +`node_modules` - All the installed node libraries. + +`splashkit` - Where the SplashKit WebAssembly library build goes! Compiled from the SplashKitWasm +folder. + +#### Files + +##### Node Files + +The following files are used when running as a node project + +`server.js` - serves the main index, and sets up routing for the libraries. + +`package.json` - The list of packages/libraries and versions that the project uses. + +##### Main Editor + +The following files are used inside the main page (`index.html`) + +`index.html` - The editor's html itself - contains a simple layout and some placeholder elements for +the file view, ExecutionEnvironment, and code editors to load into. + +`editorMain.js` - The main file that handles setting up the IDE. It loads the code editors, the +project, shows/updates the run/stop buttons, and also performs saving, loading, and file mirroring. +It also creates the ExecutionEnvironment, and IDBStoredProject on startup. + +`IDBStoredProject.js` - Holds the IDBStoredProject class, which handles saving/loading the user's +project to/from internal browser storage. See +[IDBStoredProject](/products/splashkit/documentation/splashkit-online/code-documentation/classes/idb-stored-project) +for internal documentation. + +`executionEnvironment.js` - Holds the ExecutionEnvironment class, which handles 'compiling' and +running the user's code in a safe way. See +[ExecutionEnvironment](/products/splashkit/documentation/splashkit-online/code-documentation/classes/execution-environment) +for internal documentation. + +`treeview.js` - Holds the TreeView class, used to display a tree view targeted at showing a +filesystem. See +[TreeView](/products/splashkit/documentation/splashkit-online/code-documentation/classes/tree-view) +for internal documentation. + +`fileview.js` - Creates an instance of the TreeView class, hooks it into the IDBStoredProject and +ExecutionEnvironment's filesystems, and places it on the main page. + +`modal.js` - A utility file with a function for creating modals. + +`projectInitializer.js` - Contains demo code (as text) and the function used to initialize the +default project - does something similar to `skm new`. + +`stylesheet.css` - Contains the styles for the editor, primarily related to the TreeView but also +the code editors and other areas. + +`splashkit-javascript-hint.js` - Contains code to handle autocompletion in the code editors, +including loading `splashkit_autocomplete.json` + +`splashkit_autocomplete.json` - Contains data on all the SplashKit functions, classes and enums. + +##### Internal Execution Environment + +The following files are used inside the isolated iFrame (inside the Execution Environment) +(`executionEnvironment.html`) + +`executionEnvironment.html` - The Execution Environment's main page, contains a simple layout with +placeholders for where the canvas and terminal should go. + +`executionEnvironment_Internal.js` - Internal code for the ExecutionEnvironment. Handles receiving +messages from the main page's ExecutionEnvironment object, 'compiling', and running the user's code. + +`executionEnvironment_CodeProcessor.js` - Handles processing the user's code, transforming and +modifying it so that it can be properly paused, restarted, etc. + +`loadsplashkit.js` - used to load the SplashKit Wasm library. + +`fsevents.js` - creates an eventTarget that can be used to listen to filesystem events inside the +virtual filesystem (that the SplashKit Wasm library can access). + +`stylesheet.css` - Same as in [Main Editor](#main-editor). + +### SplashKitWasm + +This folder contains the files related to _building_ SplashKit so that it can run inside the +browser - the output from this build is then copied into Browser_IDE, where the library is used! + +`cmake` - The cmake project - used to build the SplashKit Wasm library! + +`external` - Contains the `splashkit-core` submodule, which contains all of SplashKit's code. + +`stubs` - A couple of stubs (files with empty functions) used to help compile SplashKit despite +certain functionality missing. + +`tools` - Tools used during compilation, particularly in relation to generating C++ to Javascript +bindings. + +`generated` - Files generated during the build process. + +`out` - Contains the built library! This is also copied straight into `Browser_IDE/splashkit` during +the build. + +### DemoProjects + +This folder contains a set of demo projects (just zip files) that can be loaded into the IDE for +testing, demonstration, or learning purposes. + +### .archive + +This folder contains an archive of previous trimester's work, primarily around some sort of login +system. currently unneeded but perhaps can be repurposed at some point. diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Processes/cpp-js-binding-generation-overview.md b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Processes/cpp-js-binding-generation-overview.md new file mode 100644 index 00000000..cc7ba475 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Processes/cpp-js-binding-generation-overview.md @@ -0,0 +1,424 @@ +--- +title: C++ <-> JavaScript Binding Generation Overview +description: + A detailed explanation as to the how and why of SplashKit Online's new binding generator. +--- + +## Introduction + +The only data type that can currently be passed to and from WebAssembly functions are integers. The +SplashKit API requires us not only to be able to pass numbers, but also vectors, structs, vectors of +structs, function pointers, and so on. Because of this, there is a necessity to generate _bindings_, +which are able to translate and transfer the data we need across the C++/JavaScript boundary. + +We originally used the WebIDL Binder tool to accomplish this, but it had several major flaws: + +- It did not support arrays of strings, nor structs +- It did not support arrays of arrays (e.g `matrix_2d` could not be represented) +- It would allocate memory for structs on the C++ side using malloc and only provide a pointer on + the JavaScript side. As JavaScript has no concept of a destructor, this completely ruined value + semantics and required manual freeing of even basic SplashKit types, such as colour. +- It would return struct types via a pointer to a singleton for that function. Therefore the + following code: + ```javascript + let colorA = rgba_color(1, 0, 0, 0); // Red; colorA points to the 'rgba_color return-singleton' + let colorB = rgba_color(0, 1, 0, 0); // Green; overwrites the 'rgba_color return-singleton' + // Right now colorA and colorB both point to the same 'color' - bad! + fill_rectangle(colorA * /Should be red*/, 300, 300, 200, 200); // this actually ends up green! + ``` + would draw a green rectangle, rather than a red one. +- It had no support for function overloads, making the JavaScript API more cumbersome to use and + different from usual C++ samples. + +Embind was also looked at, but also suffered from fundamental issues (see +[here](https://github.com/emscripten-core/emscripten/issues/6492) for one major issue). Thus it was +decided that a new solution was required. + +## New Solution + +The new solution was written from scratch in Python. The fundamental way it works is as follows: + +- Structs are represented as proper JavaScript objects. +- When a function is called that needs to pass a struct to the C++ side, space is allocated on the + WebAssembly stack, and the data for that object is copied from the JavaScript object. Then, a + pointer to that location on the stack is passed into the C++ function, which operates as normal. +- Similarly, if the C++ returns a struct, space is preallocated on the stack, and the C++ function + writes its return result into that space. +- Vectors are instead allocated on the heap and data copied into that space. The function is then + passed/passes back two parameters - a pointer to that location on the heap, and a count. On the + C++ side, a vector is constructed and copies the items from/to that block of memory. + +Despite the extra copying compared to the previous solution, because of several other optimizations, +it has been demonstrated to be 2x more performant than WebIDL Binder, while maintaining proper value +semantics and vastly enhanced support of SplashKit's API - in fact, there is not a single function +that cannot be called now. + +We can see an example of how this works with a simple function. Let's look at how +`string matrix_to_string(const matrix_2d &matrix)` is handled: The following is the C++ wrapper, +with some additional comments added: + +```c++ + // CPP_matrix_to_string is the wrapper function. As can be seen, it directly takes a reference to a matrix, and returns a char* pointer rather than a std::string + char* EMSCRIPTEN_KEEPALIVE CPP_matrix_to_string(const matrix_2d& matrix){ + // Here we call the SplashKit function, and store the result. + string __conv_0_out = matrix_to_string(matrix); + // Next we initialize the output variable + char* _out = (char*)0; + // And then allocate the string on the heap, cpoy the data out, and save the pointer. + heapAllocateString(_out, __conv_0_out); + // We then return the pointer. + return _out; + } +``` + +The JavaScript side has much more work to do - again with added comments as explanation: + +```javascript +// This is the JavaScript function +function matrix_to_string(matrix) { + // First we verify the type of the object passed in, and throw a useful error message if its incorrect. + if (typeof matrix !== "object" || matrix.constructor != matrix_2d) + throw new SplashKitArgumentError( + "Incorrect call to matrix_to_string: matrix needs to be a matrix_2d, not a " + typeof matrix, + ); + // We also check the argument count + if (arguments.length != 1) + throw new SplashKitArgumentError( + "Incorrect call to matrix_to_string: expects 1 parameters, not " + String(arguments.length), + ); + + // Now we allocate space on the stack. First we save the current stack address + let st = wasmExports.stackSave(); + // We then allocate space for the output char* pointer. Wasm is 32-bit by default, so 4 bytes + let _out_ptr0 = wasmExports.stackAlloc(4); + // We then allocate space for the matrix, 72 bytes + let matrix_ptr0 = wasmExports.stackAlloc(72); + let __conv_0_out; + // We write out the values of the matrix into that address in the stack + matrix.write(matrix_ptr0); + try { + // Now we call the C++ function CPP_matrix_to_string + // We pass in the pointer to that stack allocated matrix and save the returned char* + __conv_0_out = wasmExports.CPP_matrix_to_string(matrix_ptr0); + let _out; + // Now we convert the heap allocated string to a JavaScript string + _out = HeapStringToJSString(__conv_0_out); + // And return it! This will also trigger the 'finally' below + return _out; + } finally { + // We make sure to deallocate the string from the heap + DeallocHeapString(__conv_0_out); + // And also restore the stack to where it was before we allocated extra things onto it + wasmExports.stackRestore(st); + } + + // Some more error handling - this doesn't apply for this function as there is only a single + // overload, but for other functions this is a useful fallback. + if (true) + throw new SplashKitArgumentError( + "The parameters passed to this function don't match any of its overloads.\n" + + "You called matrix_to_string(" + + user_params_to_string(arguments) + + ")\n" + + "Please use one of the following overloads:\n" + + " string matrix_to_string(matrix_2d matrix)\n", + ); +} +``` + +Finally, we can have a look at the JavaScript class for matrix_2d, to get an idea of what 'write' +does: + +```javascript +class matrix_2d { + constructor(elements) { + this.elements = + elements ?? + (function () { + let a0 = new Array(3); + for (let i0 = 0; i0 < 3; i0++) { + let a1 = (a0[i0] = new Array(3)); + for (let i1 = 0; i1 < 3; i1++) { + a1[i1] = 0; + } + } + return a0; + })(); + } + + static checkCPPMapping() { + assert( + 0 == wasmExports.matrix_2d_elements_offset(), + "Wrong offset! matrix_2d.elements| 0 != " + String(wasmExports.matrix_2d_elements_offset()), + ); + assert( + 72 == wasmExports.matrix_2d_size(), + "Wrong class size! matrix_2d| 72 != " + String(wasmExports.matrix_2d_size()), + ); + } + + // This is where we write the elements of the matrix onto the stack + write(ptr) { + // We are writing doubles, so we adjust our pointer for accessing doubles by dividing by 8 (bytes) + let elements_ptr = (ptr + 0) >> 3; + for (let i0 = 0; i0 < 3; i0++) { + for (let i1 = 0; i1 < 3; i1++) { + // This is the exact line where we write into WASM memory + Module.HEAPF64[elements_ptr] = this.elements[i0][i1]; + elements_ptr += 1; + } + } + } + read(ptr) { + let elements_ptr = (ptr + 0) >> 3; + for (let i0 = 0; i0 < 3; i0++) { + for (let i1 = 0; i1 < 3; i1++) { + this.elements[i0][i1] = Module.HEAPF64[elements_ptr]; + elements_ptr += 1; + } + } + } +} +``` + +The job of the new binding generator is to generate functions and classes like this for every +function and every structure in the SplashKit API. It also has to handle generating functions for +`#defines` such as `COLOR_WHITE`, and creating function pointers on the JavaScript side and passing +them to the C++ side. + +## The Binding Generation Code - Brief Overview + +Let's now have a brief look at how the binding generation code works. There is quite a lot to it, +but here's an overview. + +### Setup + +We start with `__main__` inside `generate_javascript_bindings_and_glue.py`, which takes as arguments +the input SplashKit API json file, the output names for the C++/JS files respectively, and finally a +true/false parameter that specifies whether to emulate function overloading in the output +JavaScript. + +First it reads in the API: + +```python +# Read the api +api = read_json_api(api) +``` + +Next it creates a 'TypeEnvironment', which includes information on all basic C++ types (such as int, +float, etc), and also SplashKit structures, including size and offsets of members. The class can +also be used to resolve typedef'd types, determine if a type is a primitive, and so on. The code for +this class can be found inside `type_environment.py`, and here's how its used. + +```python +# Compute memory information about all the types +types_env = compute_type_memory_information(api) +``` + +From here, if function overloading emulation is enabled, we modify the set of functions we will be +generating code for. We detect all the functions that need to be considered overloads of each other, +and then make the parameter names identical between them, based on the longest function. This makes +the emulation later on possible, where we then detect the number of arguments and their types to +dispatch the correct C++ function. Here's an example of what it does. + +``` +The following overloads: +Draw Circle (clr: color, c: circle, ) +Draw Circle (clr: color, c: circle, opts: drawing_options, ) +Draw Circle (clr: color, x: double, y: double, radius: double, ) +Draw Circle (clr: color, x: double, y: double, radius: double, opts: drawing_options, ) + +would become the following: +Draw Circle (clr: color, c: x, ) +Draw Circle (clr: color, c: x, opts: y, ) +Draw Circle (clr: color, x: double, y: double, radius: double, ) +Draw Circle (clr: color, x: double, y: double, radius: double, opts: drawing_options, ) +``` + +None of the types have been changed - purely the names of the parameters. This is the code that +handles it: + +```python +if enable_overloading: + functions = copy.deepcopy(functions) + make_function_overloads_consistent(functions) +``` + +and the function `make_function_overloads_consistent` is inside `glue_generation.js` + +### Marshal Strategy Generation + +The next line is pretty important + +```python +# Generate all the code needed to marshal the data needed for each function +marshalled_functions = compute_marshalled_functions(types_env, functions) +``` + +This `compute_marshalled_functions` is going to take the set of functions, and for each function, +decide on and store the specific strategies it will use to pass each of its parameters and return +value. Not much code is generated in this step, but it is by far the most important. Let's quickly +look at the classes that store the data it computes: + +```python +class MarshaledFunction: + ''' A class storing information about a function that contains + all the information needed for the final code-gen''' + + def __init__(self, name, unique_name, inouts): + self.name = name + self.unique_name = unique_name + self.inouts = inouts +``` + +The `MarshalledFunction` has a `name` (its generic name), a `unique_name` (a name used when function +overloading is unavailable), and then `inouts` - which contain both parameters and return values. + +The `inouts` are all of type `MarshaledParam`, which looks as follows: + +```python +class MarshaledParam: + '''Class that stores all the information needed to generate code to pass a + parameter in/out from JS/C++''' + + def __init__(self, name, cpp_type, is_class_member=False, index=""): + self.name = name + self.is_class_member = is_class_member + self.index = index + + # The final computed types + self.cpp_type = copy.deepcopy(cpp_type) + self.boundary = [copy.deepcopy(cpp_type)] + self.js_type = copy.deepcopy(cpp_type) + + # Information about the parameter + self.is_return = False + self.return_output_via_return = False + self.write_in = True + self.write_out = True + + # The generated code used on the C++ side + self.cpp_convert_in = "" + self.cpp_out_params = [] + self.cpp_convert_out = "" + self.cpp_return = "" + + # The generated code used on the JavaScript side + self.js_alloc_sizes = [] + self.js_convert_in = "" + self.js_write_ref = "" + self.js_declare_ref = "" + self.js_read_ref = "" + self.js_out_params = [] + self.js_convert_out = "" + self.js_dealloc = "" + self.js_new = "" + self.js_constructor = "" + self.js_type_check = "" + self.js_return = "" +``` + +I won't explain every field - but hopefully it can be seen that it's storing information and small +snippets of code that will be used when converting and transferring data across the C++<->JavaScript +boundary. These types are all found inside `marshalling.py`, while the overall strategies/functions +are found in `marshalling_strategies.py` + +Back to `compute_marshalled_functions`, all it does internally is call +`calculate_marshalled_function` for each function, which then calls `marshal_parameter` for its +parameters and return value. + +`marshal_parameter` then looks at the parameter passed in, and decides based on the parameter's +type, whether it's a reference type, const, etc, how its going to be passed. These specific +decisions are detailed in comments in the code. + +Finally, at the bottom of the function it then dispatches which specific method it will marshal the +data with - we can see what that looks like here: + +```python + # Arrays require special handling + if len(array_dims) > 0: + pass_c_array(types_env, marshaled_param, address_and_divisor) + # Handle passing JS functions (for callbacks and such) + elif boundary_type.function_type != None: + pass_js_function(types_env, marshaled_param, address_and_divisor) + # If the type is a vector, then we need to pass it in via a heap allocation + elif boundary_type.typename == "vector" and value_like(boundary_type): + heap_allocate_vector_to_array(types_env, marshaled_param, address_and_divisor) + # If it's a string, similarly we pass it in by heap allocating it and passing the pointer + elif boundary_type.typename == "string" and value_like(boundary_type): + heap_allocate_string(types_env, marshaled_param, address_and_divisor) + # If type is a non primitive type, then ensure it is a passed by pointer at least + elif not types_env.is_primitive(boundary_type.typename) and value_like(boundary_type): + pass_value_struct_as_pointer(types_env, marshaled_param, address_and_divisor) + # If type is just a typedef for a pointer, wrap it as it comes in/out + elif marshaled_param.cpp_type.typename in types_env.api.typedefs: + pass_typedefed_pointer(types_env, marshaled_param, address_and_divisor) + # If type is a primitive type, pass it as it is + elif types_env.is_primitive(boundary_type.typename) or boundary_type.is_pointer(): + pass_primitive(types_env, marshaled_param, address_and_divisor) + else: + assert False, "Couldn't marshal type!\n"+str(param) + +``` + +The code for each of those functions is quite long and detailed, but almost every line has been +commented to explain the decisions it is making, so feel free to have a look inside +`marshalling_strategies.py` + +After computing our `MarshalledFunction`s, we finally get to code generation output. C++ code +generation utilities are found inside `cpp_code_gen.py`, while JavaScript code generation is found +inside `js_code_gen.py`. They contain functions for generating struct definitions, function bodies, +declarations, and so on, all based around `MarshalledFunction`. + +`glue_generation.py` then uses these functions to assemble the final code, which is called via the +following two lines in `__main__` + +```python +# Generate all the final glue code +generate_cpp_glue(api, marshalled_functions, output_cpp) +generate_js_glue(types_env, api, marshalled_functions, output_js, enable_overloading) +``` + +There are a few other files I haven't mentioned, so here's a complete listing of every file and its +contents: + +- `generate_javascript_bindings_and_glue.py` - holds the terminal script that takes as input the + SplashKit API along with the output file paths, and performs the binding. +- `json_api_reader.py` - provides functions/classes to read in the SplashKit API and make it more + convenient to process later on +- `js_binding_gen/streaming_code_indenter.py` - a small class that is used to automatically indent + the generated code. +- `js_binding_gen/type_environment.py` - contains the `TypeEnvironment` class, used to query + sizes/layouts of built-in and SplashKit specific types. +- `js_binding_gen/marshalling.py` - contains the `MarshalledFunction` and `MarshalledParam` types, + which contain all the information needed for final code generation. +- `js_binding_gen/marshalling_strategies.py` - holds all the functions and logic needed to create + the `MarshalledFunction`s. +- `js_binding_gen/js_code_gen.py` - contains code generation functions for JavaScript; e.g function + calls, class definitions, etc. +- `js_binding_gen/cpp_code_gen.py` - contains code generation functions for C++; e.g function calls, + declarations, etc +- `js_binding_gen/glue_generation.py` - contains methods that use the code generation utilities to + actually generate the final output code. Also handles function overload emulation. +- `js_binding_gen/javascript_bindings_preamble.py` - contains lengthy code included in the generated + JS/C++ that defines various utility functions used. + +## Known Limitations + +There is only one known limitation currently. Functions that take a reference to a fundamental type, +and return data to that reference, cannot be expressed in JavaScript. The only function this is +known to affect is +`point_2d closest_point_on_lines(const point_2d from_pt, const vector &lines, int &line_idx)`, +as the number passed into `line_idx` will not change. There is no way to fix this in JavaScript at +the present time - the best we could do is make the user wrap their 'int' into a temporary object, +and then retrieve the updated value from that object after calling the function. + +## Wrap-up + +The new bindings generator has exposed vastly more SplashKit API functionality for use in +JavaScript. It fixes strange behaviors that the old bindings exhibited, that would have resulted in +confusion, especially for beginner programmers. Finally, It simplifies the usage of SplashKit Online +by making the JavaScript code look and behave almost identical to the equivalent C++ code, making it +easier to follow existing guides and API documentation. While it introduces more technical +complexity, it is a far more complete solution than the previous one, and should continue to prove +useful as SplashKit Online develops. diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Processes/how-splashkit-online-runs-code.md b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Processes/how-splashkit-online-runs-code.md new file mode 100644 index 00000000..6f564bab --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Code Documentation/Processes/how-splashkit-online-runs-code.md @@ -0,0 +1,815 @@ +--- +title: How SplashKit Online runs the user's code! +description: + A detailed explanation as to all the steps SplashKit Online takes to execute the user's code. +--- + +## Introduction + +This document is a deep dive into how SplashKit Online runs the user's code. This is a multi-step +process that will take us through much of SplashKit Online's code, so get ready! + +## Overview + +Here's a _very_ brief overview of how it works. Don't worry if you don't understand what this means +yet! Each part will be explained in due time - but feel free to use this as a reference of the +overall process. + +1. Before the user does anything... + 1. The IDE starts up, and creates an ExecutionEnvironment. + 2. The ExecutionEnvironment creates an iFrame, and loads SplashKit inside it. +2. User writes code into the code editor (currently there are two 'code blocks', General and Main). +3. User presses the Run button. First we have to run the code blocks, to create all the user's + functions/classes and initialize global variables. +4. Pressing run calls `ExecutionEnvironment.runCodeBlocks`, passing in the General Code and Main + Code code blocks. For each code block: 1. The code block's text is sent as an argument to + `ExecutionEnvironment.runCodeBlock(block, source)` 2. The source code gets syntax checked. 3. If + it is syntactically correct, it is then sent as a `message` into the ExecutionEnvironment's + iFrame. +5. The following steps all happen inside the iFrame (for security purposes) + 1. The iFrame receives the message. + 2. The code is transformed to make it runnable within the environment + 3. A real function is created from the transformed code. + 4. **The code is run!** +6. Now it needs to run the user's main: `ExecutionEnvironment.runProgram()` is called. +7. This sends a message into the iFrame. +8. The following steps all happen inside the iFrame (for security purposes) + 1. The iFrame check if the user has created a `main()` + 2. **If so, `main()` is run!** + +:::note + +If you're wondering why the user's 'code blocks' get run, and only _then_ the user's main program +gets run, here's why. JavaScript is a completely dynamic language, so unlike compiled languages like +C++, functions and classes and so on aren't known ahead of time. Instead, the creation of a +function/class itself is runtime code. The code + +```javascript +function myFunction() { + return 4; +} +myFunction(); +``` + +is _run_, to create a function called `myFunction`, that can now be called later on. + +In a similar way, functions themselves are just objects, and can be assigned as follows: + +```javascript +let myFunction = function () { + return 4; +}; +myFunction(); +``` + +When we first run the user's code blocks, we are creating all their functions and classes and global +variables. + +Only after this is done, can we then call `main()`, and start the program itself. But as you know +now, in a way it was running the whole time. + +::: + +## Before the user does anything + +Looking inside `editorMain.js` + +```javascript +// ------ Setup Project and Execution Environment ------ +let executionEnviroment = new ExecutionEnvironment(document.getElementById("ExecutionEnvironment")); +``` + +_from +[editorMain.js](https://github.com/thoth-tech/SplashkitOnline/blob/main/Browser_IDE/editorMain.js)_ + +First, an `ExecutionEnvironment` is created. + +From the +[Source Code Documentation](/products/splashkit/documentation/splashkit-online/code-documentation/classes/execution-environment) + +> ExecutionEnvironment is a class designed to abstract out running the user's code, and also handle +> the environment itself (such as resetting variables, preloading files, etc). It contains functions +> to 'compile' user code, run the main program, reset itself, and create directories/files inside +> the environment. + +When created, an important thing it does is create an iFrame (sort of a page inside the page), which +is where all code execution will take place. This is done for security, see +[here](/products/splashkit/documentation/splashkit-online/code-documentation/classes/execution-environment/#why-create-an-iframe) +for a more detailed explanation. + +Inside the iFrame, the page `executionEnvironment.html` is loaded, which loads in things like the +SplashKit library itself, and also the executionEnvironment internal scripts, like +`executionEnvironment_Internal.js` and `executionEnvironment_CodeProcessor.js` + +Once the environment finishes loading, it sends out an `initialized` event - this is when all the +green buttons in the interface become usable, and code can be executed! + +## User writes their code, then presses run + +Pressing the run button does three things: + +```javascript +clearErrorLines(); + +runAllCodeBlocks(); +/* This is what it looks like inside "runAllCodeBlocks": +executionEnviroment.runCodeBlocks([ + {name: "GeneralCode", code: editorInit.getValue()}, + {name: "MainCode", code: editorMainLoop.getValue()} +]); +*/ + +executionEnviroment.runProgram(); +``` + +_from +[editorMain.js - runProgram()](https://github.com/thoth-tech/SplashkitOnline/blob/ddb06cec6296d6de905ee0a90084a4c1a71c7a58/Browser_IDE/editorMain.js#L194C6-L194C6)_ + +1. First it clears the error lines from the code editors. +2. Next, it calls `executionEnviroment.runCodeBlocks`, and gives it the two code blocks and the + source code inside the code editors; this runs the user's code, which really means runs all the + function/variable/class initialization. +3. Finally it runs the program - this runs the user's `main` function. Let's look at step 2 more + closely. + +## Pressing run calls `ExecutionEnvironment.runCodeBlocks`, passing in the General Code and Main Code code blocks + +We can see by looking at the source code, that `runCodeBlocks` just calls `runCodeBlock` for each +block passed in. + +```javascript +runCodeBlocks(blocks){ + for (let block of blocks){ + this.runCodeBlock(block.name, block.code); + } +} +``` + +_from +[executionEnvironment.js](https://github.com/thoth-tech/SplashkitOnline/blob/main/Browser_IDE/executionEnvironment.js)_ + +So let's have a look at `runCodeBlock` + +```javascript +runCodeBlock(block, source){ + // Syntax check code - will throw if fails. + this._syntaxCheckCode(block, source); + + this.iFrame.contentWindow.postMessage({ + type: "RunCodeBlock", + name: block, + code: source, + }, "*"); +} +``` + +_from +[executionEnvironment.js](https://github.com/thoth-tech/SplashkitOnline/blob/main/Browser_IDE/executionEnvironment.js)_ + +First thing it does is call the internal function `_syntaxCheckCode(block, source)`, which as the +name says, will syntax check the code. The way this syntax checking works is somewhat complicated, +but let's step through it. + +### Some backstory (optional reading) + +Just as a precursor, in JavaScript there are multiple ways to execute code that the user provides as +text. One way is to use the function `eval`, for example you can run + +```javascript +eval("alert('Hello!');"); +``` + +and this will pop up a box, as if you had directly run + +```javascript +alert("Hello!"); +``` + +This method combines syntax checking and running together - first the browser syntax checks the +code, and then it runs it. However, we want to syntax check the code _before_ running it. The main +way to do this, is to create a _`Function` object_ from the source code. The browser will syntax +check the code when making it, without running it yet. As will be explained later, it turns out we +actually _need_ to make a `Function` object anyway, for certain important features like pausing the +code and allowing while loops. + +This can be as simple as + +```javascript +let myFunction = new Function("alert('Hello!');"); +``` + +However, we also need to be notified of any errors that occur, so we can tell the user about them. +If you are familiar with JavaScript, you might suggest a `try/catch` block, like this: + +```javascript +try { + let myFunction = new Function("alert('Hello!');"); +} catch (error) { + // tell the user about the error +} +``` + +It 'tries' to create the new function, and if it fails, we catch the error. It turns out we can get +the error message and line number from that `error`, so this seems like it will work. The problem +with this, is that the actual 'error' that occurred, technically happened on the line where +`new Function(...)` was called, and not the line inside the user's code, meaning the line number we +get back is useless. So instead the method described next is what was used. + +### Syntax Checking + +The method used for syntax checking is to create a `Function` object from the user's source code, +which lets us do the syntax check without running the code. For reasons that will be explained +later, we actually create an `AsyncFunction`, which will let us run the code in a more flexible way +later on. + +To retrieve any syntax errors that might occur when checking, we listen to the main window's `error` +event, which reports any errors that happen, and where they happened. + +So the code to perform the syntax check looks a bit like this: + +``` +Attach to the "error" event + If the event gets called next, report the error to the user. + +Create the function - if the syntax check fails, the "error" event will get called, and the function will fail here. + +Detach from the "error event" +``` + +One important aspect of implementing this, is that inside the sandboxed iFrame, the information we +get in the `error` event is very unhelpful - the line number is always 0, and the error message is +very generic. Luckily, since we are just syntax checking (and not _running_) the code, we can just +do the syntax check inside the main page instead of the iFrame - so this is what happens. + +Once the code passes syntax checking, it is sent into the iFrame for the next steps. Let's have a +look at the code running inside the iFrame that receives the code: + +```javascript +if (m.data.type == "RunCodeBlock") { + let processedCode = ""; + try { + processedCode = processCodeForExecutionEnvironment( + m.data.code, + "mainLoopStop", + "mainLoopPause", + "mainLoopContinuer", + "onProgramPause", + ); + + tryEvalSource(m.data.name, processedCode); + } catch (e) { + ReportError(userCodeBlockIdentifier + m.data.name, "Unknown syntax error.", null); + } +} +``` + +_from +[executionEnvironment_Internal.js](https://github.com/thoth-tech/SplashkitOnline/blob/ddb06cec6296d6de905ee0a90084a4c1a71c7a58/Browser_IDE/executionEnvironment_Internal.js#L248C10-L248C10)_ + +Let's break this down. First, it tries to run `processCodeForExecutionEnvironment`, passing in the +user's code and some other parameters. We'll see what that does in a moment, but for now, know that +it takes the user's code, and _changes it_, to allow us to pause it, resume it, reset it, etc. +Assuming it's successful, then we move to `tryEvalSource`, which makes a new `AsyncFunction` from +this modified source code, and then runs it! Remember, these stages all take place securely inside +the iFrame. + +Let's look at how the code modification/transformation works, and why we do it. + +## The code is transformed to make it runnable within the environment + +### Code Transformation + +#### Why do we modify/transform the user's code? + +There are a couple of things that we want the user's code to be able to do, that's impossible to +support without modifying their code. + +##### We want them to be able to have infinite while loops + +It's pretty normal to have code that looks like this in a C program: + +```c +void main(){ + bool quit = false; + while(!quit){ + ...do stuff... + } +} +``` + +where it just loops and loops until the user quits. However, in a browser, JavaScript is executed on +the same thread as the page. So normally the browser might do something like this: + +1. Check for user input +2. Update the page +3. If the user clicks the button, **run some JavaScript** +4. Goto 1 + +Which works fine if the 'run some JavaScript' part ends quickly. But if it enters a loop, like in +the code above, then the browser won't be able to check for input or even update the page until the +code ends - if it's an infinite loop like above, the page can only crash. + +What's the solution? We modify loops inside the user's code, so that they give control _back_ to the +browser periodically. This is done with JavaScript's `async` function support, and requires all user +functions to be marked as `async`, to have calls to those functions marked with `await`, to have +code inserted in every loop to handle the control passing, and to have user classes have some +changes (since constructors can't be async). + +Here are some more specific details (optional reading): + +- All loops automatically await a timeout of 0 seconds after executing for more than ~25ms. +- screen_refresh (and other similar functions) await a window.requestAnimationFrame +- All user functions are marked as async, so that they can use await. +- Similarly, all calls to user functions are marked with await. +- Constructors cannot be async, so rename all constructors of user classes to `__constructor`, and + call it when user classes are newed. `let player = new Player()` becomes + `let player = (new Player()).__constructor()` + +This same setup is used to enable code pausing, and stopping, by simply listening for +\*pause/stop/continue **flags\*** when it does the awaits. To stop, we simply throw a +'ForceBreakLoop' error. To pause, we create a promise and await it. To continue, we call that +promise. + +_Here's something important to note, for those wondering why we just don't use `eval` instead of +putting the user's code in a new `Function` object. We couldn't do this transformation if we didn't +put the user's code inside a function, because you cannot `eval` asynchronous code! Meaning the user +couldn't write while loops, or any long running code at all!_ + +##### We want the user to be able to declare global functions, variables, and classes in one block and be able to access them in another + +When we evaluate the user's code, we are technically sticking it inside a function, then running it. +As such, the variables, functions and classes declared are actually scoped to that function, meaning +they vanish once the function ends. This obviously isn't very helpful - the user couldn't define +things in one code block, and use them in another, because they're in different scopes! In fact, we +couldn't even run the user's main, since it would vanish just after the code that creates it +finishes evaluating. + +We could just combine the user's code together into a single piece that executes in the same scope, +but then we couldn't have hot-reloading, where the user can update their code _while_ the program +runs. + +So what we do, is modify the user's code, so that declarations made inside the "global" scope, are +manually assigned to the _real_ global scope outside the function that the user's code is written +in. Just as an example, imagine the user has written the following code. + +General Code: + +```javascript +let globalVariable = "Hello!"; +``` + +Main: + +```javascript +function main() { + write_line(globalVariable); +} +``` + +If we evaluated each block by putting the block's code directly into a new `Function` and running +the function, it would be equivalent to the following: + +```javascript +function GeneralCode() { + let globalVariable = "Hello!"; +} +function MainCode() { + function main() { + write_line(globalVariable); + } +} + +// Init the user's functions, variables, etc +GeneralCode(); +MainCode(); + +// Start the program! +main(); +``` + +Hopefully it's clear why this wouldn't work. + +Here's how we transform it: + +```javascript +function GeneralCode() { + window.globalVariable = "Hello!"; +} +function MainCode() { + window.main = function main() { + write_line(globalVariable); + }; +} + +// Init the user's functions, variables, etc +GeneralCode(); +MainCode(); + +// Start the program! +main(); +``` + +Notice how every time we define something that should be in the global scope, we assign it to +`window`? This is (_one name for_) the global scope in JavaScript. So now the +variables/functions/classes are actually in the global scope, and everything works as expected. + +##### We also want them to be able to restart their program without old variables and functions being left behind + +Now that we have the variables in the global scope, we have a problem. Let's say the user runs the +program above once. They then remove the line of code defining `globalVariable`. If they restart +their program, you'd expect that an error occurs when they reach the line +`write_line(globalVariable);`, since `globalVariable` isn't defined right? + +But no error occurs! This is because, the global variable was already set the _first_ time they ran +the program, and when they 'restarted' it, all we did was call `main()` again, meaning the global +variable stayed in existence! We could fully reset the executionEnvironment with +`resetEnvironment()`, but this takes a long time (up to 20 seconds), so doing this every time the +user runs their code would be a poor user experience. + +Luckily, we already know what the global variables are - we already transform them after all. So +what we can do is keep a list of them, and then when the user restarts the program, we can `delete` +all the variables from the global `window` object, and then we get a clean run; hence the function +`cleanEnvironment()` exists. Now when the user runs, they'll get an error as they should! + +#### How do we modify the code? + +While we could just modify the text as a string, this is error prone and kind of hacky. Instead, we +use a JavaScript library called **Babel**, which parses the user's JavaScript, and creates what's +called an AST (or abstract-syntax-tree), which lets us treat each part of the code as separate +objects we can manipulate. For example: + +```javascript +let a = 10; +``` + +might become something like + +```javascript +VariableDeclaration(Identifier("a"), NumericLiteral(10), (type = "let")); +``` + +There's no need to understand this too deeply, but it's just good to know. + +#### Putting it all together + +Now we have all the pieces needed to understand the `processCodeForExecutionEnvironment` function. + +```javascript +function processCodeForExecutionEnvironment( + userCode, + asyncStopName, + asyncPauseName, + asyncContinueName, + asyncOnPauseName, +) { + asyncifyTransform__asyncStopName = asyncStopName; + asyncifyTransform__asyncPauseName = asyncPauseName; + asyncifyTransform__asyncContinueName = asyncContinueName; + asyncifyTransform__asyncOnPauseName = asyncOnPauseName; + + // Find the user's global declarations - important for next step + // Couldn't find a way to return extra information, so they are stored + // in the global 'findGlobalDeclarationsTransform__userScope' + Babel.transform(userCode, { + plugins: ["findGlobalDeclarationsTransform"], + }); + + // Now do the actual transforms! + userCode = Babel.transform(userCode, { + plugins: ["makeFunctionsAsyncAwaitTransform", "asyncify"], + retainLines: true, + }); + + return userCode.code; +} +``` + +_from +[executionEnvironment_CodeProcessor.js](https://github.com/thoth-tech/SplashkitOnline/blob/ddb06cec6296d6de905ee0a90084a4c1a71c7a58/Browser_IDE/executionEnvironment_CodeProcessor.js#L275)_ + +We can see it takes the user's code, and also some _names_ for the variables that will handle making +the code stop/pause/continue - these are the _flags_ mentioned earlier. It also takes the name of a +callback to call, when the user's code actually pauses. + +We can see the first thing it does is assign these to some variables - you can ignore that part for +now, it's just an implementation detail (it doesn't seem possible to pass parameters into Babel +transforms, so I just used global variables...). But after that, it calls Babel with the +`"findGlobalDeclarationsTransform"`, this handles updating the list of global variables that we +clear when restarting the program. Then we run it again with two more passes - +`"makeFunctionsAsyncAwaitTransform"`, and `"asyncify"`, which handle making functions/calls +async/await along with the scope changes, and inserting the yielding back to the browser during +loops, respectively. + +## A real function is created from the transformed code + +```javascript +processedCode = processCodeForExecutionEnvironment( + m.data.code, + "mainLoopStop", + "mainLoopPause", + "mainLoopContinuer", + "onProgramPause", +); + +tryEvalSource(m.data.name, processedCode); +``` + +Hopefully we now understand what the first line here does. Now we get to actually run the processed +code! First we have to turn it into a real function, and this is exactly what `tryEvalSource` does +first. Let's have a look inside: + +```javascript +async function tryEvalSource(block, source) { + // First create and syntax check the function + let blockFunction = await createEvalFunctionAndSyntaxCheck(block, source); + + if (blockFunction.state != "success") return blockFunction; + + return await tryRunFunction(blockFunction.value, reportError); +} +``` + +_from +[executionEnvironment_Internal.js](https://github.com/thoth-tech/SplashkitOnline/blob/ddb06cec6296d6de905ee0a90084a4c1a71c7a58/Browser_IDE/executionEnvironment_Internal.js#L191)_ + +As can be seen, the first thing that happens is that we call `createEvalFunctionAndSyntaxCheck`, +which does exactly what it says. You'll notice we're syntax checking here as well - this isn't +exactly deliberate, it just happens automatically when the `Function` object is created. Still, it's +helpful if the Babel output had a syntax error, for instance. The important part is inside +`createEvalFunctionAndSyntaxCheck`, here: + +```javascript +return Object.getPrototypeOf(async function () {}).constructor( + '"use strict";' + source + "\n//# sourceURL=" + userCodeBlockIdentifier + block, +); +``` + +_from +[executionEnvironment_Internal.js](https://github.com/thoth-tech/SplashkitOnline/blob/ddb06cec6296d6de905ee0a90084a4c1a71c7a58/Browser_IDE/executionEnvironment_Internal.js#L179C44-L179C44)_ + +Here's where the user's code _finally_ becomes a real function, that will actually be called! Notice +it looks a little different to the `new Function("...")` example earlier. This is because, it's +creating an `AsyncFunction`, which doesn't have a nice constructor, so we access it directly. The +`AsyncFunction` is important, because all of that work we did before modifying the user's code to +give control back to the browser when it loops, won't work without it being an `AsyncFunction`! + +You'll also notice that we modify the user's code slightly; we don't just pass `source` directly, we +add `"use strict";` at the start, and `//# sourceURL=...` at the end. What do these do? + +- `"use strict;"` makes the user's JavaScript code execute in strict mode, which tidies up a lot of + the language's semantics, forces variable declarations to be explicit, and overall improves code + quality and makes errors easier to track down. We couldn't turn on `"use strict";` without the + manual scoping fixes either! +- `//# sourceURL=...` tells the browser what 'source file' the code is from. This means that when + the browser reports an error, we'll be able to tell what code block it came from! Notice we add + `userCodeBlockIdentifier` at the start? This is just a short string that we can use to help us + tell if an error came from user code, or if it came from code in the IDE itself. An example might + look like this `//# sourceURL=__USERCODE__MainCode`, and so if an error occurs, we will see it + came from `__USERCODE__MainCode`, and tell the user it came from their "Main Code" block! + +Now we can finally call this function to run the user's code! Remember, this won't run their +_program_ but it will run the code which creates all their functions, global variables, classes, and +of course their `main()` function. Actually running the code happens inside `tryRunFunction`, and +we'll look at that in just a short bit. But just know now that the code has been run (or failed with +an error); let's assume it successfully ran, and so we can actually run the user's `main`! + +## Now it needs to run the user's main + +If we recall, this all started with the user pressing the Run button, which looked like this: + +```javascript +clearErrorLines(); + +runAllCodeBlocks(); +/* This is what it looks like inside "runAllCodeBlocks": +executionEnviroment.runCodeBlocks([ + {name: "GeneralCode", code: editorInit.getValue()}, + {name: "MainCode", code: editorMainLoop.getValue()} +]); +*/ + +executionEnviroment.runProgram(); +``` + +_from +[editorMain.js - runProgram()](https://github.com/thoth-tech/SplashkitOnline/blob/ddb06cec6296d6de905ee0a90084a4c1a71c7a58/Browser_IDE/editorMain.js#L194C6-L194C6)_ + +We now know what `runAllCodeBlocks` does quite well - it syntax checks the code, sends it to the +iFrame, the code gets transformed, stuffed into a function, and then run! So what does +`executionEnviroment.runProgram()` do? It's comparatively _much_ simpler! + +First thing it does is send a message to the iFrame, telling it to run the program - we definitely +don't want to run the program in the main page, so this is all secured inside the iFrame, like the +execution earlier. Upon receiving this message, it then calls its own internal `runProgram()` + +```javascript +async function runProgram() { + if (window.main === undefined || !(window.main instanceof Function)) { + ReportError(userCodeBlockIdentifier + "Program", "There is no main() function to run!", null); + return; + } + if (!mainIsRunning) { + mainLoopStop = false; + + mainIsRunning = true; + parent.postMessage({ type: "programStarted" }, "*"); + await tryRunFunction(window.main); + mainIsRunning = false; + parent.postMessage({ type: "programStopped" }, "*"); + } +} +``` + +_from +[executionEnvironment_Internal.js](https://github.com/thoth-tech/SplashkitOnline/blob/ddb06cec6296d6de905ee0a90084a4c1a71c7a58/Browser_IDE/executionEnvironment_Internal.js#L223)_ + +Let's break this down. + +First, it checks to see if the main program even exists: + +```javascript +if (window.main === undefined || !(window.main instanceof Function)) +``` + +We can see how it's just checking the 'global' scope of `window` - which is the same one we know the +user's functions get assigned to! So if the use created a `main` function, we'll be able to find it. +We also make sure it _is_ actually a function, and that they didn't do something like +`let main = 10;` + +Next we make sure it isn't already running. If it was, we could end up with `main()` running +multiple times simultaneously, not ideal! + +```javascript +if (!mainIsRunning){ + mainLoopStop = false; +``` + +If it wasn't already running, it's time to start it! First turn off the `mainLoopStop` flag. +Remember the async control flags mentioned earlier - this is one of them! If it's `true`, the +program will stop as soon as it can, so we make sure it's `false`. + +```javascript +mainIsRunning = true; +parent.postMessage({ type: "programStarted" }, "*"); +await tryRunFunction(window.main); +mainIsRunning = false; +parent.postMessage({ type: "programStopped" }, "*"); +``` + +Now we set `mainIsRunning` to `true` (so that we can't start it multiple times at the same time), +and post a message to the outside window `"programStarted"` - there's a listener in the main page +that will then change the green buttons accordingly. + +Finally, the moment of truth: `await tryRunFunction(window.main);` We run the program! It's called +with `await`, which means that the code will _wait_ for it to finish before continuing. Remember we +made all the user functions `async`? This allows them to give control back to the browser +momentarily, but it also means that they can't stop things that call them from continuing to the +next line of code - so we `await` to make sure we wait for the program to completely stop. + +Once it does finally end (which will happen if we set `mainLoopStop` to `true`), we set +`mainIsRunning` back to `false`, so the user can start it again, and then post a message back to the +main window `"programStopped"`, which will again update the buttons accordingly. + +### `tryRunFunction(func)` - what does it do? + +The responsibility of `tryRunFunction` - which is used when running the code blocks earlier as well, +is to run the user's code, and then detect when it has errors and report them to the user. + +These aren't syntax errors in this case, these are runtime errors (for instance if the user tries to +call a function that doesn't exist, or access outside the bounds of an array), and so we go about +detecting them in a way a bit different to the syntax errors before. + +And after all, we can't use the window's `error` callback for the same reasons mentioned earlier - +inside the iFrame, the error message is generic, and line number reported is always 0! And we +certainly can't run the code outside the iFrame, or that would defeat the entire point of having it. + +If we look inside `tryRunFunction`, we'll see it actually ends up calling `tryRunFunction_Internal`, +which is a bit more interesting. Here's a simplified version: + +```javascript +async function tryRunFunction_Internal(func) { + try { + await func(); + return "success!"; + } catch (err) { + if (err instanceof ForceBreakLoop) { + return "Stopped"; + } + + let error = parseErrorStack(err); + return error; + } +} +``` + +_from +[executionEnvironment_Internal.js](https://github.com/thoth-tech/SplashkitOnline/blob/ddb06cec6296d6de905ee0a90084a4c1a71c7a58/Browser_IDE/executionEnvironment_Internal.js#L138)_ + +We can see it takes the user's function (for instance, the user's `main()`, or the `AsyncFunctions` +we made from their code blocks), and tries to run it. It waits for it to finish with `await`, and if +it finishes without issues, it returns "success!". + +However, if an error was thrown, we catch it. If it was a `ForceBreakLoop` error, then we know it +threw it because the user pressed the Stop button, not because it crashed, and so we just report +back that it "Stopped". However, if that didn't happen, we figure out information about the error +(such as its line number and what code block it happened in) with `parseErrorStack(err)`, and then +return information about the error. + +This information is received by the original `tryRunFunction`, and if an error occurred it reports +it to the user via `ReportError`. + +Let's take a closer look at `parseErrorStack`, as the last stop on our journey. + +### parseErrorStack - what does _it_ do? + +Once we catch an error, the problem becomes "how do we report it to the user?" We need to give them +the error message, and at least a line number and code block to look at. If the error message had +members like `err.lineNumber` or `err.fileName` it'd be great, but they don't (unless you're using +Firefox...). However, all modern browsers support `err.stack`, which gives us a piece of text +describing the error and where it happened. It looks a bit like this: + +```javascript +gameInnerLoop@Init.js;:25:25 +main@Main.js;:25:11 +async*tryRunFunction_Internal@http://localhost:8000/executionEnvironment_Internal.js:57:21 +tryRunFunction@http://localhost:8000/executionEnvironment_Internal.js:89:21 +runProgram@http://localhost:8000/executionEnvironment_Internal.js:132:15 +@http://localhost:8000/executionEnvironment_Internal.js:167:9 +EventListener.handleEvent*@http://localhost:8000/executionEnvironment_Internal.js:144:8 +``` + +We can see on each line, the function, filename, line number, and even column number! The problem, +is that `stack` is actually non-standardised JavaScript, and so each browser implements it slightly +differently. Additionally, we still have to actually parse (read) the string, to get all the +information out of it. This is the job that `parseErrorStack` performs. + +The actual method isn't that complicated. It uses a regex that is designed to work across both +Firefox and Chrome based browsers (including Edge), that reads out the file name and line number. It +then returns these! Not too hard overall. One thing to note, is there are two lines inside +`parseErrorStack` that might be confusing: + +```javascript +if (file.startsWith(userCodeBlockIdentifier)) lineNumber -= userCodeStartLineOffset; +``` + +_from +[executionEnvironment_Internal.js - parseErrorStack](https://github.com/thoth-tech/SplashkitOnline/blob/ddb06cec6296d6de905ee0a90084a4c1a71c7a58/Browser_IDE/executionEnvironment_Internal.js#L123)_ + +Once we have extracted the line number, we check to see if the file name starts with the +`userCodeBlockIdentifier` (remember this from earlier, when we added the `//# sourceURL=` to the +user's code to help identify it?). If it starts with this, we know it's user code. And then we +subtract `userCodeStartLineOffset` from it. Why do we do that? The answer is that when we create the +`AsyncFunction` object, Firefox actually adds some lines to the start. For example, let's say we +create a simple function from text: + +```javascript +let myFunc = new Function("console.log('Hi!');"); +``` + +If we were to look at the function's source code with: + +```javascript +myFunc.toString(); +``` + +We get the following (at least in Firefox): + +```javascript +function anonymous() { + console.log("Hi!"); +} +``` + +See how there are two extra lines at the start? When the ExecutionEnvironment starts, it actually +detects how many lines the browser adds at the start, and stores it inside +`userCodeStartLineOffset` - so in Firefox, `userCodeStartLineOffset` is equal to `2`. Subtracting +this from `lineNumber` then gives us the _actual_ line number of the error, so that we can highlight +it in the user's code editor. + +## Recap + +Hopefully having read all of that, you have a decent understanding of the steps SplashKit Online +takes to run the user's code! As a recap, let's have one more look at the overview, which hopefully +makes a lot more sense now. + +1. Before the user does anything... + 1. The IDE starts up, and creates an ExecutionEnvironment. + 2. The ExecutionEnvironment creates an iFrame, and loads SplashKit inside it. +2. User writes code into the code editor (currently there are two 'code blocks', General and Main). +3. User presses the Run button. First we have to run the code blocks, to create all the user's + functions/classes and initialize global variables. +4. Pressing run calls `ExecutionEnvironment.runCodeBlocks`, passing in the General Code and Main + Code code blocks. For each code block: 1. The code block's text is sent as an argument to + `ExecutionEnvironment.runCodeBlock(block, source)` 2. The source code gets syntax checked. 3. If + it is syntactically correct, it is then sent as a `message` into the ExecutionEnvironment's + iFrame. +5. The following steps all happen inside the iFrame (for security purposes) + 1. The iFrame receives the message. + 2. The code is transformed to make it runnable within the environment + 3. A real function is created from the transformed code. + 4. **The code is run!** +6. Now it needs to run the user's main: `ExecutionEnvironment.runProgram()` is called. +7. This sends a message into the iFrame. +8. The following steps all happen inside the iFrame (for security purposes) + 1. The iFrame check if the user has created a `main()` + 2. **If so, `main()` is run!** diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Research and Findings/api-support-tests.md b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Research and Findings/api-support-tests.md new file mode 100644 index 00000000..ab2a8b5b --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Research and Findings/api-support-tests.md @@ -0,0 +1,75 @@ +--- +title: API Support Tests +description: + The results of running tests to check support for parts of the SplashKit API, across the two + currently supported languages. +--- + +# Report on SplashKit API functionality in SplashKit Online + +### Overview + +While much of the SplashKit API already works in browsers thanks to Emscripten, there are still +areas of functionality that do not. This report will outline what is working, what isn't, and the +general reason why. + +### SplashKit Tests + +It was decided that the most efficient way to test SplashKit's functionality was to use the existing +suite of tests that exist inside `splashkit-core`. To test the JavaScript language backend, these +tests had to be converted. To assist with this, a small C++ to JavaScript conversion utility was +written; the result of this was then patched up manually. For C++, a few of the tests had to be +slightly modified, but all in all are practically identical to their original source. + +The project file containing these tests will be added to the SplashKit Online DemoProjects folder +for reproducibility. Here are the results grouped by API category. + +| Field | JavaScript | C++ | Details | +| ---------------- | ----------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| Animations | Full Support | Full Support | | +| Audio | Near Full Support | Near Full Support | No FLAC support or MOD support. | +| Camera | Full Support | Full Support | | +| Colour | Full Support | Full Support | | +| Geometry | Full Support | Full Support | | +| Graphics | Full Support | Near Full Support | C++ backend doesn't support reading pixels currently (so no `take_screenshot`, etc). | +| Input | Near Full Support | Near Full Support | IME doesn't show up when using `Start Reading Text`. | +| Json | Full Support | Full Support | | +| Logging | Full Support | Full Support | | +| Networking | No Support | No Support | All networking functionality is replaced with stubs currently, due to no cURL support. | +| Physics | Full Support | Full Support | | +| Raspberry | No Support | No Support | Disabled during build. | +| Resource Bundles | Full Support | Full Support | | +| Resources | Full Support | Full Support | | +| Sprites | Full Support | Full Support | | +| Terminal | Partial Support | Limited Support | **JavaScript**: it all _works_, but no terminal input bar. 'Input' _popup_ appears, that has confusing behaviour of only sending data once _cancelled_. This may be fixed very shortly however.
**C++**: all the _read_ functions return immediately with no input. | +| Timers | Full Support | Full Support | | +| Utilities | Near Full Support | Full Support | [Display Dialog](https://splashkit.io/api/utilities/#display-dialog) does not work in JavaScript backend, as it enters a busy loop that freezes the page. | +| Windows | Partial Support | Partial Support | No support for multiple windows, or for moving the window. No way to close the current window. | + +And here are the results specific to each test - some tests test multiple things unfortunately, so +some of these results aren't very helpful. + +| Test | JavaScript | C++ | Details | +| ------------------- | ---------------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Animations | Works fully | Works fully | | +| Audio | Partially works | Partially works | Cannot download test audio. | +| Bundles | Works fully | works mostly | | +| Camera | Works fully | Works fully | | +| Geometry | Works fully | Works fully (Note) | Cannot close the first screen - replaced with delay | +| Graphics | Fails | Fails | | +| Input | Partially works | Partially works | Only support for one window currently | +| Logging | Works fully | Works fully | | +| Physics | Works fully | Fails | Due to use of read pixel | +| Resources | Works fully | Works fully | | +| Shape drawing | Works fully | Mostly works | Have to disable `take_screenshot` usage for C++ backend | +| Sprite tests | Works fully | Works fully | | +| Terminal | Possible failure | Possible failure | Slightly unsure what the behaviour should be | +| Text | Mostly Works | Mostly Works | Just fails to download font | +| Timers | works | Works fully | | +| Windows | Fails | Fails | JavaScript backend freezes (due to Display Dialog). C++ fails after clicking okay, with `Cannot read properties of null (reading 'createTexture')` in console - works if `display_dialog(...)` line is removed. | +| Cave Escape | Works fully | Works fully | | +| Web Server | Fails | Fails | | +| RESTful Web Service | Fails | Fails | | +| UDP Networking Test | Fails | Fails | | +| TCP Networking Test | Fails | Fails | | +| JSON Unit Test | Works fully | Works fully | | diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Research and Findings/splashkit-online-research-outcome.md b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Research and Findings/splashkit-online-research-outcome.md new file mode 100644 index 00000000..d7fc0a0b --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Research and Findings/splashkit-online-research-outcome.md @@ -0,0 +1,212 @@ +--- +title: SplashKit Online Research Spike Outcome +--- + +**Spike:** NA + +**Title:** SplashKit Online Research Spike Plan + +**Author:** Sean Boettger, sboettger@deakin.edu.au, sean@whypenguins.com + +## Goals / Deliverables + +The goal of this spike was to investigate whether Emscripten and Emception could be used to compile +and run SplashKit online via WASM, and in doing so produce this report. In the process, a fork of +SplashKit-Core was made to improve reproducibility. This can be found here: +https://github.com/WhyPenguins/splashkit-core/tree/EmscriptenTest + +## Technologies, Tools, and Resources used + +- Internet Browser: Firefox +- Programming Languages: C++, Python, Javascript +- Compilers: Emscripten +- Docker +- Emception +- Programming Libraries: SplashKit +- Text Editor: Notepad++ +- Terminal + +## Tasks undertaken + +Here are the key tasks that were performed to produce the main results. The actual path taken took a +bit more research and experimentation. + +### Testing Emscripten + +- Installed and activated Emscripten using emsdk (see + https://emscripten.org/docs/getting_started/downloads.html) +- Tried compiling some simple SDL code (such as that found here + https://blog.conan.io/2023/07/20/introduction-to-game-dev-with-sdl2.html) with the command + `emcc -sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sSDL2_IMAGE_FORMATS='["bmp","png","xpm"]' sdl_test.cpp -o sdl_test.html`. + Emscripten already has ports for many libraries such as SDL, which was found out about here + (https://emscripten.org/docs/compiling/Building-Projects.html) +- Ran a python web server with `python -m http.server` +- Navigated to localhost:8000 - the program was running in the browser. + +### Compiling SplashKit to WASM + +- This took a few changes to SplashKit's source code. To make this easier to reproduce, a fork of + SplashKit-Core has been created that has a branch with the changes required to make SplashKit + compile a simple example under Emscripten. See here: + https://github.com/WhyPenguins/splashkit-core/tree/EmscriptenTest + +#### The following is a brief list of changes + +- Cloned SplashKit-Core +- Modified CMakeLists.txt as follows: - Appended `set(CMAKE_C_COMPILER "emcc") ` + `set(CMAKE_CXX_COMPILER "emcc")` at the top. - Appended `-sUSE_SDL=2` to the make flags. - + Appended the following to be linked: - `-sUSE_SDL=2` - `-sUSE_SDL_TTF=2` - `-sUSE_SDL_GFX=2` - + `-sUSE_SDL_NET=2` - `-sUSE_SDL_MIXER=2` - `-sUSE_SDL_IMAGE=2` - + `-sSDL2_IMAGE_FORMATS='["bmp","png","xpm"]'` and removed any existing duplicates. - Modified a few + of the files and dependencies to either use Windows or Linux headers depending on what they + required (perhaps the build environment was unusual). - Commented out tests +- Modified web_driver.cpp and terminal.cpp so they were stubs without includes. +- At this point running `cmake -G "Unix Makefiles" . && make` built. +- To test functionality simply, the code from the starting tutorial + (https://splashkit.io/articles/guides/tags/starter/get-started-drawing/) was brought across and + replaced the Tests in the test folder. The test target in the makefile was modified to output this + test. `set(CMAKE_EXECUTABLE_SUFFIX ".html")` was also important to make it output properly. +- From here, the Python webserver was started in the output directory, and the starting tutorial + could be ran in the browser. + +### Compiling Emception + +- First Docker was installed, and WSL2 setup. +- Next, Emception was cloned and built following the instructions + (https://github.com/jprendes/emception) +- Unfortunately, a number of issues were encountered. Compiling LLVM took approximately 16GB of RAM, + and so the VM's RAM and swap limits needed to be adjusted; otherwise the compilation process was + killed. It also took approximately a day. +- Compilation errors were encountered later on. These have been reported already on the repository + (https://github.com/jprendes/emception/issues/24), and no fix nor work around has been proposed + yet. In order to not spend too long, Emception was shelved for now to work on interfacing + SplashKit with Javascript. + +### Using SplashKit as a Library in Javascript + +- There were three different approaches that could be taken - each one was tested along with + pros/cons examined. +- First step was to test 'cwrap'ing. +- The Main function was renamed, and wrapped in `extern "C"` +- An additional 'rerender' function was added, to test multiple calls. +- `-sEXPORTED_RUNTIME_METHODS=ccall,cwrap` was added to the makefile +- From here, the file was loaded in the browser, and the following executed on the brower's console: + +``` +start_main = Module.cwrap('start_main', 'number', []) +start_main()` +different_render = Module.cwrap('different_render', 'number', []) +different_render() +``` + +- This method worked easily, however wrapping create_window immediately posed issues as it takes a + C++ string (not a primitive), and also returns something other than a primitive. Methods involving + manual allocation were investigated, but instead the two binding implementations Embind and WebIDL + Binder seemed more promising. +- Embind bindings for colour and a few functions were created. They look as follows: + +``` +EMSCRIPTEN_BINDINGS(color) { + emscripten::value_object("color") + .field("r", &color::r) + .field("g", &color::g) + .field("b", &color::b) + .field("a", &color::a); +} +EMSCRIPTEN_BINDINGS(my_module) { + emscripten::function("open_window", (window (*)(std::string, int, int)){&open_window}, emscripten::allow_raw_pointers()); + emscripten::function("clear_screen", (void (*)(void)){&clear_screen}); + emscripten::function("clear_screen_color", (void (*)(color)){&clear_screen}); + emscripten::function("refresh_screen", (void (*)(void)){&refresh_screen_}); +} +``` + +- Unfortunately it seems Embind has issues with raw pointers, which SplashKit uses a lot of. + Apparently it should only have issues with pointers to primitive types, but the same error was + encountered even with structures (such as \_window_data\*). +- Finally WebIDL Binder was tried out. +- SplashKitWasm.idl was created and filled out with some simple prototypes. +- The C++ and Javascript glue was created by running + `python ../../emsdk/upstream/emscripten/tools/webidl_binder.py SplashKitWasm.idl SplashKitWasmGlue` +- It was tested at the console with the following commands: + +``` +SK = new Module.SplashKitJavascript() +SK.open_window("Testing!", 800, 600) +SK.clear_screen(SK.color(0.7,0,1,1)) +SK.refresh_screen() +``` + +``` +SK.clear_screen(SK.color(1,1,1,1)); +SK.fill_ellipse(SK.color(0,1,0,1), 0, 400, 800, 400); +SK.fill_rectangle(SK.color(0.4,0.4,0.4,1), 300, 300, 200, 200); +SK.fill_triangle(SK.color(1,0,0,1), 250, 300, 400, 150, 550, 300); +SK.refresh_screen() +``` + +- It was here that testing was ended and this report was written up. The results can be seen in the + final commit on the EmscriptenTest branch. + +This report took a bit longer to write up than it should have, as initially all the tests with +Emscripten were performed using a personal compilation tool in order to make initial testing quick. +That tool continued to be used to compile SplashKit-Core. Migrating to using SplashKit-Core's own +compilation method took longer, but hopefully by doing so the results can be more easily reproduced +and expanded on in the future. + +## What we found out + +### Code using SplashKit can be compiled with Emscripten and run in the browser. + +#### What worked + +During testing, the majority of SplashKit was compiled and linked successfully, and basic +functionality (opening a window, drawing shapes) was confirmed to work. In the SDL test, SDL input +was confirmed to work, making it likely it does in SplashKit as well. + +#### What wasn't tested + +Any functionality outside of that was not tested, including sound, animation, etc. Twitter, +terminal, serial and JSON functionality was also not tested/replaced with stubs. + +#### What didn't work + +Web functionality was replaced with stubs due to the usage of cURL which is not currently compilable +under Emscripten. See (https://github.com/emscripten-core/emscripten/issues/3270) + +### SplashKit can be compiled as a library and used in Javascript. + +Embind seemed promising but due to issues with raw pointers WebIDL Binder was investigated further +and is plausibly the better alternative for this project. It has issues with functions in global +scope unfortunately (https://github.com/emscripten-core/emscripten/issues/8390), requiring the +majority of SplashKit's functions to be wrapped in a class. + +### Emception was unable to be compiled. + +Until the bug here (https://github.com/jprendes/emception/issues/24) is fixed, it seems like it will +be difficult to compile Emception without really digging into how it works and correcting the +problem ourselves. Whether this is worth it or not is hard to say. + +## Open issues/risks + +As Emception was unable to be compiled, it is difficult to evaluate whether it would have been a +good solution. There is risk that continuing to try and use it would just consume more time. + +Much of SplashKit is also yet to be tested; perhaps there are yet unknown issues regarding sound and +other interactivity. Testing of larger codebases using SplashKit should be conducted. + +## Recommendation + +One way forward would be to continue developing SplashKit Online as a Javascript based scripting +environment; it has been confirmed SplashKit can be used as a library via Javascript, and this +ensures no load on the server regarding compiling, and also no uncertainty regarding whether it will +be possible to get Emception working. + +Another way forward is to use Emscripten as a back-end compiler to the web IDE, similar to the +original SplashKit Online repository. This introduces more complexity on the server side, but would +allow users to develop using C++ just as they would on their own computer. + +Finally, it might be worth continuing to investigate Emception and try to get it to compile. Several +unknowns exist - how long will it take to understand and make compile, and if it runs whether it be +able to compile well enough (there are concerns regarding speed). If it is successful however this +would probably give the best result, but there are many unknowns. diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Research and Findings/splashkit-online-research-plan.md b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Research and Findings/splashkit-online-research-plan.md new file mode 100644 index 00000000..fc5aa04a --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/Research and Findings/splashkit-online-research-plan.md @@ -0,0 +1,70 @@ +--- +title: SplashKit Online Research Spike Plan +--- + +**Name:** SplashKit Online Research Spike Plan + +## Context + +It would be useful if SplashKit could be used directly in-browser, in order to make it easier for +people to get started without difficulties setting it up locally on their own machine. Last +trimester the SplashKit Online project was started, however due to its difficulty was placed on +hold. + +The purpose of this spike is to investigate technologies that may make running it online more +viable, and explore which ways seem most promising. The main technology to be investigated here is +WebAssembly (or WASM), which was mentioned in the readme for the SplashKit-Online repository +(https://github.com/thoth-tech/SplashkitOnline). The technology itself doesn't appear to have been +used in the project; instead it seems that project relied on both compiling _and_ executing the code +on a back-end server. This could be considered an extension of that initial research. + +**Knowledge Gap:** + +- It is currently unknown how well certain technologies like WASM could be used to compile/run code + using SplashKit in a browser. +- It is unknown if code can be compiled quick enough within the browser. +- It is unknown if and how effectively SplashKit can be compiled as a library to be used within the + browser. + +**Skill Gap:** + +- There is a lack of experience with technology like WASM, + +**Technology Gap:** + +- Ability to compile SplashKit to WASM. + +It is unsure whether projects like Emscripten or Emception are able to compile SplashKit and run the +result in a browser interactively; this will need to be investigated. It is also uncertain whether +it would be better to compile within the browser itself, or on a back-end server. + +## Goals/Deliverables + +- Report on possible ways to continue developing SplashKit Online + - Confirm whether code using SplashKit can be compiled with Emscripten (C/C++ to WASM compiler) + and executed in a browser + - Confirm whether SplashKit can be compiled and used as a library via Javascript in a browser + - Confirm SplashKit code can be compiled in-browser using Emception (self hosted Emscripten) + +**Planned start date:** Week 1 T3 2023 + +**Deadline:** Week 2 T3 2023 + +## Planning notes + +- Setup Emscripten +- Confirm code using SDL can be compiled with Emscripten and executed in a browser + - Setup simple SDL example + - Compile with Emscripten + - Run in browser and check result +- Confirm code using SplashKit can be compiled with Emscripten and executed in a browser + - Setup simple SplashKit example + - Compile with Emscripten + - Run in browser and check result +- (Optional) Test whether SplashKit can be compiled and used as a library via Javascript in a + browser + - Investigate methods of binding + - Test binding methods +- Build and setup Emception + - Confirm SDL code can be compiled in-browser using Emception + - Confirm SplashKit code can be compiled in-browser using Emception diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/index.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/index.mdx new file mode 100644 index 00000000..c0c92e4e --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Online/index.mdx @@ -0,0 +1,70 @@ +--- +title: SplashKit Online +sidebar: + label: Overview + order: 10 +--- + +import { CardGrid, LinkCard } from "@astrojs/starlight/components"; + +## The SplashKit Online Team + +The SplashKit Online Team manages all aspects of the +[SplashKit Online IDE](https://thoth-tech.github.io/splashkit-online/) website, a web-based IDE +designed to help beginner programmers quickly start building 2D games directly in the browser. + +It currently supports JavaScript (with experimental C++ functionality) and leverages WebAssembly +(Wasm) to execute SplashKit code, but the goal is to expand this support to include all languages +that SplashKit supports: C++, C#, Python, and Pascal. + +The team’s responsibilities include: + +- Ensuring consistent styling and branding across the site +- Improving language support by integrating additional language support. (Currently supporting + Javascript and (experimental) C++.) +- Optimising the site’s usability and accessibility for a smooth user experience by improving the + user experience, performance and language-specific features. + +## Onboarding Information + + + + + + + + + + + +## More Specific Information + +Coming soon... diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/01-Tutorial-Proposal-Template.md b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/01-Tutorial-Proposal-Template.md new file mode 100644 index 00000000..aa9f1a9f --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/01-Tutorial-Proposal-Template.md @@ -0,0 +1,39 @@ +--- +title: Tutorial Proposal Template +description: Use this template to create a proposal for a new SplashKit tutorial. +sidebar: + label: Tutorial Proposal Template +--- + +## Introduction + +Provide a brief introduction to the tutorial, explaining what the tutorial will cover and what the +reader will learn from it. + +## Tutorial Details + +### Tutorial Structure + +Explain the basic structure you plan to use for the tutorial. (Whole code first then explain +snippets? Or introduce code "as-you-go" style? Background information at the top or throughout the +tutorial? etc.) + +### Level of Difficulty + +Mention the level of difficulty and the target audience for the tutorial +(beginner/intermediate/advanced). + +### Functions Covered + +List the main SplashKit functions that will be included in the tutorial + +- [Function1](link to function on splashkit.io) +- [Function2](link to function on splashkit.io) +- [Function3](link to function on splashkit.io) +- etc. + +## Conclusion + +Summarise the importance of the tutorial and how it will benefit the readers. Reiterate the main +points covered in the tutorial and explain how readers can apply this new knowledge in their own +projects. diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/02-Tutorial-Style-Guide.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/02-Tutorial-Style-Guide.mdx new file mode 100644 index 00000000..fa977ccd --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/02-Tutorial-Style-Guide.mdx @@ -0,0 +1,397 @@ +--- +title: Tutorial Style Guide +description: Use this guide to ensure your SplashKit tutorial is formatted correctly. +sidebar: + label: Tutorial Style Guide +--- + +import { Tabs, TabItem } from "@astrojs/starlight/components"; + +## General + +Create tutorial in an `.mdx` file. + +Make sure your tutorials follow the **markdownlint** extension's formatting. + +Correct any yellow squiggly lines. + +## Headings + +Make sure to use the following **title** format: + +```mdx +--- +title: Tutorial Heading +--- +``` + +Then use `## Heading` for the highest heading level. + +Always keep a blank line between headings and other text. + +### Subheadings + +For subheadings that you want to see in the RHS sidebar/panel on splashkit.io, use `### Subheading`. +Subheadings lower than this will not be shown. + +Do not use bolded lines for headings/subheadings. + +## Links + +Do not use any "raw" links. Links must always use the following format: + +```mdx +[Text to show for link](URL link) +``` + +Make sure to link your headings within the same file if these are mentioned, using the following +format: + +```mdx +[Heading text](#link-to-heading) +``` + +## Images + +Always keep a blank line between images and other text. + +Use the following format for all images: + +```mdx +![Alt text](link to image) +``` + +For the **Alt text** part above: Briefly explain what the image is showing. This is important for +accessibility. + +For the **link to image** part above: If you are linking an image resource that you have downloaded, +this will need to be put into an **images** folder in the same place as the tutorial. +For example, with the **skbox.png** image in the images folder here, you would use: + +```mdx +![Image of SplashKit box logo](./images/skbox.png) +``` + +Which would produce: + +![Image of SplashKit box logo](./images/skbox.png) + +## Lists + +Always keep a blank line between lists and other text. + +## Code Blocks + +Use fenced code blocks for any code snippets or terminal commands, to make it easier for the reader +to copy. + +Always include a language with the fenced code blocks. + +### C++ Code + +For C++, you would use the following format: + +````md +```cpp +#include "splashkit.h" + +int main() +{ + open_window("Window Title... to change", 800, 600); + delay(5000); + close_all_windows(); + return 0; +} +``` +```` + +Which would produce: + +```cpp +#include "splashkit.h" + +int main() +{ + open_window("Window Title... to change", 800, 600); + delay(5000); + close_all_windows(); + return 0; +} +``` + +### C# Code + +For example, if using C#, you would use the following format: + +````md +```csharp +using static SplashKitSDK.SplashKit; + +OpenWindow("Window Title... to change", 800, 600); +Delay(5000); +CloseAllWindows(); +``` +```` + +Which would produce: + +```csharp +using static SplashKitSDK.SplashKit; + +OpenWindow("Window Title... to change", 800, 600); +Delay(5000); +CloseAllWindows(); +``` + +### Python Code + +For Python, you would use the following format: + +````md +```python +from splashkit import * + +open_window("Window Title... to change", 800, 600) +delay(5000) +close_all_windows() +``` +```` + +Which would produce: + +```python +from splashkit import * + +open_window("Window Title... to change", 800, 600) +delay(5000) +close_all_windows() +``` + +For any blocks that are not code, you can use `plaintext` for the language. For terminal commands, +use `shell` for the language. + +If your guide is only using 1 language (and not using at least both C# and C++), make sure to +include the language used in the title. + +### Multiple Code Languages + +To show the same code in different languages, you will need to use +[Tabs](https://starlight.astro.build/guides/components/#tabs). + +Make sure to add the following line to your file underneath the title: + +```mdx +import { Tabs, TabItem } from "@astrojs/starlight/components"; + +; +``` + +And then using the examples from above, you would have: + +````md + + + +```cpp +#include "splashkit.h" + +int main() +{ + string name; // declare a variable to store the name + string quest; // and another to store a quest + + write("What is your name: "); // prompt the user for input + name = read_line(); // read user input + + // read in another value + write("And what is your quest? "); + quest = read_line(); + + write_line(name + "'s quest is: " + quest); // output quest to the terminal + + return 0; +} +``` + + + + + + + +```csharp +using static SplashKitSDK.SplashKit; + +string name; // declare a variable to store the name +string quest; // and another to store a quest + +Write("What is your name: "); // prompt the user for input +name = ReadLine(); // read user input + +// Read in another value +Write("And what is your quest? "); +quest = ReadLine(); + +WriteLine(name + "'s quest is: " + quest); // output quest to the terminal +``` + + + + +```csharp +using SplashKitSDK; + +namespace ReadingText +{ + public class Program + { + public static void Main() + { + string name; // declare a variable to store the name + string quest; // and another to store a quest + + SplashKit.Write("What is your name: "); // prompt the user for input + name = SplashKit.ReadLine(); // read user input + + // Read in another value + SplashKit.Write("And what is your quest? "); + quest = SplashKit.ReadLine(); + + SplashKit.WriteLine(name + "'s quest is: " + quest); // output quest to the terminal + } + } +} +``` + + + + + + + +```python +from splashkit import * + +write("What is your name: ") # prompt the user for input +name = read_line() # read user input and store in a variable + +# Read in another value +write("And what is your quest? ") +quest = read_line() + +write_line(name + "'s quest is: " + quest) +``` + + + +```` + +Which would produce the following: + + + + +```cpp +#include "splashkit.h" + +int main() +{ + string name; // declare a variable to store the name + string quest; // and another to store a quest + + write("What is your name: "); // prompt the user for input + name = read_line(); // read user input + + // read in another value + write("And what is your quest? "); + quest = read_line(); + + write_line(name + "'s quest is: " + quest); // output quest to the terminal + + return 0; +} +``` + + + + + + + +```csharp +using static SplashKitSDK.SplashKit; + +string name; // declare a variable to store the name +string quest; // and another to store a quest + +Write("What is your name: "); // prompt the user for input +name = ReadLine(); // read user input + +// Read in another value +Write("And what is your quest? "); +quest = ReadLine(); + +WriteLine(name + "'s quest is: " + quest); // output quest to the terminal +``` + + + + +```csharp +using SplashKitSDK; + +namespace ReadingText +{ + public class Program + { + public static void Main() + { + string name; // declare a variable to store the name + string quest; // and another to store a quest + + SplashKit.Write("What is your name: "); // prompt the user for input + name = SplashKit.ReadLine(); // read user input + + // Read in another value + SplashKit.Write("And what is your quest? "); + quest = SplashKit.ReadLine(); + + SplashKit.WriteLine(name + "'s quest is: " + quest); // output quest to the terminal + } + } +} +``` + + + + + + + +```python +from splashkit import * + +write("What is your name: ") # prompt the user for input +name = read_line() # read user input and store in a variable + +# Read in another value +write("And what is your quest? ") +quest = read_line() + +write_line(name + "'s quest is: " + quest) +``` + + + + +## Callouts (Asides) + +Use callouts (also known as [Asides](https://starlight.astro.build/guides/components/#asides)) to +highlight tips or important notes. + +:::tip[Make the page interesting] + +These can help to direct the reader to any extra info, and help to add more colour to your tutorial +guide. + +::: diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/03-Tutorial-Reviews.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/03-Tutorial-Reviews.mdx new file mode 100644 index 00000000..b8af0182 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/03-Tutorial-Reviews.mdx @@ -0,0 +1,61 @@ +--- +title: Tutorial Reviews +description: Use this template to create a review for a SplashKit tutorial. +sidebar: + label: Tutorial Reviews +--- + +import { FileTree } from "@astrojs/starlight/components"; +import { LinkCard } from "@astrojs/starlight/components"; +import { Steps } from "@astrojs/starlight/components"; + +## Filling out the Tutorial Review + +When doing a tutorial review ensure to do the following: + + + +1. Read the tutorial to ensure it is clear and easy to follow. +2. Ensure the tutorial has the following languages: + - C# using top level statements, as well as using OOP + - C++ + - Python +3. Run all the code in the way the tutorial describes to ensure it works. +4. Include screenshots of all the code running in your pull request description. + + + +### Links + +Documentation Repo file tree: + + + +- docs/ + - SplashKit/ + - tutorials/ + - Reviews/ + - Tutorial-Name.md + + + + + + + diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/04-adding-oop.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/04-adding-oop.mdx new file mode 100644 index 00000000..a78a2b47 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/04-adding-oop.mdx @@ -0,0 +1,201 @@ +--- +title: Guide to adding OOP to SplashKit tutorials +description: Learn how to add object-oriented programming (OOP) to the SplashKit tutorials. +sidebar: + hidden: true + label: Adding OOP to Guides +--- + +import { Tabs, TabItem } from "@astrojs/starlight/components"; + +## Adding OOP and Top Level C# to Splashkit Tutorials + +One of the current goals of the SplashKit team is to enhance the tutorials by including both +top-level statement and object-oriented (OOP) versions of C# programs. This guide outlines how to +effectively integrate OOP into the existing tutorials, providing both options for users to choose +from. + +### The Full Code Block Structure + +The full code block structure for C++, C# in top level and OOP, and Python is as follows: + +````md + + + +```cpp + +Add C++ code here + +``` + + + + + + +```csharp + +Add top-level statement version of C# code here + +``` + + + + +```csharp + +Add OOP version of C# code here + +``` + + + + + + +```python + +Add Python code here + +``` + + + +```` + +This is the new standard structure for all Splashkit tutorials. The C# code block has been replaced +with a tabs component that contains two tabs, one for top-level statements and one for +object-oriented programming. The C# code block has been replaced with a tabs component that contains +two tabs, one for top-level statements and one for object-oriented programming. + +### Adding OOP to the Splashkit tutorials + +If you are adding OOP to the Splashkit tutorials, you will need to replace the C# section with the +following code block in order to have both top-level statements and object-oriented programming +options: + +````md + + + +```csharp + +Add top-level statement version of C# code here + +``` + + + + +```csharp + +Add OOP version of C# code here + +``` + + + +```` + +## Example + +Once done, the view of the code blocks will remain the same on the Splashkit site. However, once +clicking on the C# tab, the user will be able to see both the top-level statements and +object-oriented programming versions of the code. + + + + +```cpp +#include "splashkit.h" + +int main() +{ + string name; // declare a variable to store the name + string quest; // and another to store a quest + + write("What is your name: "); // prompt the user for input + name = read_line(); // read user input + + // read in another value + write("And what is your quest? "); + quest = read_line(); + + write_line(name + "'s quest is: " + quest); // output quest to the terminal + + return 0; +} +``` + + + + + + + +```csharp +using static SplashKitSDK.SplashKit; + +string name; // declare a variable to store the name +string quest; // and another to store a quest + +Write("What is your name: "); // prompt the user for input +name = ReadLine(); // read user input + +// Read in another value +Write("And what is your quest? "); +quest = ReadLine(); + +WriteLine(name + "'s quest is: " + quest); // output quest to the terminal +``` + + + + +```csharp +using SplashKitSDK; + +namespace ReadingText +{ + public class Program + { + public static void Main() + { + string name; // declare a variable to store the name + string quest; // and another to store a quest + + SplashKit.Write("What is your name: "); // prompt the user for input + name = SplashKit.ReadLine(); // read user input + + // Read in another value + SplashKit.Write("And what is your quest? "); + quest = SplashKit.ReadLine(); + + SplashKit.WriteLine(name + "'s quest is: " + quest); // output quest to the terminal + } + } +} +``` + + + + + + + +```python +from splashkit import * + +write("What is your name: ") # prompt the user for input +name = read_line() # read user input + +# Read in another value +write("And what is your quest? ") +quest = read_line() + +write_line(name + "'s quest is: " + quest) # output quest to the terminal +``` + + + diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/04-oop-styling.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/04-oop-styling.mdx new file mode 100644 index 00000000..78761569 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/04-oop-styling.mdx @@ -0,0 +1,169 @@ +--- +title: Converting Between Top-Level Statements and OOP Styling in C# +description: Learn how to add object-oriented programming (OOP) to the SplashKit tutorials. +sidebar: + label: C# OOP Styling + hidden: true +--- + +import { Tabs, TabItem } from "@astrojs/starlight/components"; +import { Steps } from "@astrojs/starlight/components"; + +This guide explains how to convert between top-level statements and object-oriented programming +(OOP) styles in C# for SplashKit tutorials. This guide is good to refer to when you need to convert +code between the two styles. + +## C# Tabs + +### Understanding the Differences Between Top-Level and OOP Styles + +**Top-Level Statements**: + +- Top-level statements allow you to write C# code without explicitly defining a class or `Main` + method. +- Uses the directive: `using static SplashKitSDK.SplashKit;`, so SplashKit functions are called + directly, such as `WriteLine("Hello!");`. + +**Object-Oriented Programming (OOP)**: + +- OOP-style C# code requires defining a `Main` method inside a class. +- Uses `using SplashKitSDK;`, meaning all SplashKit commands are prefixed with `SplashKit.` (e.g., + `SplashKit.WriteLine("Hello!");`). + +### Converting from Top-Level Statements to OOP + +To convert from top-level statements to OOP, follow these steps: + + + +1. **Add a Namespace and Class**: + + Wrap your code in a namespace and class with a `Main` method. + +2. **Adjust the `using` Directive**: + + Replace `using static SplashKitSDK.SplashKit;` with `using SplashKitSDK;`. + +3. **Prefix SplashKit Functions**: + + Add `SplashKit.` before each SplashKit function. + + + +--- + +#### Example Conversion + +**Top-Level Code**: + +```csharp +using static SplashKitSDK.SplashKit; + +WriteLine("What is your name?"); +string name = ReadLine(); + +WriteLine("Hello, " + name + "!"); +``` + +**Converted to OOP**: + +```csharp +using SplashKitSDK; + +namespace Program +{ + public class Program + { + public static void Main() + { + SplashKit.WriteLine("What is your name?"); + string name = SplashKit.ReadLine(); + + SplashKit.WriteLine("Hello, " + name + "!"); + } + } +} +``` + +### Converting from OOP to Top-Level Statements + +To convert from OOP to top-level statements: + + + +1. **Remove Namespace and Class Wrapping**: + + Delete the `namespace` and `class` definitions along with the `Main` method. + +2. **Adjust the `using` Directive**: + + Replace `using SplashKitSDK;` with `using static SplashKitSDK.SplashKit;`. + +3. **Remove the `SplashKit.` Prefix**: + + Directly call functions like `WriteLine()` and `ReadLine()`. + + + +--- + +#### Example Conversion + +**OOP Code**: + +```csharp +using SplashKitSDK; + +namespace Program +{ + public class Program + { + public static void Main() + { + SplashKit.WriteLine("What is your name?"); + string name = SplashKit.ReadLine(); + + SplashKit.WriteLine("Hello, " + name + "!"); + } + } +} +``` + +**Converted to Top-Level Statements**: + +```csharp +using static SplashKitSDK.SplashKit; + +WriteLine("What is your name?"); +string name = ReadLine(); + +WriteLine("Hello, " + name + "!"); +``` + +### Quick Reference + +**Top-Level to OOP**: + +- Replace `using static SplashKitSDK.SplashKit;` with `using SplashKitSDK;`. +- Wrap code in: + + ```csharp + namespace Program + { + public class Program + { + public static void Main() + { + // Code here + } + } + } + ``` + +- Prefix SplashKit functions with `SplashKit.`. + +**OOP to Top-Level**: + +- Replace `using SplashKitSDK;` with `using static SplashKitSDK.SplashKit;`. +- Remove `namespace`, `class`, and `Main` method wrappers. +- Remove `SplashKit.` prefixes. diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/05-basic-vectors-proposal.md b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/05-basic-vectors-proposal.md new file mode 100644 index 00000000..c1d981ed --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/05-basic-vectors-proposal.md @@ -0,0 +1,99 @@ +--- +title: Tutorial Proposal Guide +description: + Structure of a tutorial proposal on basic vector mathematics and its applications in game + development. +sidebar: + hidden: true + label: Tutorial Proposal Guide +--- + +## Tutorial Template 1: Basic Vectors + +This tutorial will cover the fundamentals of vector mathematics and some applications (such as in +game development). The intended audience will be for beginners to intermediate learners, and will +guide them through understanding and implementing vector operations, including angle and magnitude +calculations, vector addition and subtraction, and the dot product. It will also cover other +techniques like vector normals and basic reflection, all within the context of creating dynamic game +mechanics. By the end, it will lead to a greater understanding of using vectors to enhance program +functionality and interactivity. + +### Tutorial Details + +#### Tutorial Structure + +This tutorial will follow an "as-you-go" approach, introducing concepts and code snippets +progressively. Each section will focus on a specific vector operation, providing both theoretical +background and practical implementation. Visual aids and code examples will be used throughout to +help illustrate the concepts. It will also contain the code for the learner to run themselves and +adjust the values as they please to see the effects on the program. + +#### Level of Difficulty + +This tutorial is geared towards beginners and intermediate learners with basic programming +knowledge. It's ideal for those looking to expand their understanding of game mechanics through +vector mathematics. + +#### Functions Covered + +The tutorial will cover the following main SplashKit functions: + +1. [double vector_angle(const vector_2d v)](https://splashkit.io/api/physics/#vector-angle) +2. [double vector_magnitude(const vector_2d &v)](https://splashkit.io/api/physics/#vector-magnitude) +3. [vector_2d vector_add(const vector_2d &v1, const vector_2d &v2)](https://splashkit.io/api/physics/#vector-add) +4. [vector_2d vector_subtract(const vector_2d &v1, const vector_2d &v2)](https://splashkit.io/api/physics/#vector-subtract) +5. [vector_2d vector_normal(const vector_2d &v)](https://splashkit.io/api/physics/#vector-normal) +6. [double dot_product(const vector_2d &v1, const vector_2d &v2)](https://splashkit.io/api/physics/#dot-product) +7. [vector_2d vector_multiply(const vector_2d &v1, double s)](https://splashkit.io/api/physics/#vector-multiply) +8. [vector_2d vector_point_to_point(const point_2d &start, const point_2d &end_pt)](https://splashkit.io/api/physics/#vector-point-to-point) + +### Conclusion + +This tutorial provides a comprehensive introduction to vectors and their applications in game +development. By understanding and utilising vector operations, readers can significantly enhance the +realism and responsiveness of their games. Whether creating simple games or increasing the +interactivity of their existing games, the skills gained from this tutorial will add complexity to +their programs. + +## Tutorial Template 2: Camera Controls + +### Introduction + +This tutorial will cover how to use the various camera functions in SplashKit to implement dynamic +camera movements in graphical applications. By following this tutorial, readers will learn to create +zoom effects, responsive camera controls, and movements enhancing the interactivity and immersion of +their games or other projects. + +### Tutorial Details + +#### Tutorial Structure + +This tutorial will follow an "as-you-go" style. Each section will introduce a specific concept and +demonstrate its practical application with step-by-step code examples. The tutorial will start with +a basic overview of the camera functions, then guide readers through progressively more complex +examples, allowing them to apply what they’ve learned immediately. Visual aids will be used to +illustrate camera movements and effects in real-time. + +#### Level of Difficulty + +This tutorial is targeted at intermediate learners who have experience in programming with the +SplashKit library. It is ideal for developers who want to add dynamic camera control to their +graphical applications or games. + +#### Functions Covered + +The tutorial will cover the following main SplashKit functions: + +- [MoveCameraBy](https://splashkit.io/api/camera/#move-camera-by-2) +- [SetCameraPosition](https://splashkit.io/api/camera/#set-camera-position) +- [CameraPosition](https://splashkit.io/api/camera/#camera-position) +- [OptionDefaults](https://splashkit.io/api/graphics/#option-defaults) +- [OptionScaleBmp](https://splashkit.io/api/graphics/#option-scale-bmp) +- [DrawBitmap](https://splashkit.io/api/graphics/#draw-bitmap-4) + +### Conclusion + +This tutorial will help readers understand how to manipulate the camera in their SplashKit +applications. By mastering these camera functions, developers can create more engaging and +interactive experiences, such as zoom effects and camera movements. This knowledge will be valuable +for anyone looking to improve the visual dynamics and responsiveness of their game projects. diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/06-SplashKitTutorials.md b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/06-SplashKitTutorials.md new file mode 100644 index 00000000..e6df651e --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/06-SplashKitTutorials.md @@ -0,0 +1,613 @@ +--- +title: Tutorials List +description: A compilation of SplashKit tutorials with recommendations for improvement. +sidebar: + hidden: true +--- + +On this page is a compilation of SplashKit tutorials and tutorial proposals. Areas of potential +improvement have been marked. + +The tutorials have been layed out in categories that seem reasonable for further development. There +is a need for both tutorials that focus on specific areas (such as sprites, or audio), along with +tutorials that bring these concepts together cohesively (like the Metroidvania series). + +## Current Tutorials + +--- + +### Starter + +#### _Installation_ + +- Overview: Installation guides for SplashKit for different operating systems. +- Status: Completed +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/installation/) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/tree/master/src/content/docs/installation/) +- Website Links: [_Live_](https://splashkit.io/installation/) + +#### _Getting Started Drawing using Procedures_ + +- Overview: An introduction to the basics of SplashKit. +- Status: Completed +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/2018-05-30-get-started-drawing.html.md.erb) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Starter/get-started-drawing.mdx) +- Website Links: [_Live_](https://splashkit.io/guides/starter/get-started-drawing/) + +#### _Understanding Double Buffering_ + +- Overview: An explanation of double buffering. +- Status: Needs Improvement/Checking + - Explaining that without double buffering, the in-between states while drawing could end up + visible to the user would be good. +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/2018-05-30-basic-drawing.html.md.erb) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Starter/double-buffering.mdx) +- Website Links: [_Live_](https://splashkit.io/guides/starter/double-buffering/) + +#### _Loading Resources with Bundles_ + +- Overview: An explanation of bundles. +- Status: Completed +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/2018-06-05-bundles.html.md.erb) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Starter/Bundles.mdx) +- Website Links: [_Live_](https://splashkit.io/guides/starter/bundles/) + +#### _Reading Text_ + +- Overview: How to read text from the terminal or from a graphical application. +- Status: Completed +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/2018-10-02-reading-text.html.md.erb) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Starter/reading-text.mdx) +- Website Links: [_Live_](https://splashkit.io/guides/starter/reading-text/) + +#### _Getting Started With SplashKit - Windows C#/C++_ + +- Overview: Covers installing MSYS2, SplashKit and VSCode + project setup. +- Status: Completed +- Repo Links: + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Tutorial%20Markdowns/Getting%20Started%20With%20SplashKit%20-%20C%23-C%2B%2B/Getting%20Started%20With%20Splashkit%20-%20C%23-C%2B%2B.md) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Starter/Getting%20Started%20With%20Splashkit.md) +- Website Links: [_Live_](https://splashkit.io/guides/starter/getting-started-with-splashkit/) + +--- + +### Input + +#### _Getting Started With Mouse Button and Inputs_ + +- Overview: Covers mouse inputs, coordinates and visibility. +- Status: Completed +- Repo Links: + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Tutorial%20Markdowns/Getting%20Started%20With%20Mouse%20Button%20and%20Inputs.md) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Inputs/Getting%20Started%20With%20Mouse%20Button%20and%20Inputs.md) +- Proposal Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Getting%20Started%20With%20Mouse%20Button%20and%20Inputs.md) +- Website Links: + [_Live_](https://splashkit.io/guides/inputs/getting-started-with-mouse-button-and-inputs/) + +#### _Using Key Callbacks_ + +- Overview: Covers registering and deregistering key callbacks. +- Status: Completed +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/kcb/2023-07-30-using-keycallbacks.html.md) + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/kcb/2023-07-30-using-keycallbacks.html.md) + +#### _Introduction to Key Codes_ + +- Overview: A list of keycodes + example. +- Status: Completed +- Repo Links: + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Tutorial%20Markdowns/Introduction%20to%20Key%20Codes.md) +- Proposal Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Introduction%20to%20Key%20Codes.md) + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Introduction%20to%20Key%20Codes.md) + +--- + +### Sprites + +#### _Sprite Layering tutorial C++_ + +- Overview: Explanation of what sprite layering is with code and video of result. +- Status: Completed +- Repo Links: + [_SplashKit-Tutorial_]() + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Sprites/Sprite%20Layering%20Tutorial.md) +- Website Links: [_Live_](https://splashkit.io/guides/sprites/sprite-layering-tutorial/) + +#### _Getting Started With Sprites in Splashkit - C#_ + +- Overview: Explanation of what sprites are in SplashKit. +- Status: Needs Improvement/Checking + - Is quite good! One thing that might make it better is to just improve the explanation of what a + sprite is, since a sprite isn't really a bitmap, it's closer to an instantiation of a bitmap (as + mentioned later on in it). +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/Tutorial%20Markdowns/Getting%20Started%20With%20Sprites%20in%20Splashkit%20Tutorial%20-%20C%23/Getting%20Started%20With%20Sprites%20in%20Splashkit%20Tutorial%20-%20CSharp.md) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Sprites/Getting%20Started%20With%20Sprites%20csharp.md) +- Proposal Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Getting%20Started%20With%20Sprites%20in%20Splashkit%20Outline%20-%20C%23.md) + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Getting%20Started%20With%20Sprites%20in%20Splashkit%20Outline%20-%20C%23.md) +- Website Links: [_Live_](https://splashkit.io/guides/sprites/getting-started-with-sprites-csharp/) + +#### _Getting Started With Sprite layering in Splashkit - C#_ + +- Overview: Explanation of what sprite layering is with code and video of result. Slightly more + technical than 'Sprite Layering tutorial C++'. +- Status: Completed +- Repo Links: + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Tutorial%20Markdowns/Getting%20Started%20With%20Sprite%20Layering%20in%20Splashkit%20Tutorial%20-%20C%23/Sprite%20layering%20in%20Splashkit%20Tutorial%20-%20C%23.md) +- Proposal Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Getting%20Started%20With%20Sprite%20Layering%20In%20Splashkit%20-%20C%23.md) + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Getting%20Started%20With%20Sprite%20Layering%20In%20Splashkit%20-%20C%23.md) + +#### _Sprite Pack Documentation_ + +- Overview: An API reference for Sprite Packs. +- Status: Needs Improvement/Checking + - As mentioned, not really a tutorial. Would be good as part of an API page. +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Sprite%20Pack%20Documentation.md) + +--- + +### Camera + +#### _Using the Splashkit Camera_ + +- Overview: A guide on SplashKit's coordinate system and camera. +- Status: Completed +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/2018-08-16-about-camera.html.md.erb) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Camera/about-camera.mdx) +- Website Links: [_Live_](https://splashkit.io/guides/camera/about-camera/) + +--- + +### Audio + +#### _Get started with SplashKit Audio_ + +- Overview: A guide on playing sound effects and music. +- Status: Needs improvement + - A bit bare-bones. See the proposal 'Introduction to Splashkit Audio and Music Functions' for + perhaps a good replacement. +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/2018-06-10-about-audio.html.md.erb) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Audio/GettingStartedAudio.mdx) +- Website Links: [_Live_](https://splashkit.io/guides/audio/gettingstartedaudio/) + +--- + +### Animations + +#### _Using Animations_ + +- Overview: A guide to animation frames and scripts. +- Status: Completed +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/2018-05-29-animation.html.md.erb) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Animations/Using%20Animation.mdx) +- Website Links: [_Live_](https://splashkit.io/guides/animations/using-animation/) + +#### _Sprite Animation_ + +- Overview: Builds upon the "Using Animations", cover similar functionality (animations, movement, + etc) +- Status: Completed +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/Sprite%20Animation%20Tutorial/Sprite%20Animation%20Tutorial.md) + +--- + +### Networking + +:::note[Thoughts] + +While these tutorials are quite good, they feel very disconnected from the rest of SplashKit. +Wouldn't creating a (very simple) multiplayer game have been a better subject? I don't think anyone +is going to make a website using SplashKit. + +::: + +#### _Getting Started With Servers_ + +- Overview: A detailed tutorial about creating a web server that serves a file. +- Status: Completed +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/2018-07-14-getting-started-with-servers.html.md.erb) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Networking/getting-started-with-servers.mdx) +- Website Links: [_Live_](https://splashkit.io/guides/networking/getting-started-with-servers/) + +#### _Routing With Servers_ + +- Overview: A continuation of the previous tutorial, serving different pages to different routes. +- Status: Completed +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/2018-08-10-routing-with-servers.html.md.erb) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Networking/routing-with-servers.mdx) +- Website Links: [_Live_](https://splashkit.io/guides/networking/routing-with-servers/) + +#### _How to make a RESTful API call using Splashkit_ + +- Overview: A tutorial on making requests to RESTful APIs. +- Status: Completed +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/2018-10-03-restful-api-call.html.md.erb) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Networking/index.mdx) +- Website Links: [_Live_](https://splashkit.io/guides/networking/restful-api-call/) + +--- + +### Databases + +#### _Using Databases_ + +- Overview: An introduction to interacting with databases via SplashKit. +- Status: Needs Improvement/Checking + - The tutorial is well written and engaging. Only thing missing perhaps is a better explanation of + what a database is, since SplashKit is targetted at beginnners who may not know what they are. A + visual example with tables might be good? +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/2017-10-03-using-databases.html.md) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Database/using-databases.mdx) +- Website Links: [_Live_](https://splashkit.io/guides/database/using-databases/) + +#### _Getting Started With SplashKit Database_ + +- Overview: A much more in-depth tutorial on the database functions (closer to an API reference). +- Status: Completed +- Repo Links: + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Tutorial%20Markdowns/Getting%20Started%20With%20SplashKit%20Database.md) +- Proposal Repo Links: + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Getting%20Started%20With%20SplashKit%20Database.md) + +--- + +### JSON + +#### _Using JSON_ + +- Overview: A short explanation of JSON with a code example. +- Status: Needs improvement + - Doesn't provide much explanation of JSON nor why one would want to use it. The code example + clearly demonstrates writing, but is missing reading that data back in. +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/2017-10-03-using-json.html.md) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/JSON/using-json.mdx) +- Website Links: [_Live_](https://splashkit.io/guides/json/using-json/) + +--- + +### Utilities + +#### _Useful Utilities_ + +- Overview: Explanation of string convertion utilities. +- Status: Completed +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/2017-10-03-useful-utilities.html.md) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Utilities/useful-utilities.md) +- Website Links: [_Live_](https://splashkit.io/guides/utilities/useful-utilities/) + +--- + +### Game Creation + +:::note[Thoughts] + +While these tutorials are quite decent, they suffer from what seems to be a big problem. There isn't +actually a completed project that the tutorials are leading up to, and since some of the parts are +written by different people, there is a lack of continuity. Something introduced by one tutorial (as +an example: creating a floor using sprites), is then forgotten about in a future tutorial (which +then opts to quickly add a ground by drawing rectangles). + +It would be good if there was a 'source-of-truth' codebase for the finished game, that can then be +used as a base to keep the tutorials cohesive even when written by different people. + +::: + +#### _Creating a 2D Metroidvania Game (1, 2, 5, 6, 12)_ + +- Overview: A series on producing a Metroidvania game, have only skim read. Seems quite thorough and + well written. +- Status: Completed +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/Creating%20a%202D%20Metroidvania%20Game%20Using%20Splashkit/) + +#### _Creating a 2D Metroidvania Game (2)_ + +- Overview: See above. + +**Note:** There are **two** 'Part 2's, with somewhat overlapping content. Someone will need to +choose which one to use in the final series, or merge bits of them together. While this tutorial +suggests it comes after the _other_ part 2, I would recommend putting this one first, since this one +covers project creation with `skm new`, and doesn't go into as much detail about drawing graphics. + +- Status: Completed +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/Creating%20a%202D%20Metroidvania%20Game%20Project%20Structure%20and%20Initialization/Creating%20a%202D%20%22Metroidvania%22%20Game%20-%20Project%20Structure%20and%20Initialization.md) + +#### _Creating a 2D Metroidvania Game (3)_ + +- Overview: See above +- Status: Completed +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Creating%20a%202D%20_Metroidvania_%20Game%20-%20Player%20Character%20Basics.md) + +#### _Creating a 2D Metroidvania Game (4)_ + +- Overview: See above +- Status: Completed +- Repo Links: + [_SplashKit-Tutorial_]() + +#### _Creating a 2D Metroidvania Game (9)_ + +- Overview: See above +- Status: Completed +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Creating%20a%202D%20_Metroidvania_%20Game%20-%20Power-Ups%20and%20Items.md) + +#### _Creating a 2D Metroidvania Game (11)_ + +- Overview: See above +- Status: Completed +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Creating%20a%202D%20_Metroidvania_%20Game%20-%20Audio%20and%20Sound%20Effects.md) + +--- + +### Meta + +#### _Writing a SplashKit Guide_ + +- Overview: A guide to contributing to SplashKit's tutorials. +- Status: Completed +- Repo Links: + [_splashkit.io_](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/contributing/index.html.md.erb) + +--- + +### Debugging, Compilation and Publishing + +#### _Debugging Your Application in Visual Studio Code (VSCode)_ + +- Overview: Debugging in VSCode; watches and breakpoints. +- Status: Completed +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/VScodeDEbuggerTut.md) + +#### _CMake Tutorials 1 to 8_ + +- Overview: Tutorials on the syntax of CMake. +- Status: Needs Improvement/Checking + - While these are well written, they don't have a whole lot to do with SplashKit aside from the + final one (see below). Should they use and reference the SplashKit cmake file as an example each + time? +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/Cmake%20Tutorial/) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Others/Cmake/) +- Proposal Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Building%20the%20SplashKit%20Core%20Library%20with%20CMake.md) + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Building%20the%20SplashKit%20Core%20Library%20with%20CMake.md) +- Website Links: [_Live_](https://splashkit.io/guides/others/cmake/1-get-started/) + +#### _CMake #9. Building the SplashKit Core Library with CMake_ + +- Overview: Final tutorial on CMake, covering compiling SplashKit Core with it. +- Status: Completed +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/Cmake%20Tutorial/9.%20Cmake%20with%20SplashKit.md) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Others/Cmake/9.%20Cmake%20with%20SplashKit.md) +- Proposal Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Building%20the%20SplashKit%20Core%20Library%20with%20CMake.md) + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Building%20the%20SplashKit%20Core%20Library%20with%20CMake.md) +- Website Links: [_Live_](https://splashkit.io/guides/others/cmake/9-cmake-with-splashkit/) + +#### _Publishing in SplashKit - C# / C++_ + +- Overview: Short tutorial explaining how to publish a game made in SplashKit, with regards to + assets and such. +- Status: Completed +- Repo Links: + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Tutorial%20Markdowns/Publishing%20with%20SplashKit%20-%20C%23) + [_splashkit.io-starlight_](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Others/Publishing%20with%20SplashKit%20Csharp.md) +- Website Links: [_Live_](https://splashkit.io/guides/others/publishing-with-splashkit-csharp/) + +--- + +### General Programming Via SplashKit (possibly irrelevant) + +#### _The Programmers Field Guide Part 0-3_ + +- Overview: Uses SplashKit while teaching general programming. +- Status: Completed +- Repo Links: + [_the-programmers-field-guide_](https://github.com/splashkit/the-programmers-field-guide/tree/main/src/content/docs/book/part-0-getting-started/3-building-programs/) + +--- + +### Other (are these actually proposals?) + +#### _Game Concept Ideas_ + +- Overview: An article on resources to help with coming up with game concepts and resources. +- Status: Needs improvement + - While it's solid as an article, the way it presents itself as the first tutorial in a series + (which as far as I can tell does not exist) makes its actual goal confusing. Unless further + tutorials in this series will be made, I suggest re-writing parts of it to make it self + contained. Is it actually a proposal? If so, why is it so long? +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/Game%20Concept.md) + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Game%20Concept.md) + +#### _Design Tutorial for 2D racer_ + +- Overview: An article describing some principles of UX/UI +- Status: Needs improvement + - Same thoughts as above. It's solid as an introductory article, but it isn't a tutorial. Again, + perhaps it's a proposal? +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/2d%20Racer%20Design%20tutorial.md) + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/2d%20Racer%20Design%20tutorial.md) + +#### _Controls_ + +- Overview: A list of the controls needed to be compatible with the arcade machine. Not a tutorial. +- Status: Needs improvement + - The file itself is fine, but it shouldn't be in tutorials. +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/arcade_controls.md) + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/arcade_controls.md.md) + [_arcade-games_](https://github.com/thoth-tech/arcade-games/blob/master/README.md) + +## Proposals + +--- + +### Incomplete (On Trello) + +#### _Creating a 2D Metroidvania Game (7, 8, 10, 13)_ + +- Overview: The remaining parts in a series on producing a Metroidvania game. +- Status: Incomplete + +#### _Introduction to Splashkit Audio and Music Functions_ + +- Overview: Proposal for introduction to audio and music functions. +- Status: Incomplete + - Seems to overlap with 'Get started with SplashKit Audio' but much more in-depth. Possibly a good + replacement. +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Audio%20Series/Basic%20Audio%20Manipulation%20in%20Splashkit.md) + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Basic%20Audio%20Manipulation%20in%20Splashkit.md) + +#### _Managing Audio Resources in Splashkit_ + +- Overview: Covers sound and music resource management. +- Status: Incomplete + - Seems to overlap with 'Get started with SplashKit Audio' but much more in-depth. Possibly a good + replacement. +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Audio%20Series/Managing%20Audio%20Resources%20in%20Splashkit.md) + +#### _Working with Sound Effects in Splashkit_ + +- Overview: Covers specifically sound effects, playing them, etc. +- Status: Incomplete + - Seems to overlap with 'Get started with SplashKit Audio' but much more in-depth. Possibly a good + replacement. +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Audio%20Series/Working%20with%20Sound%20Effects%20in%20Splashkit.md) + +#### _Software Requirements Specification for Mario-Like Game Tutorial Using Splashkit_ + +- Overview: Proposal for a Mario-like game tutorial. +- Status: Probably incomplete. +- Repo Links: + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Splash%20World%20Adventures.md) + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Splash%20World%20Adventures.md) + +#### _Understanding SplashKit Manager (SKM) Shell Commands_ + +- Overview: Covers SplashKit project setup + other commands. +- Status: Probably incomplete. + - Overlaps with 'Getting Started: C++, C#, Python, and Pascal - Windows'. See above. Also mostly + already covered by 'Getting Started With SplashKit - Windows C#/C++' +- Repo Links: + [_SplashKit-Tutorial_]() + [_documentation_]() + +--- + +### Incomplete (Not on Trello) + +#### _Using JSON Files_ + +- Overview: Proposal for a more complete JSON tutorial. +- Status: Incomplete +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Proposal%20for%20SplashKit%20JSON%20Functionality%20Tutorial%20Series.md) + +#### _2 D Racer - Features to keep & add_ + +- Overview: Proposal for features in 2D Racer? +- Status: Probably incomplete. +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/2%20D%20Racer%20-%20Features%20to%20keep%20%26%20add.md) + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/2%20D%20Racer%20-%20Features%20to%20keep%20%26%20add.md) + +### Incomplete (Archived/Deleted) + +#### _Getting Started: C++, C#, Python, and Pascal - Windows_ + +- Overview: Covers installing MSYS2, SplashKit and VSCode + project setup. +- Status: Archived - too much overlap. + - Overlaps with 'Understanding SplashKit Manager (SKM) Shell Commands'. See below. Also mostly + already covered by 'Getting Started With SplashKit - Windows C#/C++' +- Repo Links: + [_SplashKit-Tutorial_](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Getting%20Started%20in%20Splashkit%20Outline.md) + [_documentation_](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Getting%20Started%20in%20Splashkit%20Outline.md) + +## [For Reference] Current SplashKit Tutorial/Proposal Directories + +All the directories listed below contain either tutorials or proposals (or both). In its current +state, tutorials and proposals seem to be mixed together and files from the same series are +scattered across folders. There is also a lot of duplication. + +The current plan for future tutorials seems to be to store all tutorials under +[splashkit.io-starlight](https://github.com/thoth-tech/splashkit.io-starlight), and all tutorial +proposals under +[ThothTech-Documentation-Website](https://github.com/thoth-tech/ThothTech-Documentation-Website). We +should attempt to migrate all tutorials to fit under that structure at some point. There are also +some completed tutorials that are not currently live on any site - it should be investigated if +there is a reason for this. + +### Tutorials + +- [https://github.com/splashkit/splashkit.io/tree/develop/source](https://github.com/splashkit/splashkit.io/tree/develop/source/) + - [articles/contributing](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/contributing/) + - [articles/guides](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/guides/) + - [articles/installation](https://github.com/splashkit/splashkit.io/tree/develop/source/articles/installation/) +- [https://github.com/thoth-tech/SplashKit-Tutorial/blob/main](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/) + - [Tutorial Proposals](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/) + - [kcb](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/kcb/) + - [Tutorials](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/) + - [Cmake Tutorial](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/Cmake%20Tutorial/) + - [Creating a 2D Metroidvania Game Using Splashkit](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/Creating%20a%202D%20Metroidvania%20Game%20Using%20Splashkit/) + - [Sprite Layering Tutorial (C++)]() + - [Tutorial Markdowns/Getting Started With Sprites in Splashkit Tutorial - C#](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/Tutorial%20Markdowns/Getting%20Started%20With%20Sprites%20in%20Splashkit%20Tutorial%20-%20C%23/) +- [https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials and Research](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/) + - [Tutorial Proposals/Tutorial Markdowns](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Tutorial%20Markdowns/) + - [Getting Started With SplashKit - C#-C++](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Tutorial%20Markdowns/Getting%20Started%20With%20SplashKit%20-%20C%23-C%2B%2B/) + - [Getting Started With Sprite Layering in Splashkit Tutorial - C#](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/Tutorial%20Markdowns/Getting%20Started%20With%20Sprite%20Layering%20in%20Splashkit%20Tutorial%20-%20C%23/) + - [Tutorial Proposals/kcb](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/kcb/) +- [https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/) + - [Animations](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Animations/) + - [Audio](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Audio/) + - [Camera](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Camera/) + - [Database](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Database/) + - [Inputs](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Inputs/) + - [JSON](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/JSON/) + - [Networking](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Networking/) + - [Others](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Others/) + - [Cmake](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Others/Cmake/) + - [Sprites](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Sprites/) + - [Starter](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Starter/) + - [Utilities](https://github.com/thoth-tech/splashkit.io-starlight/blob/master/src/content/docs/guides/Utilities/) +- [https://github.com/thoth-tech/splashkit.io-starlight/tree/master/src/content/docs/installation](https://github.com/thoth-tech/splashkit.io-starlight/tree/master/src/content/docs/installation/) + +### Tutorial Proposals + +- [https://github.com/thoth-tech/SplashKit-Tutorial/blob/main](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/) + - [Tutorial Proposals](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/) + - [Audio Series](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorial%20Proposals/Audio%20Series/) + - [Tutorials](https://github.com/thoth-tech/SplashKit-Tutorial/blob/main/Tutorials/) +- [https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials and Research/Tutorial Proposals](https://github.com/thoth-tech/documentation/blob/main/docs/Splashkit/Applications/Tutorials%20and%20Research/Tutorial%20Proposals/) diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/07-Tutorial-JSON.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/07-Tutorial-JSON.mdx new file mode 100644 index 00000000..f492587d --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/07-Tutorial-JSON.mdx @@ -0,0 +1,85 @@ +--- +title: Tutorial links in API Documentation pages using JSON Files +description: Use this as a guide to create JSON files for your new tutorial. +sidebar: + label: Tutorial JSON File +--- + +import { FileTree } from "@astrojs/starlight/components"; + +For the [splashkit.io](https://splashkit.io/) website, JSON files are now used to list all the +functions used in the guides pages, to link them in to the API documentation pages for SplashKit +users to see if a function has been demonstrated in any of the guides. + +Here is information about how this is set up: + +### Directory + + + +- scripts/ + - json-files/ + - guides/ + - Animations/ + - animations.json + - Audio/ + - audio.json + - Camera/ + - camera.json + - Graphics/ + - graphics.json + - Input/ + - input.json + - Interface/ + - interface.json + - JSON/ + - json.json + - Networking/ + - networking.json + - Raspberry-GPIO/ + - raspberry-gpio.json + - Resource-Bundles/ + - resource-bundles.json + - Utilities/ + - ultilies.json + + + +When creating a folder for a new category, it can be placed within the guides folder. The JSON file +for a certain category should be the folder's name in lowercase. + +### Content + +Each guides' entry need to contain a name, an array of the functions used, and the url to the guide +page. It is important to use the function's **unique_global_name** to ensure the correct function is +linked on the documentation site. Each new addition can be added consecutively using the curly +brackets. + +```json +{ + "guides": [ + { + "name": "Introduction to JSON in SplashKit", + "functions": [ + "json_from_file", + "json_read_string", + "write_line", + "free_json", + "json_has_key" + ], + "url": "/guides/json/0-json_intro/" + }, + { + "name": "Reading JSON Data in SplashKit", + "functions": [ + "json_read_array_of_string", + "write_line", + "write", + "json_read_object", + "json_read_number_as_int" + ], + "url": "/guides/json/1-json_reading/" + } + ] +} +``` diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/images/skbox.png b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/images/skbox.png new file mode 100644 index 00000000..06dcae37 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Tutorials Documentation/images/skbox.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/01-overview.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/01-overview.mdx new file mode 100644 index 00000000..6be550e9 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/01-overview.mdx @@ -0,0 +1,97 @@ +--- +title: Usage Example Overview +description: Learn how to create, submit, and review usage examples for the Splashkit website. +sidebar: + label: Overview +--- + +import { Steps } from "@astrojs/starlight/components"; +import { LinkCard } from "@astrojs/starlight/components"; + +### What are Usage Examples? + +Usage examples demonstrate a specific Splashkit function within a simple, small program. The goal is +to keep the program minimal while clearly showing how the function works. + +For instance, the `write_line` example on the Splashkit site found +[here](https://splashkit.io/api/terminal/#write-line), clicking on the `See Code Example` shows how +the `write_line` function works, with a brief title of the program, program code, and a screenshot +of the output. + +The following pages cover all the steps to create, submit, and review usage examples for the +Splashkit website. + +## Steps to Completing a Usage Example + + + +1. ### Choose a Planner Card or Idea + + Pick an existing planner card that matches a SplashKit function, or create a unique example. + + Make sure the idea clearly demonstrates the function in a practical or visually interesting way. + +2. ### Develop a Demonstrative Program + + Write a simple program to illustrate the function’s use. Focus on clarity and simplicity, + ensuring that the code is easy to follow and that it showcases the function effectively. + +3. ### Write the Program in Multiple Languages + - **C++**: Implement the example with standard C++ practices. + - **C#**: Provide both a version using top-level statements and an Object-Oriented (OOP) version. + - **Python**: Write a Python version that is straightforward and reflects the same functionality. + +4. ### Create a Title for the example + - Think of a title that describes the overall functionality of the program. + - Be creative with this title. It should not be the name of the function, or use the word + "Example". + +5. ### Capture Output of Program + + Run the program in any of the languages to capture the details of the program running. + + You might do this with a screenshot, screen recording converted to a GIF, or an audio recording. + + | Output Format | Accepted File Type | Example of when to use | + | ---------------- | ------------------ | --------------------------------------------------------- | + | Screenshots | `.png` file | Simple program without any user inputs or animations. | + | Screen Recording | `.gif` file | The program has user inputs or animations to demonstrate. | + | Audio Recording | `.webm` file | The program include audio sounds. | + +6. ### Add Files to the Correct Folder in the SplashKit Repository + - Copy your files into the appropriate folder within the `splashkit.io-starlight` repository. + - Ensure file names and directory paths are consistent with SplashKit’s structure. + +7. ### Submit a Pull Request for Usage Examples + + Follow the steps in the + [Pull Requests for Usage Examples guide](/products/splashkit/05-pull-request-template/). + + Use the provided PR template, describe your example clearly, and attach explanations and + screenshots to the pull request. + + + +## Links to other pages + + + + + diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/02-creating-usage-examples.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/02-creating-usage-examples.mdx new file mode 100644 index 00000000..9799008e --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/02-creating-usage-examples.mdx @@ -0,0 +1,211 @@ +--- +title: Guide to creating usage examples +description: Learn how to create, submit, and review usage examples for the Splashkit website. +sidebar: + label: Creating Usage Examples +--- + +import { Tabs, TabItem } from "@astrojs/starlight/components"; +import { FileTree } from "@astrojs/starlight/components"; + +This guide explains how to create a usage example for the Splashkit website. + +### What are Usage Examples? + +Usage examples demonstrate a specific Splashkit function within a simple, small program. The goal is +to keep the program minimal while clearly showing how the function works or how it can be utilised. + +For instance, the `write_line` example on the Splashkit site shows how the `write_line` function +works, with a relevant title, program code, and a file showing the program output. + +![example showing on site for write line function](./images/usageexample.png) + +### Steps to Create a Usage Example + +An initial usage example includes 6 files: + +- C++ version +- C# (top-level statements) version +- C# (Object-Oriented Programming) version +- Python version +- Descriptive title for the example, in a text file +- Screenshot of the output + +1. ### Choosing a Function + + The planner board has numerous usage example suggestions for various functions, however you are + welcomed and encouraged to come up with your own creative ideas for these. Scroll through the + [API Documentation](https://splashkit.io/api/) to find various functions you could use for the + usage example, when coming up with an idea, make sure to also check to see if anyone else has + already done it. + + The goal is to create **one usage example per function** in the SplashKit library. Building out + these single examples for each function is the priority to round out the variety of examples + available. + + If you come up with a creative idea for a function that already has an example, please share it + in the SplashKit group chat or reach out to your Capstone Mentor to discuss whether it's a good + idea to add another example for that function. + +2. ### Creating The Program + + Create the program with as few lines of code as possible. You'll need to write the program in + C++, C# (using top-level statements and OOP version), and Python, all using Splashkit. Start with + the language you're most comfortable with, then convert it to the others. + + Note for C# to-level: Use `using static SplashKitSDK.SplashKit;`. For the OOP version: use + `using SplashKitSDK;`. + + #### Example + + If C++ is your strength, begin by creating a small program like this `dec_to_hex` example: + + ```cpp + #include "splashkit.h" + + int main() + { + write_line("Hello! Welcome to the decimal to hexadecimal converter."); + + // Prompt the user for a decimal input + write_line("Please enter a decimal number:"); + + // Read the input as a string + string dec_input = read_line(); + + // Convert the input string to an unsigned integer + unsigned int dec_value = convert_to_integer(dec_input); + + // Convert the decimal value to hexadecimal format + string hex_value = dec_to_hex(dec_value); + + // Display the result in hexadecimal format + write_line("The decimal value in hexadecimal format is: " + hex_value); + + return 0; + } + ``` + + This example includes meaningful comments that clearly explain each part of the program, which + helps readers understand both the structure and function. When converting to C#, notice that the + structure and comments are kept consistent, with syntax changes specific to the language: + + ```csharp + using static SplashKitSDK.SplashKit; + + WriteLine("Hello! Welcome to the decimal to hexadecimal converter."); + + // Prompt the user for a decimal input + WriteLine("Please enter a decimal number:"); + + // Read the input as a string + string dec_input = ReadLine(); + + // Convert the input string to an unsigned integer + uint dec_value = ConvertToInteger(dec_input); + + // Convert the decimal value to hexadecimal + string hex_value = DecToHex(dec_value); + + // Display the result + WriteLine("The decimal value in hexadecimal format is: " + hex_value); + ``` + +3. ### Title and Screenshot + + Provide a creative title and a screenshot of the program's output. + + **Title:** Simple Decimal to Hexadecimal Converter + + Take a screenshot of the output window and save it. If the screenshot is of the terminal window, + please crop out any commands used to run the program. + +4. ### Adding these files to Splashkit Starlight.io + + Now that you're done, you should have the following 6 files when completing an initial usage + example PR: + + + - txt file - C++ file - python file - C# (top-level statements) file - C# (OOP) file - Screenshot + of the output + + +Now you'll need to rename these before adding them to the Splashkit Starlight.io repo. + +#### Example + +Say you've created a `write_line` program. Rename the files as follows: + +```plaintext +write_line-1-example-oop.cs +write_line-1-example-top-level.cs +write_line-1-example.cpp +write_line-1-example.png or .gif +write_line-1-example.py +write_line-1-example.txt +``` + +In a separate pull request, to add to existing examples: + +```plaintext +write_line-1-hello-world-beyond.cpp +``` + +Now you can add these files to the Splashkit Starlight.io repo. If when you add them you find there +is already some files of a usage example using this same function, then you should increment the +number in the file name by 1. Furthermore, it is important that you use the function's unique global +name for the files names _(This only applies for functions that are overloaded.)_ + +Now that your files are named, add all of your files to the `usage-examples` folder under the +appropriate function category (e.g., `terminal/`). The location in the Statlight.io repo is: + + + +- public + - usage-example-files + - animations/ + - audio/ + - camera/ + - color/ + - geometry/ + - graphics/ + - input/ + - interface/ + - json/ + - logging/ + - networking/ + - physics/ + - rasberry/ + - resources_bundles/ + - resources/ + - sprites/ + - terminal/ + - write_line-1-example-oop.cs + - write_line-1-example-top-level.cs + - write_line-1-example.cpp + - write_line-1-example.png + - write_line-1-example.py + - write_line-1-example.txt + - timers/ + - utilities/ + - windows/ + + + +For more information regarding the proper file naming and placement can be found within the repo in +the `CONTRIBUTING.mdx`. The location of the file can be found here: + + + +- public + - usage-examples + - CONTRIBUTING.mdx + + + +## Next Steps + +Now follow the steps in +[Usage Example Pull Requests](/products/splashkit/05-pull-request-template/), and submit your usage +example for review. For doing a peer review, follow the steps in +[Peer Review Guide for Usage Examples](/products/splashkit/documentation/splashkit-website/usage-examples/04-usage-peer-review). diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/04-usage-peer-review.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/04-usage-peer-review.mdx new file mode 100644 index 00000000..e33b46e6 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/04-usage-peer-review.mdx @@ -0,0 +1,142 @@ +--- +title: How to do a Peer Review for Usage Examples +description: Learn how to create, submit, and review usage examples for the Splashkit website. +sidebar: + label: Usage Peer Review +--- + +## Peer Reviewing a Usage Example + +Doing a peer review for usage examples follows the same process as the +[peer review guide](/products/splashkit/06-peer-review). However, you will need to follow the steps +for reviewing usage examples. + +When reviewing an example, follow these steps: + +### 1. Test the code + +Compile/run each code file on your machine. + +- Are there any errors? +- Are there any warnings? +- Does the program run as expected? + +### 2. Analyse the effectiveness + +Consider the function being demonstrated and how it might be used by a SplashKit user. + +- Does the code example demonstrate the usefulness of the function? +- Or, do the code example give more insight into how the function works? +- Is the example simple enough for an SIT102 or SIT771 student to follow, while still being an + interesting example? + +### 3. Compare and analyse the code + +Check the structure and functionality of the code in each language. + +- Does the sequence of code match for all code files? +- Do the code comments match across all code files? +- Does the code follow the + [style guide](/products/splashkit/documentation/splashkit-website/usage-examples/05-usage-example-style-guide) + requirements? +- Is the Object Oriented C# code using the Object Oriented format where possible/relevant? +- Is the python code using the correct function names? (These function names will often differ from + other languages due to python not handling function overloads) + +### 4. Test in localhost + +Check the example displays correctly in your local development environment. + +- Does the website build successfully with `npm run build`? +- Does the example display under the correct function when previewing the website with + `npm run preview`? +- Is the correct function highlighted in the example code? + +### 5. Request changes + +Add your review comments on the pull request on GitHub. + +- Add comments for individual lines, or groups of lines in the code files. This helps the original + contributor to understand exactly what the issue is related to. +- Use professional language, and be polite but assertive. +- Include the correct version of code where relevant, or any suggested improvements. +- Ask questions if something is confusing or unclear. + +:::note + +**First Peer Review:** + +- It is _very unlikely_ that you will approve a pull request on first review without any changes. +- We all miss things in our own code, which is why peer reviews are so important. + +**Second Peer Review:** + +- This review is more likely to be able to be approved without changes being requested. +- However, it is important to check that the first reviewer did not miss anything that _should have + been found_ in the first review. +- You might also have experience that allows you to consider other aspects that the first reviewer + would not have noticed. + +::: + +### 6. Continue discussion about changes on the pull request + +Check for replies on the pull request from the original contributor. + +- These comments might be requesting more information about your suggested changes, so it is + important to respond quickly. +- Discussions may include some debate on the best way forward. Be open to the ideas suggested by the + other person, and include evidence to back up your reasoning. +- If needed, either the reviewer or the original contributor can reach out to your Mentor to help + decide what the outcome should be. +- Check for a comment from the original contributor that the requested changes have been made. + +### 7. Review the pull request again + +Repeat steps 1 - 4 above. + +- It is important to review the pull request thoroughly to ensure that the changes have not caused + other issues. +- You may notice other issues once changes have been made. This is okay, and is part of the + development process. +- Ensure that the pull request will be able to be merged upstream to the live site before you + approve it. + +### 8. Approve the pull request + +Once all the requested changes have been made, approve the pull request using the following template +in the comment of the approving review: + +```plaintext +# Peer Review + +I've reviewed the ... + +## Checks + +- [ ] All required files are present. + - [ ] Example Title (.txt) + - [ ] C++ code + - [ ] C# code (top-level statements) + - [ ] C# code (Object-Oriented Programming) + - [ ] Python code +- [ ] Code correctly uses Splashkit functions. +- [ ] Code clearly demonstrates the function. +- [ ] All versions maintain the same structure and comments. + +## Code Tests done + +- [ ] C++ code ran correctly. +- [ ] C# top level code ran correctly. +- [ ] C# OOP code ran correctly. +- [ ] Python code ran correctly. + +## Website Tests done + +- [ ] npm run build +- [ ] npm run preview +``` + +Ensure while doing peer reviews that you also follow the +[Planner Board Etiquette](/products/splashkit/07-planner-board) for moving tasks through the +process. diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/05-usage-example-style-guide.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/05-usage-example-style-guide.mdx new file mode 100644 index 00000000..e2309f2f --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/05-usage-example-style-guide.mdx @@ -0,0 +1,500 @@ +--- +title: Usage Example Style Guide +description: General rules to follow when creating usage examples +sidebar: + label: Style Guide +--- + +import { Steps, Tabs, TabItem } from "@astrojs/starlight/components"; + +## Code Style and Formatting Guide + +This guide aims to introduce new team members to some standard practices for contributing to +splashkit, such as variable declarations, formatting across languages and general do's and don'ts + +## Naming Conventions + +These are general naming conventions for variables, functions, namespaces and more that should be +used when creating usage examples for SplashKit. + +### 1. Variable declarations + +Variable declarations for SplashKit usage examples should be in the following format: + +| Language | Naming convention | Variable Example | +| -------- | ----------------- | ---------------------- | +| C++ | snake_case | `string variable_name` | +| C# | camelCase | `string variableName` | +| Python | snake_case | `variable_name` | + +See the examples below: + + + + +```cpp +#include "splashkit.h" + +int main() +{ + // Declare a variable with snake_case + string variable_name = "This is snake case"; + return 0; +} +``` + + + + + + + +```csharp +using static SplashKitSDK.SplashKit; + +// Declare a variable with camelCase +string variableName = "this is an example of camelCase"; +``` + + + + +```csharp +using SplashKitSDK; + +namespace VariableExample +{ + public class Program + { + public static void Main() + { + // Declare a variable with camelCase + string variableName = "this is an example of camelCase"; + + } + } +} +``` + + + + + + + +```python +from splashkit import * + +# declare a variable with snake_case +variable_name = "This is snake case" + +``` + + + + +**Other guidelines when creating variables**: + +| Do | Don't | +| ------------------------------------- | ----------------------------------- | +| Use descriptive variable names | Use `i`, `x`, `val` in main logic | +| Use variables for multiple use values | Declare a variable for one time use | +| Use proper types for variables | Use types such as `var` and `float` | + +### 2. Function and Methods + +When calling and naming functions and methods using SplashKit we do the following: + +| Language | Naming convention | Function/Method Example | +| -------------------- | ----------------- | ------------------------------------ | +| C++ | snake_case | `refresh_screen(60)` | +| C# (Top-Level) | PascalCase | `RefreshScreen(60)` | +| C# (Object-Oriented) | PascalCase | `SplashKit.RefreshScreen(60)` | +| Python | snake_case | `refresh_screen_with_target_fps(60)` | + +:::tip[Python function names] + +Python function names will often differ from other languages due to python not handling function +overloads. The example above shows the difference for this overload of Refresh Screen. + +You can check the correct function signature in the [API Documentation](https://splashkit.io/api/) +pages. + +::: + +### 3. C# Namespaces (Object-Oriented) + +The namespace for a usage example in C# (Object-Oriented version) should be written in Pascal case, +and will follow the convention of: The name of the function being demonstrated, with the word +"Example" added on the end, also written in Pascal case. + +**For example**: + +```csharp +using SplashKitSDK; + +namespace DrawRectangleExample +{ + // ... +} +``` + +### 4. Window Names + +When using windows to display any graphics the window name should be a description of what is +happening on the window rather than the name of the function you are displaying. + +| Good Window Name | Bad Window Name | +| ---------------------------------------- | -------------------------------------- | +| `"Colourful Starburst"` | `"Draw Line"` | +| ![Good window name](images/goodname.png) | ![Bad window name](images/badname.png) | + +## Formatting, Structure and Readability + +### Code Comments + +Code comments should be used to explain the _why_ behind code, not the _what_. Code comments should +be clear and concise + +A good Comment should explain the intent or purpose A bad comment will state the obvious + +| Do | Don't | +| --------------------------------------------- | -------------------------------------------------------------------------------- | +| `// Draw rectangle to window` | `// Call the DrawRectangle function` | +| `// Wait for user input` | `// Hold program to wait for user to press any key before the program continues` | +| Use comments for complex or non-obvious logic | Use comments to repeat code literally | +| Use comments for group of code or code block | Use comments for only the line below the comment | + +#### C# Example + +**Good comment example**: + +```csharp +// End the game if the player runs out of health +if (playerHealth <= 0) +{ + WriteLine("Game Over"); +} +``` + +**Bad comment example**: + +```csharp +if (playerHealth <= 0) +{ + // Call WriteLine when health reaches 0 + WriteLine("Game Over"); +} +``` + +### Braces and Indentation + +- **Braces:** Place braces (curly brackets) on the line following the declaration. +- **Indentation:** Between any new pair of curly brackets (`{`, `}`), write your code **4** further + spaces in from the left. + +**Do**: + +```cpp +int main() +{ + // ... +} +``` + +**Don't do**: + +```cpp +int main() { + // ... +} +``` + +### If Statements + +- The if statement condition should be on its own line. +- Use braces, even if just 1 line below, as this is easier for beginners to read. + +**Do**: + +```cpp +if (mouse_clicked(LEFT_BUTTON)) +{ + x -= SPEED; +} +``` + +**Don't do**: + +```cpp +if (mouse_clicked(LEFT_BUTTON)) x-= SPEED; +``` + +### Graphical Examples + +- If your program is using a Graphical Window, any text information should be displayed on the + Window. +- Do not use terminal outputs when using a graphics window in your program. + +### Looping + +- Do not use infinite loops, such as `while(true)`, as this is poor practice. +- Instead, use a loop condition that is defined by a boolean function, such as + `while (!quit_requested())`. + +### Use simple code + +As SplashKit usage examples are targeted to beginners, so it's important to keep the code as simple +and readable as possible. + +Avoid using advanced features such as: + +- **Ternary statements/operators** (`condition ? value-if-true : value-if-false`), and instead, + stick to traditional if/else statements. + +## C# OOP vs Top Level + +### Understanding the Differences Between Top-Level and OOP Styles + +**Top-Level Statements**: + +- Top-level statements allow you to write C# code without explicitly defining a class or `Main` + method. +- Uses the directive: `using static SplashKitSDK.SplashKit;`, so SplashKit functions are called + directly, such as `WriteLine("Hello!");`. + +**Object-Oriented Programming (OOP)**: + +- OOP-style C# code requires defining a `Main` method inside a class. +- Uses `using SplashKitSDK;`, meaning all SplashKit commands are prefixed with `SplashKit.` (e.g., + `SplashKit.WriteLine("Hello!");`). + +### Some key differences + +:::note + +When converting to OOP you should try and create and use objects where possible. + +::: + +Some key differences to note when converting between OOP and top level statements are that OOP +should be seeking to highlight the objectivity where possible. + +Note the code examples below: + +```csharp +// OOP Code +using SplashKitSDK; + +namespace DrawRectangleOnWindowExample +{ + public class Program + { + public static void Main() + { + Rectangle rectangle = new Rectangle { X = 100, Y = 100, Width = 100, Height = 100 }; + Window window = new Window("Example", 600, 400); + + window.Clear(Color.White); + window.DrawRectangle(Color.Red, rectangle); + window.Refresh(); + SplashKit.Delay(5000); + window.Close(); + } + } +} +``` + +```csharp +// Top Level Code +using SplashKitSDK; +using static SplashKitSDK.SplashKit; + +Rectangle rectangle = RectangleFrom(100, 100, 100, 100); +Window window = OpenWindow("Example", 600, 400); + +ClearWindow(window, ColorWhite()); +DrawRectangleOnWindow(window, ColorRed(), rectangle); +RefreshWindow(window); +Delay(5000); +CloseWindow(window); +``` + +The two code blocks here are functionally identical, but highlight some key differences between top +level code and OOP code. + +Notice in the OOP code, we create the `rectangle` and `window` objects, and then perform the drawing +of the rectangles through the objects' methods. In the top level code however we are calling +functions and passing in the object as parameters. + +Another key difference here, in OOP we call the color class `Color` and specify the colour we want +via the member `Red` whereas in Top Level code we call the function `ColorRed()`. + +:::tip[Using SplashKit.OpenWindow] + +For examples that do not require a `Window` variable, the C# OOP code should use +`SplashKit.OpenWindow(...)` rather than `new Window(...)`. + +This also applies to other SplashKit types such as Bitmaps and Fonts. + +::: + +--- + +### Converting from Top-Level Statements to OOP + +To convert from top-level statements to OOP, follow these steps: + + + +1. **Add a Namespace and Class**: + + Wrap your code in a namespace and class with a `Main` method. + +2. **Adjust the `using` Directive**: + + Replace `using static SplashKitSDK.SplashKit;` with `using SplashKitSDK;`. + +3. **Prefix SplashKit Functions**: + + Add `SplashKit.` before each SplashKit function. + + + +--- + +#### Example Conversion + +**Top-Level Code**: + +```csharp +using static SplashKitSDK.SplashKit; + +WriteLine("What is your name?"); +string name = ReadLine(); + +WriteLine("Hello, " + name + "!"); +``` + +**Converted to OOP**: + +```csharp +using SplashKitSDK; + +namespace WriteLineExample +{ + public class Program + { + public static void Main() + { + SplashKit.WriteLine("What is your name?"); + string name = SplashKit.ReadLine(); + + SplashKit.WriteLine("Hello, " + name + "!"); + } + } +} +``` + +### Converting from OOP to Top-Level Statements + +To convert from OOP to top-level statements: + + + +1. **Remove Namespace and Class Wrapping**: + + Delete the `namespace` and `class` definitions along with the `Main` method. + +2. **Adjust the `using` Directive**: + + Replace `using SplashKitSDK;` with `using static SplashKitSDK.SplashKit;`. + +3. **Remove the `SplashKit.` Prefix**: + + Directly call functions like `WriteLine()` and `ReadLine()`. + + + +--- + +#### Example Conversion + +**OOP Code**: + +```csharp +using SplashKitSDK; + +namespace WriteLineExample +{ + public class Program + { + public static void Main() + { + SplashKit.WriteLine("What is your name?"); + string name = SplashKit.ReadLine(); + + SplashKit.WriteLine("Hello, " + name + "!"); + } + } +} +``` + +**Converted to Top-Level Statements**: + +```csharp +using static SplashKitSDK.SplashKit; + +WriteLine("What is your name?"); +string name = ReadLine(); + +WriteLine("Hello, " + name + "!"); +``` + +### Quick Reference + +**Top-Level to OOP**: + +- Replace `using static SplashKitSDK.SplashKit;` with `using SplashKitSDK;`. +- Wrap code in: + + ```csharp + namespace FunctionNameExample + { + public class Program + { + public static void Main() + { + // Code here + } + } + } + ``` + + :::note[Namespace naming] + + In the namespace name, replace `FunctionName` with the name of the function, using PascalCase. + + ::: + +- Prefix SplashKit functions with `SplashKit.`. + +**OOP to Top-Level**: + +- Replace `using SplashKitSDK;` with `using static SplashKitSDK.SplashKit;`. + + :::note[Variables with SplashKit types] + + If your code has variables with a SplashKit data type, such as `Window`, `Bitmap`, etc, then you + will need to include `using SplashKitSDK;` as well. + + You can then comment this line out, and check that only the SplashKit variables have error + squiggles, then uncomment the line again. + + ::: + +- Remove `namespace`, `class`, and `Main` method wrappers. +- Remove `SplashKit.` prefixes. + +Using this guide, you can quickly convert between top-level statements and OOP formats in SplashKit +tutorials, making the code accessible for different programming preferences. diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/06-updating-examples.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/06-updating-examples.mdx new file mode 100644 index 00000000..57d1615f --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/06-updating-examples.mdx @@ -0,0 +1,181 @@ +--- +title: Updating Usage Examples by Adding a Missing Language +description: + Learn how to update an existing usage example by adding a missing language to the Splashkit + website. +sidebar: + label: Updating Usage Examples +draft: true +--- + +import { Tabs, TabItem } from "@astrojs/starlight/components"; +import { FileTree } from "@astrojs/starlight/components"; + +This guide explains how to add a missing language to an existing usage example for the Splashkit +website. + +### Steps to Update a Usage Example with a Missing Language + +When updating an existing usage example with a missing language, your contribution should include: + +1. Code in the missing language(s) +2. Consistent comments and formatting across all language versions +3. Updated file list with the new language version(s) + +## Updating Usage Examples with Missing Languages + +--- + +1. ### Reviewing Existing Examples + + Planner cards are typically created to update existing examples with missing languages. Review + the planner board to find examples that need additional languages to be added. + + For instance, if an example of `dec_to_hex` exists in C++ and Python but lacks a C# version and + there is a planner card for it, you can add the missing C# version. + +2. ### Writing the Program in the Missing Language + + Write the program in the missing language while maintaining consistency with the other versions. + Follow similar structure, naming conventions, and commenting styles. Below is an example for + adding C# to an existing C++ example: + + **Original C++ Code:** + + ```cpp + #include "splashkit.h" + + int main() + { + write_line("Hello! Welcome to the decimal to hexadecimal converter."); + + // Prompt the user for a decimal input + write_line("Please enter a decimal number:"); + + // Read the input as a string + string dec_input = read_line(); + + // Convert the input string to an unsigned integer + unsigned int dec_value = convert_to_integer(dec_input); + + // Convert the decimal value to hexadecimal format + string hex_value = dec_to_hex(dec_value); + + // Display the result in hexadecimal format + write_line("The decimal value in hexadecimal format is: " + hex_value); + + return 0; + } + ``` + + **C# Version (Top-level statements):** + + Note, for C# top-level statements, use `using static SplashKitSDK.SplashKit;`. + + ```csharp + using static SplashKitSDK.SplashKit; + + WriteLine("Hello! Welcome to the decimal to hexadecimal converter."); + + // Prompt the user for a decimal input + WriteLine("Please enter a decimal number:"); + + // Read the input as a string + string dec_input = ReadLine(); + + // Convert the input string to an unsigned integer + uint dec_value = ConvertToInteger(dec_input); + + // Convert the decimal value to hexadecimal format + string hex_value = DecToHex(dec_value); + + // Display the result in hexadecimal format + WriteLine("The decimal value in hexadecimal format is: " + hex_value); + ``` + + **C# Version (Object-Oriented Programming):** + + For the object-oriented programming (OOP) version, use `using SplashKitSDK;`. + + ```csharp + + using SplashKitSDK; + + namespace Program + { + public class Program + { + public static void Main() + { + SplashKit.WriteLine("Hello! Welcome to the decimal to hexadecimal converter."); + + // Prompt the user for a decimal input + SplashKit.WriteLine("Please enter a decimal number:"); + + // Read the input as a string + string dec_input = SplashKit.ReadLine(); + + // Convert the input string to an unsigned integer + uint dec_value = SplashKit.ConvertToInteger(dec_input); + + // Convert the decimal value to hexadecimal format + string hex_value = SplashKit.DecToHex(dec_value); + + // Display the result in hexadecimal format + SplashKit.WriteLine("The decimal value in hexadecimal format is: " + hex_value); + } + } + } + + ``` + + See how the structure and comments are consistent across all versions, with syntax changes + specific to the language. This consistency helps readers understand the program's structure and + function. If you need some help in understanding OOP and top level statements in C#, refer to the + [OOP Styling](/products/splashkit/documentation/splashkit-website/tutorials-documentation/04-oop-styling) + guide. + +3. ### Naming Files for the New Language Version + + Rename the files according to Splashkit’s conventions. Use the same naming pattern as the + existing example. + + For instance, if you add C# to a `write_line` example, you would name the two files as: + + ```plaintext + write_line-1-example-top-level.cs + write_line-1-example-oop.cs + ``` + +4. ### Adding the New Files to the Splashkit Starlight.io Repo + + Add the new files to the `usage-example` folder under the appropriate function category, + following the existing file structure: + + + +- public + - usage-example + - terminal + - write_line-1-example-top-level.cs + - write_line-1-example-oop.cs + + + +For detailed naming and placement rules, refer to [CONTRIBUTING.md] the `CONTRIBUTING.mdx` file +which can be found in the SplashKit Startlight. Repo at: + + + +- public + - usage-examples + - CONTRIBUTING.mdx + + + +### Next Steps + +After adding the files, follow the steps in +[Usage Example Pull Requests](/products/splashkit/05-pull-request-template/) to submit for review. +For peer review, refer to the +[Peer Review Guide for Usage Examples](/products/splashkit/documentation/splashkit-website/usage-examples/04-usage-peer-review). diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/images/badname.png b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/images/badname.png new file mode 100644 index 00000000..14df4344 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/images/badname.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/images/goodname.png b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/images/goodname.png new file mode 100644 index 00000000..3a8c73bb Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/images/goodname.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/images/usageexample.png b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/images/usageexample.png new file mode 100644 index 00000000..f866a1ed Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Usage Examples/images/usageexample.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/01-splashkit-website-overview.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/01-splashkit-website-overview.mdx new file mode 100644 index 00000000..1edf18a7 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/01-splashkit-website-overview.mdx @@ -0,0 +1,86 @@ +--- +title: SplashKit Website Team Overview +sidebar: + label: Overview +--- + +## **Welcome to the SplashKit Website Development Team!** + +## Introduction + +The SplashKit website is the gateway to empowering learners and developers with the tools they need +as they begin their journey in programming and game development. Having a well-designed, accessible, +and user-friendly website is important for new learners, as it ensures that resources, tutorials, +and documentation are easily accessible to everyone, regardless of their level of experience or any +accessibility challenges they may face. + +As a team, we’re focused on creating a site that reflects the inclusivity and innovation of the +SplashKit SDK, making sure everyone can get the most out of what we offer. + +--- + +## What We're Working Towards + +As part of the SplashKit Website Development Team, you’ll be helping us build, refine, and enhance +the user experience on the site. Some of the broader goals we’re working towards include: + +- **Enhancing the Onboarding Experience**: We aim to simplify the onboarding process for new users + and contributors, making it easy for them to find the resources they need. +- **Fixing and Expanding Accessibility of Tutorials**: We are always improving our tutorials and + guides, ensuring they’re up-to-date and accessible to learners. +- **Showcasing Community Contributions**: We want to highlight the incredible projects created using + SplashKit by building a dedicated showcase section. +- **Upholding Accessibility Standards**: Ensuring our site meets and exceeds accessibility standards + so that it’s usable by everyone, including those with disabilities. +- **Integrating SplashKit Online**: Integrating the SplashKit Online tool will significantly enhance + the accessibility and effectiveness of the SplashKit resources, enabling learners to preview + SplashKit functions directly within the website. + +These goals are collaborative efforts, and your contributions will help turn them into real features +that impact the SplashKit community directly. + +--- + +## What You Can Expect + +By joining the SplashKit Website Development Team, you’ll be stepping into a collaborative, +open-source environment where everyone’s contributions are valued, with your contributions being +experienced by users today. Here’s what you can expect from working with us: + +- **Collaboration and Support**: You’ll work with a team of dedicated contributors who will support + you while you learn how to contribute to an exciting tool. We believe in sharing knowledge and + improving together. +- **Learning Opportunities**: Whether you're new to web development or an experienced contributor, + you'll gain hands-on experience with modern tools like Astro, Starlight, and web frameworks. + You’ll also learn about accessibility best practices, design principles, and performance + optimisation. +- **Creative Freedom**: We encourage creative solutions and welcome new ideas. As a contributor, + you'll have the opportunity to shape the direction of the website, suggest improvements, and see + your work in action. +- **Peer Feedback and Reviews**: You’ll receive valuable feedback on your code through peer reviews, + helping you grow as a developer while maintaining the quality of the website. + +--- + +## What You’ll Gain + +As part of the team, you’ll gain practical experience working on a large-scale, open-source project, +giving you insights into web development, accessibility, and content management. Here’s what else +you can expect: + +- **Experience in Open-Source Development**: By contributing to a real-world project, you'll improve + your coding skills, learn best practices, and collaborate with others, which is a valuable + experience for your personal and professional development. +- **Portfolio Building**: Your work on the SplashKit website will be visible to the public, giving + you tangible examples to include in your portfolio or showcase in job interviews. +- **Contribution to the Community**: You’ll be making a direct impact the learning journey of + stduents (and even more experienced developers) who rely on SplashKit to build their skills and + projects. + +--- + +## Ready to Get Started? + +Check out the support documentation to get familiar with the project structure and how to best +contribute to the team. We’re excited to have you on the team, and we look forward to building +something amazing together! diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/02-web-dev-files.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/02-web-dev-files.mdx new file mode 100644 index 00000000..b6bec083 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/02-web-dev-files.mdx @@ -0,0 +1,332 @@ +--- +title: Key Website Development Files +sidebar: + label: Key Web Development Files +--- + +This document will help you understand the core files involved in the SplashKit website development +process. It provides guidance on which files to update when contributing and how to handle different +file types in peer reviews. This is not an exhaustive list, however should direct you to the key +files and file types when contributing. + +## Contents + +- [Contents](#contents) +- [Key Files to Update](#key-files-to-update) + - [`package.json` and `package-lock.json`](#packagejson-and-package-lockjson) + - [`astro.config.mjs`](#astroconfigmjs) + - [Site Metadata](#site-metadata) + - [Integrations](#integrations) + - [Customising Vite](#customising-vite) + - [Page Transitions and Animations](#page-transitions-and-animations) + - [Enabling SCSS or PostCSS](#enabling-scss-or-postcss) +- [Core Development Files](#core-development-files) + - [`.astro` Files](#astro-files) + - [`.jsx` and `.tsx` Files](#jsx-and-tsx-files) + - [`.css` Files](#css-files) + - [Example 1: Adjusting the colour palette in `custom.css`](#example-1-adjusting-the-colour-palette-in-customcss) + - [Example 2: Adding custom styles for a specific component](#example-2-adding-custom-styles-for-a-specific-component) +- [Image and Asset Management](#image-and-asset-management) + - [Asset Directories](#asset-directories) +- [`.mdx` Files](#mdx-files) +- [Peer Reviews: What to Look For](#peer-reviews-what-to-look-for) + - [`.mdx` Files](#mdx-files-1) + - [`.css` Files](#css-files-1) + - [`.jsx`/`.tsx` Files](#jsxtsx-files) + - [`.astro` Files](#astro-files-1) + +--- + +## Key Files to Update + +### `package.json` and `package-lock.json` + +- **Purpose**: `package.json` defines the project’s dependencies, metadata, and scripts, while + `package-lock.json` locks the versions of the dependencies to ensure consistency across different + environments. + +- **Installing Dependencies**: + When you run `npm install `, the new package is added to the `package.json` under the + `dependencies` or `devDependencies` section. It also updates `package-lock.json` to lock the + specific versions of the installed dependencies. + + **Example**: + + ```shell + npm install react + ``` + + This will add `react` to `package.json` under dependencies: + + ```json + { + "dependencies": { + "react": "^17.0.2" + } + } + ``` + + It will also update `package-lock.json` to include detailed version information for `react` and + any transitive dependencies to ensure consistency across environments. + +In most cases, you won’t need to manually edit `package.json` or `package-lock.json`. If you want to +remove a dependency, it’s best to use: + +```shell +npm uninstall +``` + +This will automatically remove the package from both `package.json` and `package-lock.json`. By +doing this, the project stays clean and free of unused dependencies. + +### `astro.config.mjs` + +**Purpose**: This config file defines the core settings for the Astro project, such as integrations, +site metadata, and base URLs. + +**Updates**: You may need to modify this file when adding integrations (e.g., Google Analytics) or +updating site-wide settings such as title, description, or site configuration. Below are some +specific examples: + +#### Site Metadata + +- **Why Update?**: You may want to change the global title, description, or other metadata for + search engine optimisation and branding purposes. +- **Example**: + + ```js + export default { + site: "https://example.com", + base: "/", + markdownOptions: { + rehypePlugins: [], + }, + build: { + format: "directory", + }, + }; + ``` + + Update `site` or `base` when the site’s URL changes or if you want to modify markdown handling + (affecting headings, tables, etc.). + +#### Integrations + +- **Why Update?**: If you’re adding design frameworks like TailwindCSS or optimising images through + Astro. +- **Example**: Integrating TailwindCSS for utility-first styling. + + ```js + import tailwind from "@astrojs/tailwind"; + + export default { + integrations: [tailwind()], + }; + ``` + + This allows you to quickly apply Tailwind's design utilities across your project. + +#### Customising Vite + +- **Why Update?**: When you need to customise the build pipeline to handle assets (images, fonts) + more efficiently. +- **Example**: Adjust Vite settings to optimise or transform images. + + ```js + export default { + vite: { + build: { + assetsInlineLimit: 4096, // in bytes + }, + }, + }; + ``` + + This controls when assets are inlined versus being loaded separately, which impacts performance + and design choices. + +#### Page Transitions and Animations + +- **Why Update?**: If you're adding smooth page transitions or animations between pages to improve + UX. +- **Example**: Adding an integration for animations using Astro Motion. + + ```js + import motion from "astro-motion"; + + export default { + integrations: [motion()], + }; + ``` + + This adds visual flair and smoother transitions between pages. + +#### Enabling SCSS or PostCSS + +- **Why Update?**: If you need to support SCSS for custom styling workflows. +- **Example**: Enabling SCSS in Astro. + + ```js + import { sass } from "@astrojs/sass"; + + export default { + integrations: [sass()], + }; + ``` + + This allows you to use SCSS for modular and efficient styling. + +--- + +## Core Development Files + +### `.astro` Files + +- **Purpose**: `.astro` files define the structure of pages and components. They are commonly used + for building both static and dynamic website content. + +- **What to update**: Add or modify pages in `src/pages/` or components in `src/components/`. + +- **Scenario**: You need to update the sidebar to include a new section in the website's navigation. + +- **How to update**: Modify the existing `Sidebar.astro` component to add a new navigation link + pointing to the new section. + + ```astro + + ``` + +- **Explanation**: In this example, a new `
  • ` element with the link to `/new-section` is added to + the sidebar's navigation, allowing users to navigate to the newly created page. +- **When to update**: Edit `.astro` files when changing page layouts, adding components, or + modifying the site’s structure. \*/} + +--- + +### `.jsx` and `.tsx` Files + +- **Purpose**: Handles interactivity and dynamic content through React components. + +- **What to update**: If adding or editing interactive elements like carousels, forms, or sliders, + modify these files. They’re typically located in `src/components/react/`. + +--- + +### `.css` Files + +- **Purpose**: CSS files manage the website's styles, such as layout, typography, colour palettes, + and spacing. Common styles are defined in files like `src/styles/custom.css`, which holds the + custom styles for the website. + +- **What to update**: You can modify styles in files like `custom.css` or create new + component-specific styles depending on the changes being made to the design or layout. + +#### Example 1: Adjusting the colour palette in `custom.css` + +- **Scenario**: You need to update the website’s colour scheme to match a new brand identity. +- **How to update**: Modify CSS variables in `custom.css` to reflect the new colours. + + ```css + :root { + --primary-colour: #3498db; + --secondary-colour: #2ecc71; + --accent-colour: #e74c3c; + --background-colour: #f4f4f4; + } + ``` + +#### Example 2: Adding custom styles for a specific component + +- **Scenario**: You want to add specific styles for a newly created `Button.astro` component. +- **How to update**: Add styles to `custom.css` for the `button` class or ID specific to the + component. + + ```css + .button-primary { + background-colour: var(--primary-colour); + colour: white; + padding: 10px 20px; + border-radius: 5px; + border: none; + cursor: pointer; + } + ``` + +- **When to update**: Modify CSS files when making changes to the overall design (e.g., colour + palette, typography) or when specific components need unique styles. + +--- + +## Image and Asset Management + +### Asset Directories + +- **Purpose**: The asset directories store static files such as images, gifs, and config files. + Proper organisation ensures that assets are easy to find and use in the project. + +- **Directory Structure**: + - **GIFs**: Store all general-purpose gifs in `public/gifs/`, regardless of content. However, if + the gif is used as part of a usage example (such as in a tutorial or documentation), store it in + `public/usage-examples-images-gifs/`. + - **Config Files**: Any configuration files that are generated from scripts (e.g., + `games-config.json`) should be placed directly in the `public/` folder. This ensures they are + accessible for any part of the project that needs them. + + - **Static Images**: Other static assets, such as images associated with tutorials, should be + stored in the same folder as the corresponding `.mdx` file. This keeps the related assets + organised with the content they belong to. + +- **Example**: + - A gif demonstrating a tutorial should be placed in `public/usage-examples-images-gifs/`. + - An image used in a physics tutorial stored in `src/content/docs/guides/physics/images` should + sit alongside the tutorial file in that same folder. + +--- + +## `.mdx` Files + +- **Purpose**: Markdown files with embedded components for creating content pages. + +- **What to update**: + - Add new content in `src/content/docs/`. + - Ensure correct frontmatter is used (`title`, `description`, `category`). + +--- + +## Peer Reviews: What to Look For + +When performing peer reviews, here’s what you should check for in various files: + +### `.mdx` Files + +- **Content Accuracy**: Ensure the information is correct and well-organised. +- **Frontmatter**: Check that the frontmatter is complete (e.g., `title`, `description`). +- **Component Usage**: Ensure embedded components are used properly (e.g., `LinkCard` or + `CardGrid`). + +### `.css` Files + +- **Consistency**: Ensure that styles follow the project’s styling conventions (e.g., consistent use + of variables for colours, fonts, and spacing). +- **Naming Conventions**: Ensure class names follow a consistent naming pattern. + +### `.jsx`/`.tsx` Files + +- **Functionality**: Ensure that the component works as expected. +- **Performance**: Look for unnecessary re-renders or inefficiencies in React component updates. +- **Code Style**: Ensure it follows SplashKit's linting rules. + +### `.astro` Files + +- **Structure**: Ensure the page/component is well-structured and follows best practices. +- **Reusability**: Consider whether code could be refactored into reusable components. + +--- diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/03-css-styling-guide.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/03-css-styling-guide.mdx new file mode 100644 index 00000000..ab9c1df2 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/03-css-styling-guide.mdx @@ -0,0 +1,263 @@ +--- +title: SplashKit Styling Guide +sidebar: + label: CSS Styling Guide +--- + +This document outlines the core styling principles for the SplashKit website to ensure consistency, +accessibility, and a cohesive design. + +## Contents + +- [Contents](#contents) +- [Colour Palette](#colour-palette) + - [Tools for Colour Palette Generation](#tools-for-colour-palette-generation) +- [Accessibility Considerations](#accessibility-considerations) + - [1. **WCAG 2.1 AA Compliance**](#1-wcag-21-aa-compliance) + - [2. **Disabling Animations and Smooth Transitions**](#2-disabling-animations-and-smooth-transitions) + - [3. **Hover Effects and Visual Cues**](#3-hover-effects-and-visual-cues) + - [4. **Colour Blindness Accessibility**](#4-colour-blindness-accessibility) +- [Typography](#typography) + - [Font](#font) + - [Font Sizes](#font-sizes) +- [Component Styling](#component-styling) + - [Buttons](#buttons) +- [Image and Asset Management](#image-and-asset-management) +- [Color Theme Editor](#color-theme-editor) + - [How to Use](#how-to-use) +- [Current Styling Values](#current-styling-values) +- [Useful Tools](#useful-tools) +- [Links](#links) + +--- + +## Colour Palette + +- **Primary Colours**: SplashKit uses a consistent colour palette to maintain a clean, cohesive + design. You are encouraged to use accessible, high-contrast colours that support both branding and + readability. + +### Tools for Colour Palette Generation + +- **Coolors.co**: Use [Coolors.co](https://coolors.co/) to generate and experiment with colour + palettes. This platform supports multiple colour spaces and includes contrast checkers, ensuring + your colour selections meet accessibility standards. + + **Example**: + + ```css + :root { + --primary-colour: ; + --secondary-colour: ; + --accent-colour: ; + --background-colour: ; + } + ``` + +- Adjust these values according to the design requirements, ensuring they meet accessibility + standards like **WCAG 2.1 AA**. + +--- + +## Accessibility Considerations + +Accessibility is a key concern, and we need to ensure that our design is inclusive and easy to +navigate for all users, including those with visual impairments. + +### 1. **WCAG 2.1 AA Compliance** + +- When designing for accessibility, ensure that colour contrast meets the **Web Content + Accessibility Guidelines (WCAG) 2.1 AA** standards. These include: + - A contrast ratio of at least **4.5:1** between text and background for normal text. + - A contrast ratio of at least **3:1** for larger text (18pt and above). +- Use tools like the **Color Theme Editor**, **Coolors.co contrast checker**, and the **Pilestone + Color Blindness Simulator** to verify your designs are accessible for all users. + +### 2. **Disabling Animations and Smooth Transitions** + +- Users should have the option to disable animations and transitions to avoid distracting or + overwhelming effects. + + **CSS Example**: + + ```css + @media (prefers-reduced-motion: reduce) { + * { + animation: none !important; + transition: none !important; + } + } + ``` + + To learn more about this feature, visit the + [@media (prefers-reduced-motion) documentation](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion). + +### 3. **Hover Effects and Visual Cues** + +- Ensure that elements that change on hover, such as buttons or links, are clearly identifiable as + interactive elements. A subtle colour change on hover is a good way to indicate that the element + is clickable. + + **Example**: + + ```css + a { + color: var(--primary-colour); + } + + a:hover { + color: var(--accent-colour); + } + ``` + +### 4. **Colour Blindness Accessibility** + +- Use tools like the + [Pilestone Color Blindness Simulator](https://pilestone.com/pages/color-blindness-simulator-1) to + test how different users experience colours. This tool is particularly useful for ensuring that + users with various forms of colour blindness can comfortably navigate the site. + + Ensure that contrast ratios are sufficient to make text legible for all users, particularly those + with colour vision deficiencies. + +--- + +## Typography + +### Font + +Use a modern, readable font to maintain consistency across the website. + +- Default fonts like `Arial`, `Roboto`, or `Gaegu` can be used for headers and body text. +- Follow the existing import patterns for fonts: + + ```css + @import url("https://use.typekit.net/vzr3ole.css"); + @import url("https://fonts.googleapis.com/css?family=Gaegu&display=swap"); + ``` + +### Font Sizes + +- Headings: Use larger font sizes for hierarchy and structure. +- Body text: Minimum 16px for readability. +- Example: + + ```css + h1 { + font-size: 2.5rem; + font-weight: bold; + } + + p { + font-size: 1rem; + } + ``` + +If needed, you can adjust these values in `custom.css` to fit specific design elements. + +--- + +## Component Styling + +### Buttons + +Buttons should use consistent styles across the website to ensure a cohesive look. + +- **Primary Button**: **Example**: + + ```css + .button-primary { + background-colour: var(--primary-colour); + colour: white; + padding: 10px 20px; + border-radius: 5px; + cursor: pointer; + border: none; + } + + .button-primary:hover { + background-colour: var(--accent-colour); + } + ``` + +If you're contributing, please review the existing styles in `custom.css` for similar elements and +ensure your additions follow the same structure. + +--- + +## Image and Asset Management + +- **GIFs**: General-purpose gifs should be stored in `public/gifs/`. If a gif is used in a usage + example (tutorials, documentation), store it in `public/usage-examples-images-gifs/`. +- **Static Images**: Images associated with tutorials or content should be stored alongside the + `.mdx` files they relate to. +- **Config Files**: Any configuration files generated from scripts (e.g., `games-config.json`) + should be placed in the `public/` folder for easy access. + +--- + +## Color Theme Editor + +The +[Starlight Color Theme Editor](https://starlight.astro.build/guides/css-and-tailwind/#:~:text=items%20in%20navigation.-,Color%20theme%20editor,-Use%20the%20sliders) +is an excellent tool for previewing and adjusting colour values for various design elements across +the website. It allows you to tweak background, text, and accent colours in real-time, providing +instant feedback on how those changes will affect the overall design. + +### How to Use + +- Use the sliders in the editor to adjust different colour variables, which are immediately + reflected in the preview. +- Once you're satisfied with your selections, you can copy the colour values and apply them to the + `custom.css` or directly into your `.astro` components. +- This tool is particularly helpful when used in conjunction with **Coolors.co** for creating + palettes or the **Pilestone Color Blindness Simulator** to ensure accessibility. + +--- + +## Current Styling Values + +Here are the current values being used in the `custom.css` file for the SplashKit website: + +```css +@import url("https://use.typekit.net/vzr3ole.css"); +@import url("https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css"); +@import url("https://fonts.googleapis.com/css?family=Gaegu&display=swap"); + +/* Dark mode colours. */ +:root { + --purple-hsl: 255, 60%, 60%; + --overlay-blurple: hsla(var(--purple-hsl), 0.2); +} + +/* Light mode colours. */ +:root[data-theme="light"] { + --purple-hsl: 255, 85%, 65%; + --sl-hue-accent: 350; + --sl-color-accent: #3d50f5; +} +``` + +Please review these values when making any changes to ensure consistency. + +--- + +## Useful Tools + +- **Coolors.co**: Use this platform to experiment with colour palettes and ensure your choices are + accessible. +- **Pilestone Color Blindness Simulator**: Test colour choices for accessibility to users with + colour vision deficiencies. +- **WCAG 2.1 AA Standards**: Use these standards as the baseline to ensure that the site is + accessible to all users, particularly with respect to contrast ratios between text and background. + +--- + +## Links + +Here are some helpful resources for styling and accessibility: + +- [Coolors.co Contrast Checker](https://coolors.co/contrast-checker) +- [Pilestone Color Blindness Simulator](https://pilestone.com/pages/color-blindness-simulator-1) +- [@media (prefers-reduced-motion) Documentation](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion) +- [WCAG 2.1 AA Guidelines](https://www.w3.org/WAI/WCAG21/quickref/) diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/04-search-guide.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/04-search-guide.mdx new file mode 100644 index 00000000..83a4bbd6 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/04-search-guide.mdx @@ -0,0 +1,192 @@ +--- +title: Algolia DocSearch +sidebar: + label: Algolia DocSearch +--- + +import { Tabs, TabItem, Steps, Aside } from "@astrojs/starlight/components"; + +Algolia DocSearch is a search engine designed to automatically extract content from Open Source +documentations, allowing it to have an instant search on tech websites. + +## Why DocSearch + +- It is free and was designed especially for open source projects and technical + documentations/blogs. +- It already has built-in support for Astro Starlight. +- It is built on Algolia Autocomplete, providing better accessiblity and customizability. +- It offers new features to better the user experience such as search history log, a favorite + system, and support for Google Analytics Integration. + +### How to Get Started + +Registration can be done via the [DocSearch Site](https://docsearch.algolia.com/apply) where you'll +need to enter your website URL and email. _(This process could take a few days for approval.)_ Once +approved, you will recieve an email to accept their invitation to get started, where you'll be taken +to the Algolia Dashboard. Further configuration can be made via this Dashboard. + + + +### Astro Starlight Integration + + + +1. Install `@astrojs/starlight-docsearch`: + + + + + + ```sh + npm install @astrojs/starlight-docsearch + ``` + + + + + + ```sh + pnpm add @astrojs/starlight-docsearch + ``` + + + + + + ```sh + yarn add @astrojs/starlight-docsearch + ``` + + + + + +2. Add DocSearch APIs to the Astro Starlight `plugins` config via `astro.config.mjs`: + + ```js + // astro.config.mjs + import { defineConfig, squooshImageService } from "astro/config"; + import starlight from "@astrojs/starlight"; + import starlightLinksValidator from "starlight-links-validator"; + + export default defineConfig({ + site: "https://splashkit.io/", + integrations: [ + starlight({ + title: "SplashKit", + description: + "SplashKit is a cross-platform game engine for C, C++ and Objective-C. It provides a simple API for 2D game development.", + plugins: [ + starlightLinksValidator({ + errorOnRelativeLinks: true, + }), + starlightDocSearch({ + appId: "DOCSEARCH_API_ID", + apiKey: "DOCSEARCH_API_KEY", + indexName: "DOCSEARCH_INDEX_NAME", + }), + ], + }), + ], + }); + ``` + +3. **Optional** Further​ configuration can be done by following guides on the + + Starlight Documentation + + . + + + +## Custom Ranking + +This following section provides a step-by-step guide to updating the custom ranking system to +prioritize categories during search operations. + +### Steps + + + +1. Start off by heading over to the + + Algolia Dashboard + + . +2. Click on the **Go To Crawler** button and select the crawler you want to adjust. +3. Once in the crawler, go to the **Editor** via the sidebar. +4. Add DocSearch APIs to the Astro Starlight `plugins` config via `astro.config.mjs`: + + ```js + actions: [ + { + indexName: "sksearchtest", + pathsToMatch: ["https://sksearchtest.netlify.app/**"], + recordExtractor: ({ $, helpers }) => { + const lvl0 = + $('details:has(a[aria-current="page"])').find("summary").find("span").first().text() || + "Documentation"; + + return helpers.docsearch({ + recordProps: { + lvl0: { + selectors: "", + defaultValue: lvl0, + }, + lvl1: "main h1", + lvl2: "main h2", + lvl3: "main h3", + lvl4: "main h4", + lvl5: "main h5", + lvl6: "main h6", + content: "main p, main li", + apiBoost: lvl0 === "Developer Documentation" ? 10 : 1, + usageBoost: lvl0 === "Usage Examples" ? 5 : 1, + }, + indexHeadings: true, + aggregateContent: true, + }); + }, + }, + ]; + ``` + +5. Inside the `recordProps`, you'll notice two variables: `apiBoost` and `usageBoost`. _These + variable names can be customized to suit your needs_. +6. The values assigned to these variables represent the boost level. The higher the number, the + stronger the boost. +7. To change which category receives a boost, simply adjust the name that the condition checks. For + example, you can modify `"Developer Documentation"` to check for a different category name, such + as `"Installation"` or `"Tutorials and Guides"`. +8. Once completed, navigate to the **Indices** tab viable the sidebar and select the index you're + working on. +9. In the Index page, head to the **Configuration** tab in the top navigation bar and select + **Ranking and Sorting**: ![Custom Ranking](./images/search-custom-ranking.PNG) + +10. As seen in the image above, place the variables defined in the Editor earlier by clickin the **+ + Add custom ranking attribute** button. The order of priority should follow a top-to-bottom + sequence, with the top-most being the highest priority. _Note: It is not recommended to place + these variables above the preset textual ranking, as the preset rankings serve as the core + foundation of the search engine’s ranking system._ + + diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/05-peer-review-web.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/05-peer-review-web.mdx new file mode 100644 index 00000000..363f63e9 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/05-peer-review-web.mdx @@ -0,0 +1,154 @@ +--- +title: Peer Review Guide +sidebar: + label: "- Peer Review Guide for Web Dev" +--- + +import { Aside } from "@astrojs/starlight/components"; + +## Introduction on how to do a peer review within the SplashKit Web Dev Team + + + +In SplashKit, peer reviews are a vital process to ensure code quality, maintainability, and +consistency across the website development project. Every pull request (PR) must follow the +Peer-Review Checklist, which checks for key factors like functionality, code readability, and +documentation. + +Additionally, the Peer-Review Prompts serve as a conversation starter for reviewers, encouraging +collaboration while allowing for a thorough and constructive review process. + + + +### SplashKit Peer-Review Checklist + +The following checklist is required to be completed for every review to ensure high-quality +contributions. + +```plaintext +## General Information + +- [ ] Type of Change: Clearly indicate the type of change (choose one): + - [ ] Bug fix + - [ ] New feature + - [ ] Breaking change + - [ ] Documentation update + +## Code Quality + +- [ ] Repository: Ensure the PR is made to the correct repository. +- [ ] Readability: Is the code easy to read and follow? Are comments included where necessary? +- [ ] Maintainability: Can this code be maintained or extended easily in the future? + +## Functionality + +- [ ] Correctness: Does the code meet the task requirements? +- [ ] Existing Functionality: Has the impact on existing functionality been considered and tested? + +## Testing + +- [ ] Test Coverage: Are unit tests provided for new or modified code? +- [ ] Test Results: Have all tests passed successfully? + +## Documentation + +- [ ] Documentation: Is the inline and external documentation updated and clear? + +## Pull Request Details + +- [ ] PR Description: Is the problem being solved clearly described? +- [ ] Checklist Completion: Have all relevant checklist items been reviewed and completed? +``` + +### SplashKit Peer-Review Prompts + +These prompts can help guide discussions during the review process and ensure that the code meets +high standards. + +- **Type of Change**: Is the PR correctly identifying the type of change (bug fix, new feature, + etc.)? +- **Code Readability**: Is the code well-structured and easy to follow? Could better comments, + names, or organisation improve it? +- **Maintainability**: Is the code modular and easy to maintain? Does it introduce any technical + debt? +- **Code Simplicity**: Are there redundant or overly complex parts of the code that could be + simplified? +- **Edge Cases**: Does the code account for edge cases? What scenarios might cause it to break? +- **Test Thoroughness**: Does the testing cover all edge cases and failure paths? Are there enough + tests to ensure code reliability? +- **Backward Compatibility**: Does the change break any existing functionality? If so, is backward + compatibility handled or documented? +- **Performance Considerations**: Could this code impact performance negatively? Can it be optimised + while maintaining readability? +- **Security Concerns**: Does this change introduce any security risks? Is input validation handled + properly? +- **Dependencies**: Are new dependencies necessary? Could they conflict with existing libraries? + Could this functionality be achieved without new dependencies? +- **Documentation**: Is the documentation clear and thorough enough for new developers to + understand? Does it cover API or external interface changes? + +--- + +## Review Guidelines for Specific File Types + +Different file types require different levels of attention during the review process. Here's what to +look for when reviewing each type of file: + +### `.mdx` Files + +- **Content Accuracy**: Ensure that the content is clear and accurate. Double-check for any errors + in the documentation or guides. +- **Frontmatter**: Ensure the frontmatter (`title`, `description`, etc.) is correctly filled out. +- **Component Usage**: Verify that components such as `LinkCard`, `CardGrid`, or others are being + used appropriately within the `.mdx` files. + +### `.css` Files + +- **Consistency**: Check that the styles align with the **Styling Guide** and maintain a consistent + use of variables (e.g., colours, fonts, spacing). +- **Accessibility**: Review for accessibility considerations, such as whether animations are + disabled for users who prefer reduced motion, and whether contrast ratios meet **WCAG 2.1 AA** + standards. +- **Naming Conventions**: Ensure that CSS class names follow a consistent naming pattern. + +### `.jsx`/`.tsx` Files + +- **Functionality**: Make sure the interactive components (e.g., sliders, forms) work as expected + and meet the requirements of the task. +- **Performance**: Look for unnecessary re-renders or other performance concerns. +- **Code Style**: Ensure the code follows **React/JSX** best practices and any project-specific + linting rules. + +### `.astro` Files + +- **Structure**: Ensure the page or component is well-structured and follows the **Astro standards** + for component and page creation. +- **Reusability**: Look for opportunities to refactor repetitive code into reusable components. + +--- + +## Useful Resources for Reviewers + +- **Starlight Documentation**: [Starlight Docs](https://starlight.astro.build/getting-started/) +- **Astro Documentation**: [Astro Docs](https://docs.astro.build/en/getting-started/) +- **WCAG 2.1 AA Guidelines**: [W3C Accessibility Standards](https://www.w3.org/WAI/WCAG21/quickref/) +- **MDN CSS Documentation**: [MDN CSS Guide](https://developer.mozilla.org/en-US/docs/Web/CSS) +- **React Documentation**: [React Official Docs](https://reactjs.org/docs/getting-started.html) + +--- + +By following these guidelines, you'll ensure that the SplashKit website project maintains high +standards of code quality, performance, and accessibility. Remember, peer reviews are not only about +verifying the code but also about learning and improving together as a team. diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/games-showcase-template.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/games-showcase-template.mdx new file mode 100644 index 00000000..9380173b --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/games-showcase-template.mdx @@ -0,0 +1,81 @@ +--- +title: Games Showcase Template +description: Game Description +download-link: "" +featured: false +sidebar: + hidden: true +--- + +{/* Embedding dynamic JavaScript directly in MDX to generate game gif - do not alter */} +{/* gif files are to go in the /public/gifs/games-showcase folder with the naming convention game-title-showcase.gif */} + +{`${frontmatter.title} + +## Description + +_Game Description_ + +## Installation + +_Installation instructions_ + +{/* Delete this tip from the final games showcase file */} + +:::tip + +An example may look like this: + +```markdown +1. Download the game files. +2. Navigate to the folder. +3. Execute `dotnet run` through the MSYS2 terminal. +``` + +::: + +{/* Download button automatically derived from correct frontmatter - do not alter */} + +
    + +
    + +## Gameplay + +_Briefly describe the gameplay of the game. Include any controls._ + +{/* Delete this tip from the final games showcase file */} :::tip An example may look like this: + +```markdown +| Action | Player 1 | +| ---------- | -------- | +| Move Up | W | +| Move Down | S | +| Move Left | A | +| Move Right | D | +| Shoot | Space | +``` + +::: + +## Developers + +- [Developer Name](developer github) + +Last updated: _last updated date for the game_ + +{/* Return button automatically generated - do not alter */} + +
    + +
    diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/games-showcase.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/games-showcase.mdx new file mode 100644 index 00000000..4e20e3ac --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/games-showcase.mdx @@ -0,0 +1,133 @@ +--- +title: Adding to the Games Showcase +description: Guide for adding to the Games Showcase on SplashKit.io +--- + +## Games Showcase Template + +The +[Games Showcase Template](https://github.com/thoth-tech/ThothTech-Documentation-Website/blob/main/src/content/docs/Products/SplashKit/Splashkit%20Website/Website%20Documentation/games-showcase-template.mdx) +is to be used when adding a game to the Games Showcase on the SplashKit.io website. This will be +included in the /src/content/docs/games folder of the SplashKit.io folder. + +#### Frontmatter + +```md +--- +title: +description: +download-link: "" +featured: true +sidebar: + hidden: false +--- +``` + +- **title**: Game Title +- **description**: Short description of game here. Keep this short as it will generate the thumbnail + in the index page. +- **download-link**: The link to the download-directory.github.io tool to download the github + repository that holds the game. Simply copy the link to the game parent game folder and add it to + the end of `https://download-directory.github.io?url=`. The download-link needs to be encapsulated + in double quotes`""`. +- **featured**: This flag is to determine if the game is shown on the Games Index page. The Games + Index page will automatically populate based on the frontmatter. +- **sidebar**: Set the hidden flag to determine if the game will show up on the sidebar. + +#### Game Gif + +This will be automatically generated when the gif file is placed into the +/public/gifs/games-showcase folder with the naming convention game-title-showcase.gif. Do not adjust +this. + +#### Description + +Add a description of the game. + +#### Installation + +Include installation instructions that are language specific. + +```markdown +1. Download the game files. +2. Navigate to the folder. +3. Execute `dotnet run` through the MSYS2 terminal. +``` + +The Download button is automatically derived from the frontmatter - do not alter this + +```html +
    + +
    +``` + +#### Gameplay + +Briefly describe the gameplay of the game. Include any controls. + +{/* Delete this tip from the final games showcase file */} + +```markdown +| Action | Player 1 | +| ---------- | -------- | +| Move Up | W | +| Move Down | S | +| Move Left | A | +| Move Right | D | +| Shoot | Space | +``` + +#### Developers + +Include the link to the github(s) of the developer(s). + +```markdown +[thoth-tech](https://github.com/thoth-tech) +``` + +Include the date that the game was last updated. + +```markdown +Last updated: +``` + +A Back to Games Index button will be automatically generated - do not alter this code. + +```html +
    + +
    +``` + +## Adding Games to the Home Page Swiper + +To add a game to the front page swiper, you will need to make sure that frontmatter in the `.mdx` +file of your game is correct. + +``` +title: The name of your game +description: The description of your game +featured: This boolean will determine if is featured on the game swiper or not +``` + +A `games-config.json` file is generated by a script (feature-games.cjs), which scans the +src/content/docs/games directory, reads the frontmatter from each .mdx file, and writes the relevant +data to the JSON file. + +This JSON is saved to src/components/react/GameCardSwiper/games-config.json. + +The Astro project runs this script automatically during development (npm run dev) and build (npm run +build). This ensures that the games-config.json file is always up to date without manual +intervention. + +In the React Swiper component, the project dynamically fetches the games-config.json file at +runtime. + +The data from games-config.json is then used to display featured games within the Swiper carousel on +the main page. It filters the games based on whether they are marked as featured, sorts them by +name, and renders them dynamically. diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/images/heading-bug.png b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/images/heading-bug.png new file mode 100644 index 00000000..2397a7db Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/images/heading-bug.png differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/images/search-custom-ranking.PNG b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/images/search-custom-ranking.PNG new file mode 100644 index 00000000..1bb9d280 Binary files /dev/null and b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/Website Documentation/images/search-custom-ranking.PNG differ diff --git a/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/index.mdx b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/index.mdx new file mode 100644 index 00000000..395d8642 --- /dev/null +++ b/src/content/docs/Products/SplashKit/Documentation/Splashkit Website/index.mdx @@ -0,0 +1,129 @@ +--- +title: SplashKit Website +description: Overview of the Splashkit.io website team. +sidebar: + label: Overview + order: 10 +--- + +import { Card, LinkCard, CardGrid, Icon } from "@astrojs/starlight/components"; + +## The SplashKit.io Website Team + +The SplashKit Website Team manages all aspects of the SplashKit.io website. This includes overseeing +the site’s design, maintaining up-to-date tutorials and usage examples, and ensuring that all +content is accurate, relevant, and user-friendly. + +The team’s responsibilities include: + +- Ensuring consistent styling and branding across the site +- Keeping tutorials, guides, and usage examples current +- Optimising the site’s usability and accessibility for a smooth user experience + +In addition to maintenance, the team actively develops new content to expand the site’s resources, +aiming to make SplashKit.io a comprehensive and helpful platform for users. + +## Onboarding Information + + + + + + + + + + +## Website Development Information + + + + + + + +## Usage Examples Information + + + + + + + + +## Tutorials Information + + + + + + + diff --git a/src/content/docs/Products/SplashKit/images/FormatOnSave.png b/src/content/docs/Products/SplashKit/images/FormatOnSave.png new file mode 100644 index 00000000..35040786 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/FormatOnSave.png differ diff --git a/src/content/docs/Products/SplashKit/images/addbranch-gitdesk.png b/src/content/docs/Products/SplashKit/images/addbranch-gitdesk.png new file mode 100644 index 00000000..92398bb3 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/addbranch-gitdesk.png differ diff --git a/src/content/docs/Products/SplashKit/images/addbranch-vscode.png b/src/content/docs/Products/SplashKit/images/addbranch-vscode.png new file mode 100644 index 00000000..0ed48974 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/addbranch-vscode.png differ diff --git a/src/content/docs/Products/SplashKit/images/clonegitdesk.png b/src/content/docs/Products/SplashKit/images/clonegitdesk.png new file mode 100644 index 00000000..ceb9ca7f Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/clonegitdesk.png differ diff --git a/src/content/docs/Products/SplashKit/images/cloneurlgitdesk.png b/src/content/docs/Products/SplashKit/images/cloneurlgitdesk.png new file mode 100644 index 00000000..1728c654 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/cloneurlgitdesk.png differ diff --git a/src/content/docs/Products/SplashKit/images/cloningrepo.png b/src/content/docs/Products/SplashKit/images/cloningrepo.png new file mode 100644 index 00000000..41bff88f Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/cloningrepo.png differ diff --git a/src/content/docs/Products/SplashKit/images/defaultprofile.png b/src/content/docs/Products/SplashKit/images/defaultprofile.png new file mode 100644 index 00000000..60cc4243 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/defaultprofile.png differ diff --git a/src/content/docs/Products/SplashKit/images/dropdown.png b/src/content/docs/Products/SplashKit/images/dropdown.png new file mode 100644 index 00000000..601a2618 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/dropdown.png differ diff --git a/src/content/docs/Products/SplashKit/images/gitclone.gif b/src/content/docs/Products/SplashKit/images/gitclone.gif new file mode 100644 index 00000000..cb484ecd Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/gitclone.gif differ diff --git a/src/content/docs/Products/SplashKit/images/namebranch-gitdesk.png b/src/content/docs/Products/SplashKit/images/namebranch-gitdesk.png new file mode 100644 index 00000000..44abf01f Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/namebranch-gitdesk.png differ diff --git a/src/content/docs/Products/SplashKit/images/namebranch-vscode.png b/src/content/docs/Products/SplashKit/images/namebranch-vscode.png new file mode 100644 index 00000000..6473b263 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/namebranch-vscode.png differ diff --git a/src/content/docs/Products/SplashKit/images/newbranch-vscode.png b/src/content/docs/Products/SplashKit/images/newbranch-vscode.png new file mode 100644 index 00000000..853b7fcd Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/newbranch-vscode.png differ diff --git a/src/content/docs/Products/SplashKit/images/newterminal.png b/src/content/docs/Products/SplashKit/images/newterminal.png new file mode 100644 index 00000000..49169f58 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/newterminal.png differ diff --git a/src/content/docs/Products/SplashKit/images/openrepo.png b/src/content/docs/Products/SplashKit/images/openrepo.png new file mode 100644 index 00000000..cc4c62b4 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/openrepo.png differ diff --git a/src/content/docs/Products/SplashKit/images/prinvscode.gif b/src/content/docs/Products/SplashKit/images/prinvscode.gif new file mode 100644 index 00000000..acbd3f03 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/prinvscode.gif differ diff --git a/src/content/docs/Products/SplashKit/images/publishbranch-gitdesk.png b/src/content/docs/Products/SplashKit/images/publishbranch-gitdesk.png new file mode 100644 index 00000000..4cebaa64 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/publishbranch-gitdesk.png differ diff --git a/src/content/docs/Products/SplashKit/images/publishbranch-vscode.png b/src/content/docs/Products/SplashKit/images/publishbranch-vscode.png new file mode 100644 index 00000000..d0123175 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/publishbranch-vscode.png differ diff --git a/src/content/docs/Products/SplashKit/images/pull-request-fig1.png b/src/content/docs/Products/SplashKit/images/pull-request-fig1.png new file mode 100644 index 00000000..6fddb32b Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/pull-request-fig1.png differ diff --git a/src/content/docs/Products/SplashKit/images/pull-request-fig2.png b/src/content/docs/Products/SplashKit/images/pull-request-fig2.png new file mode 100644 index 00000000..a1a77163 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/pull-request-fig2.png differ diff --git a/src/content/docs/Products/SplashKit/images/pull-request-fig3.png b/src/content/docs/Products/SplashKit/images/pull-request-fig3.png new file mode 100644 index 00000000..66593b54 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/pull-request-fig3.png differ diff --git a/src/content/docs/Products/SplashKit/images/pull-request-fig4.png b/src/content/docs/Products/SplashKit/images/pull-request-fig4.png new file mode 100644 index 00000000..a5cc2c33 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/pull-request-fig4.png differ diff --git a/src/content/docs/Products/SplashKit/images/selectterminal.png b/src/content/docs/Products/SplashKit/images/selectterminal.png new file mode 100644 index 00000000..1a0634e0 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/selectterminal.png differ diff --git a/src/content/docs/Products/SplashKit/images/splashkitfork.png b/src/content/docs/Products/SplashKit/images/splashkitfork.png new file mode 100644 index 00000000..b8a8a41b Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/splashkitfork.png differ diff --git a/src/content/docs/Products/SplashKit/images/starlightrepo.png b/src/content/docs/Products/SplashKit/images/starlightrepo.png new file mode 100644 index 00000000..5b0a1f62 Binary files /dev/null and b/src/content/docs/Products/SplashKit/images/starlightrepo.png differ diff --git a/src/content/docs/Products/SplashKit/index.mdx b/src/content/docs/Products/SplashKit/index.mdx new file mode 100644 index 00000000..d5572437 --- /dev/null +++ b/src/content/docs/Products/SplashKit/index.mdx @@ -0,0 +1,269 @@ +--- +title: SplashKit +description: The landing page for SplashKit. +sidebar: + order: 0 + label: Overview +tableOfContents: + maxHeadingLevel: 4 +--- + +import { Card, LinkCard, CardGrid, Icon, Aside } from "@astrojs/starlight/components"; + +Welcome to SplashKit! Further resources detailing how to work on SplashKit are provided per-project +in the sidebar to the left. + + + +## SplashKit Overview + +As a new contributor to SplashKit, you’ll be working on a versatile and beginner-friendly software +development toolkit focused on simplifying 2D game development and interactive applications. +SplashKit already supports cross-platform development for Windows, macOS, and Linux, allowing +developers to use a single codebase for multiple platforms. + +This document aims to provide a brief overview of the SplashKit ecosystem and highlight the core +areas where you’ll contribute to SplashKit’s growth. The focus of future growth will be on extending +its functionality, improving existing features, and supporting the developer community through +improved tutorials and documentation. + +### SplashKit Documentation + +#### SplashKit.io + + + + + + + + + +SplashKit.io is the primary public-facing website for the SplashKit community. It contains guides, +tutorials, and comprehensive API documentation. This platform is designed to help users, especially +beginners, learn how to use SplashKit effectively in their projects. As a contributor, your +responsibilities might include writing new guides, updating existing tutorials, and ensuring the API +documentation is clear and up-to-date. + +#### Thoth-Tech Documentation Website + + + + + + + + + +The Thoth-Tech Documentation Website is an internal platform focused on providing detailed +explanations of features and guides targeted at the Thoth-Tech team. It serves as a valuable +resource for team members to reference when contributing to SplashKit or collaborating on projects. +Contributors may need to update or write internal-facing documentation, particularly as new features +or internal tools are developed. + +#### Documentation + + + + + + + + +The documentation repository is a 'miscellaneous' collection where all documents that do not fit +into other repositories are stored. This might include research reports, documentation on incomplete +or experimental features, or other internal records. Contributors might add new documentation here +or help organize and maintain existing records to ensure they are accessible and up-to-date. + +### SplashKit Development + +#### SplashKit Core + + + + + + + + +Contributing to SplashKit Core means working directly on the foundation of the SDK. This involves +core functionalities like rendering, audio management, input handling, and more. As a team member, +you’ll focus on adding new features, fixing bugs, and ensuring the overall performance of the SDK +remains high. + +While the core is primarily built in C++, you’ll be contributing to a codebase that supports +translation into other languages like C#, Python, and Pascal. Although the translation process is +largely automated, maintaining the quality and performance of the core features will be your main +responsibility. Cross-platform development is central to SplashKit, so you'll be handling different +OS nuances as you work on features that need to run smoothly on Windows, macOS, and Linux. + +#### SplashKit Manager (SKM) + + + + + + + +The SplashKit Manager (SKM) is a command-line interface (CLI) and application tool designed to +simplify the development workflow with SplashKit. It automates tasks such as project setup, +dependency management, compilation, and running code across different platforms. Contributions to +SKM will primary be to ensure it stays aligned with updates and new features in SplashKit Core. For +example, you’ll ensure that new dependencies or libraries introduced in the core SDK are correctly +included and managed across all supported platforms. + +Beyond core synchronisation, there may also be opportunities to improve the overall user experience +by streamlining project initialization, refining dependency management, or adding tools that make +the workflow more efficient for developers. However, your primary focus will be ensuring SKM +seamlessly integrates with the evolving features and requirements of the core SplashKit SDK. + +#### SplashKit Translator + + + + + + + +The SplashKit Translator automates the process of translating SplashKit’s core C++ functionality +into other supported languages like C#, Python, and Pascal. Since this process is largely automated +using ERB templating, there’s minimal need for direct contributions here. + +Your focus will remain on maintaining and enhancing the core SDK, as changes there will naturally +propagate through the automated translation process. Ensuring that core features are implemented +cleanly and efficiently in C++ will help maintain consistency across languages. + +#### SplashKit Online + + + + + + + +SplashKit Online is a web-based IDE designed to help beginner programmers quickly start building 2D +games directly in the browser. While it currently supports JavaScript (with experimental C++ +functionality) and leverages WebAssembly (Wasm) to execute SplashKit code, the goal is to expand +this support to include all languages that SplashKit supports: C#, Python, and Pascal. + +As a contributor to SplashKit Online, your primary responsibility will be developing and integrating +full support for these languages, allowing users to write and run code in C#, Python, and Pascal +seamlessly within the browser-based environment. This will involve extending the IDE's functionality +to handle language-specific nuances and ensuring that WebAssembly can execute code from these +languages efficiently. + +Your work will also include improving the user experience, making the platform more intuitive and +accessible for users, and ensuring that the transition between languages is smooth. This could +involve building better language selection interfaces, optimizing performance for different +languages, and adding language-specific tools or debugging features. + +#### Arcade Machines + + + + + + + + +The Arcade Machines on Deakin Campuses use emulationstation, retropie, and a custom SplashKit +application to run games built using the SplashKit SDK. These machines offer students the +opportunity to upload their games and test them in a real-world arcade environment. The machines are +designed to help students see their creations in action on physical hardware, making for a hands-on +experience that bridges the gap between development and arcade-style game deployment. + +#### Game Development + + + + + + + + +The Game Development team is a small, focused group that produces games designed to highlight the +capabilities of SplashKit. These games follow industry-standard design patterns and practices to +ensure they are polished and well-structured. The goal is to showcase what can be achieved using +SplashKit while maintaining professional standards in game design and development. These projects +serve as both a demonstration of SplashKit’s features and an inspiration for developers using the +SDK to build their own games. diff --git a/src/content/docs/Products/index.mdx b/src/content/docs/Products/index.mdx new file mode 100644 index 00000000..287ac94d --- /dev/null +++ b/src/content/docs/Products/index.mdx @@ -0,0 +1,32 @@ +--- +title: Check out our products! +description: Thoth Tech's latest and greatest +sidebar: + label: Overview + order: 0 +--- + +import { LinkCard } from "@astrojs/starlight/components"; + +
    + + SplashKit logo +
    + +
    + + OnTrack Logo +
    diff --git a/src/content/docs/Resources/Onboarding Hub/ontrack.mdx b/src/content/docs/Resources/Onboarding Hub/ontrack.mdx new file mode 100644 index 00000000..917a2122 --- /dev/null +++ b/src/content/docs/Resources/Onboarding Hub/ontrack.mdx @@ -0,0 +1,97 @@ +--- +title: OnTrack Onboarding Hub +setup: | + import { Steps, LinkCard, CardGrid } from "@astrojs/starlight/components"; +--- + +import { Steps, LinkCard, CardGrid } from "@astrojs/starlight/components"; + +## Contributing to OnTrack + +Contributing to OnTrack is a great way to enhance a student-focused learning and feedback platform +while gaining experience in development workflows. Whether you’re interested in adding new features, +fixing bugs, improving documentation, or optimizing user experience, we welcome all contributions! + +### Trimester Workflow + +
      + +1. **Explore OnTrack**: Begin by exploring the various OnTrack resources on this website. See below + for links. Familiarize yourself with the structure and functionality of each project and its + repositories and contribution guides. +2. **Choose Tasks**: Work with the team or your mentor to identify tasks you can complete. These may + range from feature development and bug fixes to documentation improvements. +3. **Fork the Repository**: When contributing, be sure to fork from the Thoth-Tech repo. This + ensures changes are first reviewed and integrated internally before being merged into the main + project. +4. **Follow the Contribution Guide**: If a repository has its own contribution guide, usually in a + CONTRIBUTING.md file, then this guide should be followed. These will provide specific guidelines + to set up environments to work on particular projects. If you are unsure, reach out to fellow + team members and your mentor for further guidance. +5. **Make Changes**: Begin working on your chosen task. Be sure to follow the repository's + guidelines and document your work clearly. +6. **Submit a Pull Request (PR)**: Use the provided PR template (if available) to submit your work. + Clearly explain your changes, and explain the context and reasoning behind your changes. Ensure + your code is well-tested and documented. +7. **Peer Review**: All contributions are subject to peer review. This is an opportunity to + collaborate with other developers, improve the quality of your code, and ensure that it adheres + to project standards. Peer reviews will involve a list of tasks that you are expected to review, + but they are also expected to be in the form of a discussion which aims to produce the best + changes possible. +8. **Mentor Review**: After peer review, your mentor will review the changes for final approval + before they are merged. +9. **Merging**: Contributions are typically merged into the main project repository at the end of a + development trimester, ensuring stability and quality. + +
    + +## Important Resources + + + + + + + + + + + + + diff --git a/src/content/docs/Resources/Onboarding Hub/splashkit-onboarding-doc.mdx b/src/content/docs/Resources/Onboarding Hub/splashkit-onboarding-doc.mdx new file mode 100644 index 00000000..43713e96 --- /dev/null +++ b/src/content/docs/Resources/Onboarding Hub/splashkit-onboarding-doc.mdx @@ -0,0 +1,82 @@ +--- +title: SplashKit Onboarding Guide +--- + +import { Steps, LinkCard, CardGrid } from "@astrojs/starlight/components"; + +## Contributing to SplashKit + +Contributing to SplashKit is a great way to help improve a powerful, beginner-friendly game +development toolkit while gaining experience in open-source development. Whether you’re interested +in adding new features, fixing bugs, improving documentation, or helping with testing, we welcome +all kinds of contributions! + +### Trimester Workflow + + + +1. **Explore SplashKit**: Begin by exploring the various SplashKit resources on this website. See + below for links. Familiarize yourself with the structure and functionality of each project and + its repositories and contribution guides. +2. **Choose Tasks**: Work with the team or your mentor to identify tasks you can complete. These may + range from feature development and bug fixes to documentation improvements. +3. **Fork the Repository**: When contributing, be sure to fork from the Thoth-Tech repo, not the + upstream SplashKit repo. This ensures changes are first reviewed and integrated internally before + being merged upstream. +4. **Follow the Contribution Guide**: If a repository has its own contribution guide, usually in a + CONTRIBUTING.md file, then this guide should be followed. These will provide specific guidelines + to setup environments to work on particular projects. If you are unsure, reach out to fellow team + members and your mentor for further guidance. +5. **Make Changes**: Begin working on your chosen task. Be sure to follow the repository's + guidelines and document your work clearly. +6. **Submit a Pull Request (PR)**: Use the provided PR template (if available) to submit your work. + Clearly explain your changes, and explain the context and reasoning behind your changes. Ensure + your code is well-tested and documented. +7. **Peer Review**: All contributions are subject to peer review. This is an opportunity to + collaborate with other developers, improve the quality of your code, and ensure that it adheres + to project standards. Peer reviews will involve a list of tasks that you are expected to review, + but they are also expected to be in the form of a discussion which aims to produce the best + changes possible. +8. **Mentor Review**: After peer review, your mentor will review the changes for final approval + before they are merged. +9. **Merging**: Contributions are typically merged upstream at the end of a development trimester, + ensuring the stability and quality of the SplashKit project. + + + +## Important Resources + + + + + + + + + + + diff --git a/src/content/docs/Resources/Onboarding Hub/thothtech-onboarding-doc.md b/src/content/docs/Resources/Onboarding Hub/thothtech-onboarding-doc.md new file mode 100644 index 00000000..a03e8ec6 --- /dev/null +++ b/src/content/docs/Resources/Onboarding Hub/thothtech-onboarding-doc.md @@ -0,0 +1,123 @@ +--- +title: Thoth Tech Welcome Package +--- + +# Welcome to Thoth Tech! + +We are thrilled to welcome you to the Thoth Tech team. Your arrival marks an exciting new chapter +for us, and we are eager to see the impact you will make as you embark on this journey with us. Your +presence is more than just joining a new companyβ€”it contributes significantly to our growth and +success. + +## About Thoth Tech + +Thoth Tech is a dynamic software development company based in Melbourne, Australia, committed to +creating cutting-edge educational technologies. Our mission is to develop, operate, and deploy tools +that enhance educational outcomes. We aim to empower students, connect them with tutors, and +facilitate personalised learning experiences. + +To get acquainted with Thoth Tech, watch our +[welcome video](https://video.deakin.edu.au/media/t/1_kbi75vmk). + +Once you join Thoth Tech, you will have access to relevant channels on Microsoft Teams. For +company-wide communication, check out the +[General](https://teams.microsoft.com/l/channel/19%3aQfx_STHU90OsVYBHVYKhsRQ5gmEe0s9Q6kOpBf6bli81%40thread.tacv2/General?groupId=0e15669c-3f66-49aa-b023-640fe1dda2e0&tenantId=d02378ec-1688-46d5-8540-1c28b5f470f6) +channel under Thoth Tech, as well as the following specific channels: + +- [On Track](https://teams.microsoft.com/l/channel/19%3abd20175d09414f079490a2403f7fca74%40thread.tacv2/OnTrack?groupId=0e15669c-3f66-49aa-b023-640fe1dda2e0&tenantId=d02378ec-1688-46d5-8540-1c28b5f470f6) +- [Splash Kit](https://teams.microsoft.com/l/channel/19%3aeacddf4a1ced46dbaa8e8a6ea0b47a86%40thread.tacv2/SplashKit?groupId=0e15669c-3f66-49aa-b023-640fe1dda2e0&tenantId=d02378ec-1688-46d5-8540-1c28b5f470f6) +- [CourseFlow](https://teams.microsoft.com/l/channel/19%3af886962165924b0ba929c9081b6c56de%40thread.tacv2/CourseFlow?groupId=0e15669c-3f66-49aa-b023-640fe1dda2e0&tenantId=d02378ec-1688-46d5-8540-1c28b5f470f6) +- [Art Gallery](https://teams.microsoft.com/l/channel/19%3ad3cd3317976a4ae1b35edb32b73e3cef%40thread.tacv2/Art%2520Gallery?groupId=0e15669c-3f66-49aa-b023-640fe1dda2e0&tenantId=d02378ec-1688-46d5-8540-1c28b5f470f6) +- [Company Operations](https://teams.microsoft.com/l/channel/19%3aac7a48118f7d4d12b77c587aa2d0b808%40thread.tacv2/Company%2520Operations?groupId=0e15669c-3f66-49aa-b023-640fe1dda2e0&tenantId=d02378ec-1688-46d5-8540-1c28b5f470f6) + +## Our Culture and Values + +At Thoth Tech, we foster a culture of collaboration, innovation, and respect. Our core values are: + +- **Create effective, maintainable, and user-friendly software**: Our aim is to produce tools that + are not only functional but also enjoyable and easy to use. +- **Uphold sustainable excellence**: We strive for continuous improvement and high standards. +- **Be people-focused**: We collaborate with kindness and respect, valuing each team member's + contributions. +- **Be inclusive and supportive**: We promote an environment where everyone feels valued and + supported. + +These values guide our interactions, decisions, and achievements. We encourage you to embrace them +and bring your unique perspective to enrich our work environment. + +## Measuring Our Success + +Our success is measured by: + +- **User Satisfaction**: Achieving a 90% satisfaction rate with our technology tools. +- **Client Feedback**: Receiving positive feedback regarding the impact of our tools on educational + outcomes. +- **Timely Deliveries**: Meeting deadlines and adhering to project specifications. + +## Promoting Team Culture + +We promote a positive team culture through: + +- **Open Communication**: Encourage honest communication, active listening, and constructive + feedback. +- **Trust and Safety**: Create a trusting and psychologically safe environment for sharing ideas. +- **Collaboration**: Recognise and value each team member’s contributions. +- **Conflict Management**: Address conflicts constructively and seek solutions that benefit the + team. +- **Transparency and Accountability**: Operate with openness and assume positive intent in + communication. +- **Empowerment and Iteration**: Support individual empowerment and iterative progress. + +## Your Impact + +We believe every team member plays a crucial role in shaping our future. Your skills, experiences, +and insights are valuable as we work together to achieve our goals. We’re excited to see the impact +you’ll make on our projects and overall success. + +## Open Communication + +At Thoth Tech, we value open communication. Feel free to share your ideas, concerns, and feedback +with your team, project leads, or across groups. Your voice matters, and we look forward to hearing +your thoughts. + +## Specific Tasks for Your Role + +- See the relevant onboarding guide for your project to ensure your environment is set up to + contribute early on in the trimester. +- Attend the weekly class or review the recording. +- Introduce yourself on the + [Social](https://teams.microsoft.com/l/channel/19%3a149fd9615b2d40d1826f66a22a0382e8%40thread.tacv2/Social?groupId=0e15669c-3f66-49aa-b023-640fe1dda2e0&tenantId=d02378ec-1688-46d5-8540-1c28b5f470f6) + channel. +- Get to know your team, team lead, and mentor. +- Your mentor will set up a weekly cadence. If you haven’t heard from them, reach out to schedule a + one-on-one meeting to discuss next steps and cadences. +- Stay updated on communications in the relevant Teams channels, including the General channel. +- Understand how specific teams will collaborateβ€”using Planner, Git, Teams, etc. +- Agree on team cadence and formats. + +## Getting Help + +There are several ways to get help with Thoth Tech products: + +1. Attend product meetings and chat with your team. +2. Participate in scheduled help sessions for live support. +3. Check Teams channels for recorded videos and Q&A sessions. +4. Post your questions in the relevant Teams channels for community support. +5. Reach out to your team members directly. +6. Contact your product lead for assistance. +7. Consult with your mentor or project leads for guidance. +8. Use online resources and guides for troubleshooting. + +Remember, taking the initiative to seek out answers and using various communication channels is key +to your success. + +## Support Protocols + +1. Ask questions on the forum and wait for a response. +2. Utilise weekly team meetings to address issues or doubts. +3. Attend help and training sessions organised by product leads. +4. Be polite and respectful when asking for assistance. +5. Seek help from colleagues outside your local team if needed. +6. Keep your mentor informed of your progress and any OnTrack tasks. + +Welcome aboard, and we look forward to achieving great things together! diff --git a/src/content/docs/processes/quality-assurance/templates/bug-report-template.md b/src/content/docs/Resources/Quality Assurance/Templates/bug-report-template.md similarity index 100% rename from src/content/docs/processes/quality-assurance/templates/bug-report-template.md rename to src/content/docs/Resources/Quality Assurance/Templates/bug-report-template.md diff --git a/src/content/docs/processes/quality-assurance/templates/pr-template.md b/src/content/docs/Resources/Quality Assurance/Templates/pr-template.md similarity index 100% rename from src/content/docs/processes/quality-assurance/templates/pr-template.md rename to src/content/docs/Resources/Quality Assurance/Templates/pr-template.md diff --git a/src/content/docs/processes/quality-assurance/templates/srs-template.md b/src/content/docs/Resources/Quality Assurance/Templates/srs-template.md similarity index 100% rename from src/content/docs/processes/quality-assurance/templates/srs-template.md rename to src/content/docs/Resources/Quality Assurance/Templates/srs-template.md diff --git a/src/content/docs/processes/quality-assurance/templates/test-plan-template.md b/src/content/docs/Resources/Quality Assurance/Templates/test-plan-template.md similarity index 100% rename from src/content/docs/processes/quality-assurance/templates/test-plan-template.md rename to src/content/docs/Resources/Quality Assurance/Templates/test-plan-template.md diff --git a/src/content/docs/processes/quality-assurance/templates/test-strategy-template.md b/src/content/docs/Resources/Quality Assurance/Templates/test-strategy-template.md similarity index 100% rename from src/content/docs/processes/quality-assurance/templates/test-strategy-template.md rename to src/content/docs/Resources/Quality Assurance/Templates/test-strategy-template.md diff --git a/src/content/docs/Resources/Quality Assurance/git-contributions-guide.md b/src/content/docs/Resources/Quality Assurance/git-contributions-guide.md new file mode 100644 index 00000000..03ea2ee5 --- /dev/null +++ b/src/content/docs/Resources/Quality Assurance/git-contributions-guide.md @@ -0,0 +1,487 @@ +--- +title: Git Contribution Guide +sidebar: + label: Git Contribution Guide +--- + +## Contents + +- [Contributing to Repositories: How To](#contributing-to-repositories-how-to) +- [Branching Guidelines](#branching-guidelines) +- [Commit Guidelines](#commit-guidelines) +- [Code Review Guidelines](#code-review-guidelines) +- [Git Workflow Summary](#git-workflow-summary) + +## Contributing to Repositories: How To + +Repositories are where existing Thoth Tech code is stored, and where new code contributions, once +tested and approved, will ultimately be merged. + +To begin working on your project, follow these steps: + +### If you have yet to cloned the repository to your local machine + +- **Clone the Repository**: Clone your project's relevant Thoth Tech repository to your local + machine: + ```shell + git clone + ``` +- **Navigate to the created project folder**. You will be on the default branch (main/master). + +### If you have already cloned the repository to your local machine + +- **Update Your Local Copy**: Ensure you are on the main/master branch and pull the latest changes + from the origin: + + ```shell + git checkout main + git pull origin main + ``` + +_Then:_ + +- **Create a New Branch:** Create a new branch for your changes as per the + [Branching Guidelines](#branching-guidelines): + + ```shell + git checkout -b + ``` + +- **Make Your Changes:** Implement your code changes on the newly created branch. +- **Commit Your Changes:** Commit your changes using the format provided in the + [Commit Guidelines](#commit-guidelines). + + ```shell + git add . + git commit -m "Descriptive commit message" + ``` + +- **Push Your Branch:** Push your branch to the origin. + + ```shell + git push origin + ``` + +- **Create a Draft Pull Request:** Create a [Draft Pull Request](#draft-pull-request) to merge your + branch into the main Thoth Tech branch for your repository. Add + [Required Approvals](#required-approvals) (note: it will be blocked from merging while in draft + form). Comment on the progress and any feedback sought. + +- **Continue Development:** Keep making changes on your local branch, committing and pushing until + you are satisfied that the code meets all tests, acceptance criteria, and is ready for merging. + +- **Publish Your Pull Request:** Change the status of your Pull Request to "Ready for Review" to + finalise it. + +For an example sequence of git commands used in this process, refer to the +[Git Workflow Summary](#git-workflow-summary). + +## Branching Guidelines + +No commits should be made directly to the default branch (usually main/master/develop). Instead, +branches should be created off the default branch to encompass any changes. + +Branch names must be descriptive and include a reference to the task or subtask number the work +relates to, following this format: + +| Branch Naming Format | Use | +| ------------------------------------------------------ | ---------------------------------------------- | +| `feature/` | New product feature/function | +| `fix/` | For a fix | +| `doc/` | Non-feature-related document additions/changes | + +### Example + +For the Voice Verification project (with tasks reflected in Planner task cards): + +**Product: Voice Verification** + +_Tasks:_ + +1. _Voice Registration_ + + 1.1. _Receive Voice Input_ + + 1.2. _Store Voice Input_ + +2. _Voice Matching_ + +3. _task..._ + + 3.1 _subtask..._ + +A programmer starting work on the Voice Verification component subtask 1.2 should use a branch +named: `feature/voice-verification-1.2-store-voice-input`. + +This branch can be created and checked out using the git command: + +```shell +git checkout -b feature/voice-verification-1.2-store-voice-input +``` + +## Commit Guidelines + +Thoth Tech follows the Git commit message format required by the Doubtfire LMS (see +[doubtfire-lms's CONTRIBUTING.md](https://github.com/doubtfire-lms/doubtfire-deploy/blob/development/CONTRIBUTING.md#commit-message-format)), +which this section mirrors. This format makes for an easier-to-read and more useful commit history. + +### Message Format + +Each commit message consists of a header, a body, and a footer. + +```plaintext +
    + + + +