diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5d2be6f712586..58ed454c985d8 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,4 +1,4 @@ -name: deploy +name: Build and deploy website on: push: @@ -12,26 +12,38 @@ on: workflow_dispatch: permissions: - contents: write + contents: read + +concurrency: + group: website-${{ github.ref }} + cancel-in-progress: true jobs: - deploy: + build: runs-on: ubuntu-latest steps: - - name: Checkout 🛎️ - uses: actions/checkout@v3 - - name: Setup Ruby - uses: ruby/setup-ruby@v1 - with: - ruby-version: '3.2.1' - bundler-cache: true - - name: Install and Build 🔧 - run: | - npm install -g mermaid.cli - bundle exec jekyll build - - name: Deploy 🚀 - if: github.event_name != 'pull_request' - uses: JamesIves/github-pages-deploy-action@v4 - with: - folder: _site + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '24' + cache: npm + - run: npm ci + - run: npm run verify + - uses: actions/upload-pages-artifact@v3 + with: + path: dist + deploy: + needs: build + if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/main') + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index b97cf91da5508..af733011f10d2 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,12 @@ _site .tweet-cache Gemfile.lock vendor - +node_modules/ +dist/ +.astro/ +public/assets/ +public/papers.bib +public/social-card.png +.env +.env.* +!.env.example diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000000000..7f4c2980b4080 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,6 @@ +{ + "plugins": ["prettier-plugin-astro"], + "singleQuote": true, + "printWidth": 100, + "overrides": [{ "files": "*.astro", "options": { "parser": "astro" } }] +} diff --git a/README.md b/README.md index eae151a7c0f1d..f911a81e12797 100644 --- a/README.md +++ b/README.md @@ -1,661 +1,22 @@ -# al-folio - -[maintainers]: https://img.shields.io/badge/maintainers-4-success.svg 'Number of maintainers' - +# Boxi Yu's website -[![deploy](https://github.com/alshedivat/al-folio/actions/workflows/deploy.yml/badge.svg)](https://github.com/alshedivat/al-folio/actions/workflows/deploy.yml) -[![demo](https://img.shields.io/badge/theme-demo-brightgreen.svg)](https://alshedivat.github.io/al-folio/) -[![GitHub contributors](https://img.shields.io/github/contributors/alshedivat/al-folio.svg)](https://github.com/alshedivat/al-folio/graphs/contributors/) -[![Maintainers][maintainers]](#maintainers) -[![GitHub release](https://img.shields.io/github/v/release/alshedivat/al-folio)](https://github.com/alshedivat/al-folio/releases/latest) -[![GitHub license](https://img.shields.io/github/license/alshedivat/al-folio?color=blue)](https://github.com/alshedivat/al-folio/blob/master/LICENSE) -[![GitHub stars](https://img.shields.io/github/stars/alshedivat/al-folio)](https://github.com/alshedivat/al-folio) -[![GitHub forks](https://img.shields.io/github/forks/alshedivat/al-folio)](https://github.com/alshedivat/al-folio/fork) +An academic website for Boxi Yu's research, publications, and service, built with Astro. -[![Docker Image Version](https://img.shields.io/docker/v/amirpourmand/al-folio?sort=semver&label=docker%20image&color=blueviolet)](https://hub.docker.com/r/amirpourmand/al-folio) -[![Docker Image Size](https://img.shields.io/docker/image-size/amirpourmand/al-folio?sort=date&label=docker%20image%20size&color=blueviolet)](https://hub.docker.com/r/amirpourmand/al-folio) -[![Docker Pulls](https://img.shields.io/docker/pulls/amirpourmand/al-folio?color=blueviolet)](https://hub.docker.com/r/amirpourmand/al-folio) +## Quick start -A simple, clean, and responsive [Jekyll](https://jekyllrb.com/) theme for academics. -If you like the theme, give it a star! +Use Node 24 LTS and npm. -[![Preview](https://raw.githubusercontent.com/alshedivat/al-folio/master/assets/img/al-folio-preview.png)](https://alshedivat.github.io/al-folio/) - -## User community - -The vibrant community of **al-folio** users is growing! -Academics around the world use this theme for their homepages, blogs, lab pages, as well as webpages for courses, workshops, conferences, meetups, and more. -Check out the community webpages below. -Feel free to add your own page(s) by sending a PR. - - - - - - - - - - - - - - - - - - -
Academics -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -★ -
Labs -★ -★ -★ -★ -★ -★ -★ -
Courses -CMU PGM (S-19)
-CMU DeepRL (F-19, S-20, F-20, S-21, F-21, S-22)
-CMU MMML (F-20, F-22)
-CMU AMMML (S-22, S-23)
-CMU ASI (S-23)
-CMU Distributed Systems (S-21) -
Conferences & workshops -ICLR Blog Post Track (2023)
-ML Retrospectives (NeurIPS: 2019, 2020; ICML: 2020)
-HAMLETS (NeurIPS: 2020)
-ICBINB (NeurIPS: 2020, 2021)
-Neural Compression (ICLR: 2021)
-Score Based Methods (NeurIPS: 2022)
-Images2Symbols (CogSci: 2022) -
- -## Lighthouse PageSpeed Insights - -[![Google PageSpeed](https://raw.githubusercontent.com/alshedivat/al-folio/master/assets/img/pagespeed.svg)](https://pagespeed.web.dev/report?url=https%3A%2F%2Falshedivat.github.io%2Fal-folio%2F&form_factor=desktop) - -## Table Of Contents - -- [al-folio](#al-folio) - - [User community](#user-community) - - [Lighthouse PageSpeed Insights](#lighthouse-pagespeed-insights) - - [Table Of Contents](#table-of-contents) - - [Getting started](#getting-started) - - [Installation](#installation) - - [Local setup using Docker (Recommended on Windows)](#local-setup-using-docker-recommended-on-windows) - - [Local Setup (Standard)](#local-setup-standard) - - [Deployment](#deployment) - - [Upgrading from a previous version](#upgrading-from-a-previous-version) - - [FAQ](#faq) - - [Features](#features) - - [Publications](#publications) - - [Collections](#collections) - - [Layouts](#layouts) - - [The iconic style of Distill](#the-iconic-style-of-distill) - - [Full support for math \& code](#full-support-for-math--code) - - [Photos](#photos) - - [Other features](#other-features) - - [GitHub's repositories and user stats](#githubs-repositories-and-user-stats) - - [Theming](#theming) - - [Social media previews](#social-media-previews) - - [Atom (RSS-like) Feed](#atom-rss-like-feed) - - [Related posts](#related-posts) - - [Contributing](#contributing) - - [Maintainers](#maintainers) - - [License](#license) - -## Getting started - -Want to learn more about Jekyll? Check out [this tutorial](https://www.taniarascia.com/make-a-static-website-with-jekyll/). -Why Jekyll? Read [Andrej Karpathy's blog post](https://karpathy.github.io/2014/07/01/switching-to-jekyll/)! - -### Installation - -For a hands-on walkthrough of al-folio installation, check out [this cool video tutorial](https://www.youtube.com/watch?v=g6AJ9qPPoyc) by one of the community members! 🎬 🍿 - -The preferred way of using this template is by clicking in [Use this template](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template#creating-a-repository-from-a-template) above the file list. -Then, create a new repository at `github.com:/`. If you plan to upload your site to `.github.io`, -note that the name of your repository must be `.github.io` or `.github.io`, as stated in the [GitHub pages docs](https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#types-of-github-pages-sites). -For more information on how to deploy your site, check the [Deployment](#deployment) section below. After you created your new repository, just download it to your machine: - -```bash -$ git clone git@github.com:/.git -$ cd -``` - ---- - -#### Local setup using Docker (Recommended on Windows) - -You need to take the following steps to get `al-folio` up and running in your local machine: - -- First, install [docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/install/). -- Finally, run the following command that will pull a pre-built image from DockerHub and will run your website. - -```bash -$ docker-compose up -``` - -Note that when you run it for the first time, it will download a docker image of size 300MB or so. - -Now, feel free to customize the theme however you like (don't forget to change the name!). After you are done, you can use the same command (`docker-compose up`) to render the webpage with all you changes. Also, make sure to commit your final changes. - -> To change port number, you can edit `docker-compose.yml` file. - -
(click to expand) Build your own docker image: - -> Note: this approach is only necessary if you would like to build an older or very custom version of al-folio. - -Build and run a new docker image using: - -```bash -$ docker-compose -f docker-local.yml up -``` - -> If you want to update jekyll, install new ruby packages, etc., all you have to do is build the image again using `--force-recreate` argument at the end of previous command! It will download ruby and jekyll and install all ruby packages again from scratch. - -
- ---- - -#### Local Setup (Standard) - -Assuming you have [Ruby](https://www.ruby-lang.org/en/downloads/) and [Bundler](https://bundler.io/) installed on your system (*hint: for ease of managing ruby gems, consider using [rbenv](https://github.com/rbenv/rbenv)*). - -```bash -$ bundle install -$ bundle exec jekyll serve --lsi -``` - -Now, feel free to customize the theme however you like (don't forget to change the name!). -After you are done, **commit** your final changes. - ---- - -#### Deployment - -Deploying your website to [GitHub Pages](https://pages.github.com/) is the most popular option. -Starting version [v0.3.5](https://github.com/alshedivat/al-folio/releases/tag/v0.3.5), **al-folio** will automatically re-deploy your webpage each time you push new changes to your repository! :sparkles: - -**For personal and organization webpages:** - -1. The name of your repository **MUST BE** `.github.io` or `.github.io`. -2. In `_config.yml`, set `url` to `https://.github.io` and leave `baseurl` empty. -3. Set up automatic deployment of your webpage (see instructions below). -4. Make changes, commit, and push! -5. After deployment, the webpage will become available at `.github.io`. - -**For project pages:** - -1. In `_config.yml`, set `url` to `https://.github.io` and `baseurl` to `//`. -2. Set up automatic deployment of your webpage (see instructions below). -3. Make changes, commit, and push! -4. After deployment, the webpage will become available at `.github.io//`. - -**To enable automatic deployment:** - -1. Click on **Actions** tab and **Enable GitHub Actions**; do not worry about creating any workflows as everything has already been set for you. -2. Go to Settings -> Actions -> General -> Workflow permissions, and give **Read and write permissions** to GitHub Actions -3. Make any other changes to your webpage, commit, and push. This will automatically trigger the **Deploy** action. -4. Wait for a few minutes and let the action complete. You can see the progress in the **Actions** tab. If completed successfully, in addition to the `master` branch, your repository should now have a newly built `gh-pages` branch. -5. Finally, in the **Settings** of your repository, in the Pages section, set the branch to `gh-pages` (**NOT** to `master`). For more details, see [Configuring a publishing source for your GitHub Pages site](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#choosing-a-publishing-source). - -If you keep your site on another branch, open `.github/workflows/deploy.yml` **on the branch you keep your website on** and change on->push->branches and on->pull\_request->branches to the branch you keep your website on. This will trigger the action on pulls/pushes on that branch. The action will then deploy the website on the branch it was triggered from. - -
(click to expand) Manual deployment to GitHub Pages: - -If you need to manually re-deploy your website to GitHub pages, go to Actions, click "Deploy" in the left sidebar, then "Run workflow." - -
- -
(click to expand) Deployment to another hosting server (non GitHub Pages): - -If you decide to not use GitHub Pages and host your page elsewhere, simply run: - -```bash -$ bundle exec jekyll build --lsi -``` - -which will (re-)generate the static webpage in the `_site/` folder. -Then simply copy the contents of the `_site/` directory to your hosting server. - -**Note:** Make sure to correctly set the `url` and `baseurl` fields in `_config.yml` before building the webpage. If you are deploying your webpage to `your-domain.com/your-project/`, you must set `url: your-domain.com` and `baseurl: /your-project/`. If you are deploying directly to `your-domain.com`, leave `baseurl` blank. - -
- -
(click to expand) Deployment to a separate repository (advanced users only): - -**Note:** Do not try using this method unless you know what you are doing (make sure you are familiar with [publishing sources](https://help.github.com/en/github/working-with-github-pages/about-github-pages#publishing-sources-for-github-pages-sites)). This approach allows to have the website's source code in one repository and the deployment version in a different repository. - -Let's assume that your website's publishing source is a `publishing-source` subdirectory of a git-versioned repository cloned under `$HOME/repo/`. -For a user site this could well be something like `$HOME/.github.io`. - -Firstly, from the deployment repo dir, checkout the git branch hosting your publishing source. - -Then from the website sources dir (commonly your al-folio fork's clone): - -```bash -$ bundle exec jekyll build --lsi --destination $HOME/repo/publishing-source -``` - -This will instruct jekyll to deploy the website under `$HOME/repo/publishing-source`. - -**Note:** Jekyll will clean `$HOME/repo/publishing-source` before building! - -The quote below is taken directly from the [jekyll configuration docs](https://jekyllrb.com/docs/configuration/options/): - -> Destination folders are cleaned on site builds -> -> The contents of `` are automatically cleaned, by default, when the site is built. Files or folders that are not created by your site will be removed. Some files could be retained by specifying them within the `` configuration directive. -> -> Do not use an important location for ``; instead, use it as a staging area and copy files from there to your web server. - -If `$HOME/repo/publishing-source` contains files that you want jekyll to leave untouched, specify them under `keep_files` in `_config.yml`. -In its default configuration, al-folio will copy the top-level `README.md` to the publishing source. If you want to change this behavior, add `README.md` under `exclude` in `_config.yml`. - -**Note:** Do _not_ run `jekyll clean` on your publishing source repo as this will result in the entire directory getting deleted, irrespective of the content of `keep_files` in `_config.yml`. - -
- ---- - -#### Upgrading from a previous version - -If you installed **al-folio** as described above, you can configure a [GitHub action](https://github.com/AndreasAugustin/actions-template-sync) to automatically sync your repository with the latest version of the theme. - -Go to Settings -> Actions -> General -> Workflow permissions, give Read and write permissions to GitHub Actions, check "Allow GitHub Actions to create and approve pull requests", and save your changes. - -Then go to Actions -> New workflow -> set up a workflow yourself, setup the following workflow and commit your changes: - -```yaml -name: Sync from template -on: - # cronjob trigger - schedule: - - cron: "0 0 1 * *" - # manual trigger - workflow_dispatch: -jobs: - repo-sync: - runs-on: ubuntu-latest - steps: - # To use this repository's private action, you must check out the repository - - name: Checkout - uses: actions/checkout@v3 - - name: actions-template-sync - uses: AndreasAugustin/actions-template-sync@v0.7.3 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - source_repo_path: alshedivat/al-folio - upstream_branch: master -``` - -You will receive a pull request within your repository if there are some changes available in the template. - -Another option is to manually update your code by following the steps below: - -```bash -# Assuming the current directory is -$ git remote add upstream https://github.com/alshedivat/al-folio.git -$ git fetch upstream -$ git rebase v0.9.0 -``` - -If you have extensively customized a previous version, it might be trickier to upgrade. -You can still follow the steps above, but `git rebase` may result in merge conflicts that must be resolved. -See [git rebase manual](https://help.github.com/en/github/using-git/about-git-rebase) and how to [resolve conflicts](https://help.github.com/en/github/using-git/resolving-merge-conflicts-after-a-git-rebase) for more information. -If rebasing is too complicated, we recommend re-installing the new version of the theme from scratch and port over your content and changes from the previous version manually. - ---- - -### FAQ - -Here are some frequently asked questions. -If you have a different question, please ask using [Discussions](https://github.com/alshedivat/al-folio/discussions/categories/q-a). - -1. **Q:** After I create a new repository from this template and setup the repo, I get a deployment error. - Isn't the website supposed to correctly deploy automatically?
- **A:** Yes, if you are using release `v0.3.5` or later, the website will automatically and correctly re-deploy right after your first commit. - Please make some changes (e.g., change your website info in `_config.yml`), commit, and push. - Make sure to follow [deployment instructions](https://github.com/alshedivat/al-folio#deployment) in the previous section. - (Relevant issue: [209](https://github.com/alshedivat/al-folio/issues/209#issuecomment-798849211).) - -2. **Q:** I am using a custom domain (e.g., `foo.com`). - My custom domain becomes blank in the repository settings after each deployment. - How do I fix that?
- **A:** You need to add `CNAME` file to the `master` or `source` branch of your repository. - The file should contain your custom domain name. - (Relevant issue: [130](https://github.com/alshedivat/al-folio/issues/130).) - -3. **Q:** My webpage works locally. - But after deploying, it is not displayed correctly (CSS and JS is not loaded properly). - How do I fix that?
- **A:** Make sure to correctly specify the `url` and `baseurl` paths in `_config.yml`. - Set `url` to `https://.github.io` or to `https://` if you are using a custom domain. - If you are deploying a personal or organization website, leave `baseurl` blank. - If you are deploying a project page, set `baseurl: //`. - -4. **Q:** Atom feed doesn't work. Why? -
- **A:** Make sure to correctly specify the `url` and `baseurl` paths in `_config.yml`. - RSS Feed plugin works with these correctly set up fields: `title`, `url`, `description` and `author`. - Make sure to fill them in an appropriate way and try again. - -5. **Q:** My site doesn't work when I enable `related_blog_posts`. Why?
- **A:** This is probably due to the [classifier reborn](https://github.com/jekyll/classifier-reborn) plugin, which is used to calculate - related posts. If the error states `Liquid Exception: Zero vectors can not be normalized...`, it means that it could not calculate related - posts for a specific post. This is usually caused by [empty or minimal blog posts](https://github.com/jekyll/classifier-reborn/issues/64) - without meaningful words (i.e. only [stop words](https://en.wikipedia.org/wiki/Stop_words)) or even - [specific characters](https://github.com/jekyll/classifier-reborn/issues/194) you used in your posts. Also, the calculus for similar posts are - made for every `post`, which means every page that uses `layout: post`, including the announcements. To change this behavior, simply add - `related_posts: false` to the front matter of the page you don't want to display related posts on. - -## Features - -### Publications - -Your publications' page is generated automatically from your BibTex bibliography. -Simply edit `_bibliography/papers.bib`. -You can also add new `*.bib` files and customize the look of your publications however you like by editing `_pages/publications.md`. - -

- -
(click to expand) Author annotation: - -In publications, the author entry for yourself is identified by string array `scholar:last_name` and string array `scholar:first_name` in `_config.yml`: - -```yaml -scholar: - last_name: [Einstein] - first_name: [Albert, A.] -``` - -If the entry matches one form of the last names and the first names, it will be underlined. -Keep meta-information about your co-authors in `_data/coauthors.yml` and Jekyll will insert links to their webpages automatically. -The co-author data format in `_data/coauthors.yml` is as follows, - -```yaml -"Adams": - - firstname: ["Edwin", "E.", "E. P.", "Edwin Plimpton"] - url: https://en.wikipedia.org/wiki/Edwin_Plimpton_Adams - -"Podolsky": - - firstname: ["Boris", "B.", "B. Y.", "Boris Yakovlevich"] - url: https://en.wikipedia.org/wiki/Boris_Podolsky - -"Rosen": - - firstname: ["Nathan", "N."] - url: https://en.wikipedia.org/wiki/Nathan_Rosen - -"Bach": - - firstname: ["Johann Sebastian", "J. S."] - url: https://en.wikipedia.org/wiki/Johann_Sebastian_Bach - - - firstname: ["Carl Philipp Emanuel", "C. P. E."] - url: https://en.wikipedia.org/wiki/Carl_Philipp_Emanuel_Bach -``` - -If the entry matches one of the combinations of the last names and the first names, it will be highlighted and linked to the url provided. - -
- -
(click to expand) Buttons (through custom bibtex keywords): - -There are several custom bibtex keywords that you can use to affect how the entries are displayed on the webpage: - -- `abbr`: Adds an abbreviation to the left of the entry. You can add links to these by creating a venue.yaml-file in the _data folder and adding entries that match. -- `abstract`: Adds an "Abs" button that expands a hidden text field when clicked to show the abstract text -- `arxiv`: Adds a link to the Arxiv website (Note: only add the arxiv identifier here - the link is generated automatically) -- `bibtex_show`: Adds a "Bib" button that expands a hidden text field with the full bibliography entry -- `html`: Inserts an "HTML" button redirecting to the user-specified link -- `pdf`: Adds a "PDF" button redirecting to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory) -- `supp`: Adds a "Supp" button to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory) -- `blog`: Adds a "Blog" button redirecting to the specified link -- `code`: Adds a "Code" button redirecting to the specified link -- `poster`: Adds a "Poster" button redirecting to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory) -- `slides`: Adds a "Slides" button redirecting to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory) -- `website`: Adds a "Website" button redirecting to the specified link -- `altmetric`: Adds an [Altmetric](https://www.altmetric.com/) badge (Note: if DOI is provided just use `true`, otherwise only add the altmetric identifier here - the link is generated automatically) -- `dimensions`: Adds a [Dimensions](https://www.dimensions.ai/) badge (Note: if DOI or PMID is provided just use `true`, otherwise only add the Dimensions' identifier here - the link is generated automatically) - -You can implement your own buttons by editing the bib.html file. - -
- ---- - -### Collections - -This Jekyll theme implements `collections` to let you break up your work into categories. -The theme comes with two default collections: `news` and `projects`. -Items from the `news` collection are automatically displayed on the home page. -Items from the `projects` collection are displayed on a responsive grid on projects page. - -

- -You can easily create your own collections, apps, short stories, courses, or whatever your creative work is. -To do this, edit the collections in the `_config.yml` file, create a corresponding folder, and create a landing page for your collection, similar to `_pages/projects.md`. - ---- - -### Layouts - -**al-folio** comes with stylish layouts for pages and blog posts. - -#### The iconic style of Distill - -The theme allows you to create blog posts in the [distill.pub](https://distill.pub/) style: - -

- -For more details on how to create distill-styled posts using `` tags, please refer to [the example](https://alshedivat.github.io/al-folio/blog/2021/distill/). - -#### Full support for math & code - -**al-folio** supports fast math typesetting through [MathJax](https://www.mathjax.org/) and code syntax highlighting using [GitHub style](https://github.com/jwarby/jekyll-pygments-themes): - -

- - -

- -#### Photos - -Photo formatting is made simple using [Bootstrap's grid system](https://getbootstrap.com/docs/4.4/layout/grid/). -Easily create beautiful grids within your blog posts and project pages: - -

- - - -

- ---- - -### Other features - -#### GitHub's repositories and user stats - -**al-folio** uses [github-readme-stats](https://github.com/anuraghazra/github-readme-stats) and [github-profile-trophy](https://github.com/ryo-ma/github-profile-trophy) -to display GitHub repositories and user stats on the `/repositories/` page. - -Edit the `_data/repositories.yml` and change the `github_users` and `github_repos` lists to include your own GitHub profile and repositories to the `/repositories/` page. - -You may also use the following codes for displaying this in any other pages. - -```html - -{% if site.data.repositories.github_users %} -
- {% for user in site.data.repositories.github_users %} - {% include repository/repo_user.html username=user %} - {% endfor %} -
-{% endif %} - - -{% if site.repo_trophies.enabled %} -{% for user in site.data.repositories.github_users %} - {% if site.data.repositories.github_users.size > 1 %} -

{{ user }}

- {% endif %} -
- {% include repository/repo_trophies.html username=user %} -
-{% endfor %} -{% endif %} - - -{% if site.data.repositories.github_repos %} -
- {% for repo in site.data.repositories.github_repos %} - {% include repository/repo.html repository=repo %} - {% endfor %} -
-{% endif %} +```sh +npm ci +npm run dev ``` -#### Theming - -A variety of beautiful theme colors have been selected for you to choose from. -The default is purple, but you can quickly change it by editing the -`--global-theme-color` variable in the `_sass/_themes.scss` file. -Other color variables are listed there as well. -The stock theme color options available can be found at `_sass/variables.scss`. -You can also add your own colors to this file assigning each a name for ease of -use across the template. - -#### Social media previews - -**al-folio** supports preview images on social media. -To enable this functionality you will need to set `serve_og_meta` to `true` in your `_config.yml`. -Once you have done so, all your site's pages will include Open Graph data in the HTML head element. - -You will then need to configure what image to display in your site's social media previews. -This can be configured on a per-page basis, by setting the `og_image` page variable. -If for an individual page this variable is not set, then the theme will fall back to a site-wide `og_image` variable, configurable in your `_config.yml`. -In both the page-specific and site-wide cases, the `og_image` variable needs to hold the URL for the image you wish to display in social media previews. - -#### Atom (RSS-like) Feed - -It generates an Atom (RSS-like) feed of your posts, useful for Atom and RSS readers. -The feed is reachable simply by typing after your homepage `/feed.xml`. -E.g. assuming your website mountpoint is the main folder, you can type `yourusername.github.io/feed.xml` - -#### Related posts - -By default, there will be a related posts section on the bottom of the blog posts. -These are generated by selecting the `max_related` most recent posts that share at least `min_common_tags` tags with the current post. -If you do not want to display related posts on a specific post, simply add `related_posts: false` to the front matter of the post. -If you want to disable it for all posts, simply set `enabled` to false in the `related_blog_posts` section in `_config.yml`. - -## Contributing - -Contributions to al-folio are very welcome! -Before you get started, please take a look at [the guidelines](CONTRIBUTING.md). - -If you would like to improve documentation, add your webpage to the list below, or fix a minor inconsistency or bug, please feel free to send a PR directly to `master`. -For more complex issues/bugs or feature requests, please open an issue using the appropriate template. - -### Maintainers - -Our most active contributors are welcome to join the maintainers team. -If you are interested, please reach out! - - - - - - - - - - - - - -

Maruan

Rohan Deb Sarkar

Amir Pourmand

George
- - - - - - -## License +Run `npm run verify` before release. Production builds exclude editorial drafts. -The theme is available as open source under the terms of the [MIT License](https://github.com/alshedivat/al-folio/blob/master/LICENSE). +- [Website maintenance and publishing](WEBSITE.md) +- [Refinement plan](_planning/site-refinement-plan.md) +- [Migration report](_planning/migration-report.md) +- [Original al-folio documentation](_planning/legacy-theme-readme.md) -Originally, **al-folio** was based on the [\*folio theme](https://github.com/bogoli/-folio) (published by [Lia Bogoev](https://liabogoev.com) and under the MIT license). -Since then, it got a full re-write of the styles and many additional cool features. +The original Jekyll content and assets remain available for reference. Only +Astro's `dist/` output is deployed by the updated workflow. diff --git a/WEBSITE.md b/WEBSITE.md new file mode 100644 index 0000000000000..c459d77efea2a --- /dev/null +++ b/WEBSITE.md @@ -0,0 +1,117 @@ +# Website maintenance + +The new site uses Astro static output. Original Jekyll source remains for reference +and is not included in the generated website. + +## Current scope: academic homepage + +The homepage uses a compact biography followed by a linked research map. Its six +selected publications are grouped into coding-agent evaluation, test oracles, +AI-system testing, and AIOps. Edit `src/data/research.ts` to update map membership +and publication groups together. The map describes thematic connections, not a +timeline or technical dependency graph. Its layout becomes a vertical list on +small screens; all links work without client-side JavaScript. + +The homepage and navigation prioritize academic identity, research, publications, +service, and biography. Writing and education routes are retained for later work, +but are not promoted in the academic navigation or homepage. Normal local preview +should use `npm run dev` (without drafts). + +Research summaries and resource links live in `src/data/site.ts`; full citation +metadata lives in `_bibliography/papers.bib`. Keep quantitative claims scoped to +the cited paper's evaluation. Service records in `src/data/services.json` preserve +all 20 original entries across 2021-2025, with an integration test against the +original source. Add new service records to both the migration baseline and the +dataset, or explicitly update the migration test when maintaining newer years. + +## Run and verify + +Use Node 24 LTS (minimum 22.12) and npm. + +```sh +npm ci +npm run dev +npm run dev:drafts +npm run verify +npm run preview +``` + +Use either development command, not both on the same port. Normal development +hides drafts; `dev:drafts` shows them with a visible editorial banner and noindex. +Production builds always exclude drafts, including when CONTENT_PREVIEW is set. +Astro 7 runs the dev server in the background. Use `npx astro dev stop` before +switching preview modes; `npx astro dev logs` displays its logs. + +`verify` runs type checks, the static build, link and migration checks, draft +isolation checks, and a publishing integration test in a temporary directory. +The integration test renders both Markdown and MDX without changing local articles. + +## Write an article + +Create a stable filename under `src/content/writing/`. Its name becomes the URL. +Use Markdown by default and MDX when an article needs a component. + +```yaml +--- +title: 'A precise article title' +description: 'What the reader will learn.' +publishedAt: 2026-09-08 +language: en +topics: [AI evaluation] +audience: developers and research readers +draft: true +featured: false +series: Evaluating AI in practice +order: 3 +--- +``` + +`series` and `order` are optional, but must be supplied together. Use distinct +order values within a series. `updatedAt` describes a substantive revision. +Review facts, references, examples, and resource links. Then set `draft: false`, +select the publication date, and run `npm run verify`. +Home shows up to two featured articles; Writing contains all released articles. +RSS and sitemap use the same publication-date and draft restrictions. + +Future-dated posts require a new build on or after their publication date. This +repository does not schedule future publishing automatically. Articles linked +from a released article must also be published; broken links fail verification. + +The two initial English explainers are editorial drafts prepared during the +redesign, not existing published work. Review them before release. + +## Update research and background + +- `_bibliography/papers.bib`: publication records, resource URLs, citation keys. +- `src/data/site.ts`: profile metadata and three research highlights. +- `src/data/services.json`: migrated academic service records. +- `_news/*.md` and `_talks/*.md`: retained announcement and talk sources. +- `src/pages/about.astro` and `src/pages/teaching.astro`: background and assistantships. +- `src/pages/education.astro`: learning resource and series placement. + +Bibliography keys remain publication anchors. The unused legacy APS string +declaration was removed; the lightweight parser expects explicit field values +rather than BibTeX string macros. Existing PDF paths remain unchanged. +`prepare:assets` copies PDFs, portrait and legacy icon, exports clean BibTeX, +and generates a PNG social card from `public/social-card.svg`. + +## Release and rollback + +Review the site and editorial drafts separately. Production builds exclude drafts. + +The workflow validates pull requests and uploads an artifact without publishing +them. Pushes or manual runs on master/main deploy verified `dist/` output using +GitHub's official upload-pages-artifact and deploy-pages actions. Repository Pages +settings must use GitHub Actions as the build source; the github-pages environment +allows the master branch to deploy. + +The previous deployed gh-pages commit is +`5ad5ce2f6b855d3b6ececc9be7090c22e14c2fe6`; the branch is retained for rollback. +For rollback, prepare a revert PR for the migration, including its workflow, or +redeploy the retained known-good static artifact through the normal deployment +process. Avoid force-pushing or resetting shared history. The source baseline for +this redesign is 5b12a018464201cee4c0b2bf148779c425289b0d. To restore the legacy +site immediately, switch Pages back to branch publishing from gh-pages at its +retained commit. Reverting source code alone does not change the Pages build source. + +See `_planning/migration-report.md` for retained routes and editorial follow-ups. diff --git a/_bibliography/papers.bib b/_bibliography/papers.bib index fb4a511a7aaa3..f48f570c5e003 100644 --- a/_bibliography/papers.bib +++ b/_bibliography/papers.bib @@ -1,31 +1,34 @@ --- --- -@string{aps = {American Physical Society,}} - - @article{yu2026sweabs, abbr={ICML}, title={SWE-ABS: Adversarial Benchmark Strengthening Exposes Inflated Success Rates on Test-based Benchmark}, - author={Yu, Boxi and others}, + author={Yu, Boxi and Cao, Yang and Zhang, Yuzhong and Lin, Liting and Xu, Junjielong and Zhong, Zhiqing and Xu, Qinghua and Wang, Guancheng and Cao, Jialun and Cheung, Shing-Chi and He, Pinjia and Briand, Lionel}, journal={ICML'26: International Conference on Machine Learning}, year={2026}, selected={true}, - topic={CodeAgents} + topic={CodeAgents}, + arxiv={2603.00520}, + url={https://arxiv.org/abs/2603.00520}, + pdf={https://arxiv.org/pdf/2603.00520} } -@article{yu2025utboost, +@inproceedings{yu2025utboost, abbr={ACL}, title={UTBoost: Rigorous Evaluation of Coding Agents on SWE-Bench}, author={Boxi Yu and Yuxuan Zhu and Pinjia He and Daniel Kang}, year={2025}, + booktitle={Proceedings of the 63rd Annual Meeting of the Association for Computational Linguistics (Volume 1: Long Papers)}, + pages={3762--3774}, + doi={10.18653/v1/2025.acl-long.189}, selected={true}, topic={CodeAgents}, arxiv={2506.09289}, code={https://github.com/CUHK-Shenzhen-SE/UTBoost}, primaryClass={cs.SE}, - url={https://arxiv.org/abs/2506.09289}, - pdf={https://arxiv.org/pdf/2506.09289} + url={https://aclanthology.org/2025.acl-long.189/}, + pdf={https://aclanthology.org/2025.acl-long.189.pdf} } @article{yu2023Retro, @@ -43,7 +46,7 @@ @article{yu2023Retro @article{cao2025, abbr={ICML Position}, - title={How Should We Build A Benchmark? Revisiting 274 Code-Related Benchmarks For LLMs}, + title={Code Benchmarks Should Prioritize Rigor, Reliability, and Reproducibility}, author={Jialun Cao and Yuk-Kit Chan and Zixuan Ling and Wenxuan Wang and Shuqing Li and Mingwei Liu and Ruixi Qiao and Yuting Han and Chaozheng Wang and Boxi Yu and Pinjia He and Shuai Wang and Zibin Zheng and Michael R. Lyu and Shing-Chi Cheung}, journal={ICML Position}, year={2026}, @@ -59,6 +62,8 @@ @article{cao2025 @article{zhong2025deprecation, abbr={ICSE}, title={An Empirical Study on Package-Level Deprecation in Python Ecosystem}, + doi={10.1109/ICSE55347.2025.00046}, + url={https://doi.org/10.1109/ICSE55347.2025.00046}, author={Zhong, Zhiqing and He, Shilin and Wang, Haoxuan and Yu, Boxi and Yang, Haowen and He, Pinjia}, journal={ICSE'25: International Conference on Software Engineering}, year={2025}, @@ -94,6 +99,8 @@ @article{yu2024dspyg @article{mang2024EQR, abbr={ICSE}, title={Testing Graph Database Systems via Equivalent Query Rewriting}, + doi={10.1145/3597503.3639200}, + url={https://doi.org/10.1145/3597503.3639200}, author={Mang, Qiuyang and Fang, Aoyang and Yu, Boxi and Chen, Hanfei and He, Pinjia}, journal={ICSE'24: International Conference on Software Engineering}, year={2024}, @@ -123,7 +130,7 @@ @article{yu2023tin author={Yu, Boxi and Hu, Yiyan and Mang, Qiuyang and Hu, Wenhan and He, Pinjia}, journal={ESEC/FSE'23: Joint European Software Engineering Conference and Symposium on the Foundations of Software Engineering}, pdf={https://arxiv.org/pdf/2308.07937.pdf}, - code={https://github.com/RobustNLP/TestIC}, + code={https://github.com/RobustNLP/TestNER}, year={2023}, selected={true}, topic={AutomatedTesting}, @@ -151,7 +158,7 @@ @inproceedings{yu2023rome series = {ISSTA 2023}, selected={true}, topic={AutomatedTesting}, - code={https://github.com/RobustNLP/TestNER}, + code={https://github.com/RobustNLP/TestIC}, html={https://dl.acm.org/doi/abs/10.1145/3597926.3598094}, pdf={https://arxiv.org/pdf/2306.02228.pdf}, slides={Rome_slides.pdf} diff --git a/_config.yml b/_config.yml index 7453f6a35a25c..1208b446ddc3d 100644 --- a/_config.yml +++ b/_config.yml @@ -6,7 +6,7 @@ title: blank # the website title (if blank, full name will be used instead) first_name: Boxi middle_name: last_name: Yu -email: boxiyu@link.cuhk.edu.cn +email: boxi.yu@lero.ie description: > # the ">" symbol means to ignore newlines until "footer_text:" Academic homepage of Boxi Yu, Senior Research Fellow at Lero. footer_text: > diff --git a/_planning/legacy-theme-readme.md b/_planning/legacy-theme-readme.md new file mode 100644 index 0000000000000..eae151a7c0f1d --- /dev/null +++ b/_planning/legacy-theme-readme.md @@ -0,0 +1,661 @@ +# al-folio + +[maintainers]: https://img.shields.io/badge/maintainers-4-success.svg 'Number of maintainers' + + +[![deploy](https://github.com/alshedivat/al-folio/actions/workflows/deploy.yml/badge.svg)](https://github.com/alshedivat/al-folio/actions/workflows/deploy.yml) +[![demo](https://img.shields.io/badge/theme-demo-brightgreen.svg)](https://alshedivat.github.io/al-folio/) +[![GitHub contributors](https://img.shields.io/github/contributors/alshedivat/al-folio.svg)](https://github.com/alshedivat/al-folio/graphs/contributors/) +[![Maintainers][maintainers]](#maintainers) +[![GitHub release](https://img.shields.io/github/v/release/alshedivat/al-folio)](https://github.com/alshedivat/al-folio/releases/latest) +[![GitHub license](https://img.shields.io/github/license/alshedivat/al-folio?color=blue)](https://github.com/alshedivat/al-folio/blob/master/LICENSE) +[![GitHub stars](https://img.shields.io/github/stars/alshedivat/al-folio)](https://github.com/alshedivat/al-folio) +[![GitHub forks](https://img.shields.io/github/forks/alshedivat/al-folio)](https://github.com/alshedivat/al-folio/fork) + +[![Docker Image Version](https://img.shields.io/docker/v/amirpourmand/al-folio?sort=semver&label=docker%20image&color=blueviolet)](https://hub.docker.com/r/amirpourmand/al-folio) +[![Docker Image Size](https://img.shields.io/docker/image-size/amirpourmand/al-folio?sort=date&label=docker%20image%20size&color=blueviolet)](https://hub.docker.com/r/amirpourmand/al-folio) +[![Docker Pulls](https://img.shields.io/docker/pulls/amirpourmand/al-folio?color=blueviolet)](https://hub.docker.com/r/amirpourmand/al-folio) + +A simple, clean, and responsive [Jekyll](https://jekyllrb.com/) theme for academics. +If you like the theme, give it a star! + +[![Preview](https://raw.githubusercontent.com/alshedivat/al-folio/master/assets/img/al-folio-preview.png)](https://alshedivat.github.io/al-folio/) + +## User community + +The vibrant community of **al-folio** users is growing! +Academics around the world use this theme for their homepages, blogs, lab pages, as well as webpages for courses, workshops, conferences, meetups, and more. +Check out the community webpages below. +Feel free to add your own page(s) by sending a PR. + + + + + + + + + + + + + + + + + + +
Academics +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +★ +
Labs +★ +★ +★ +★ +★ +★ +★ +
Courses +CMU PGM (S-19)
+CMU DeepRL (F-19, S-20, F-20, S-21, F-21, S-22)
+CMU MMML (F-20, F-22)
+CMU AMMML (S-22, S-23)
+CMU ASI (S-23)
+CMU Distributed Systems (S-21) +
Conferences & workshops +ICLR Blog Post Track (2023)
+ML Retrospectives (NeurIPS: 2019, 2020; ICML: 2020)
+HAMLETS (NeurIPS: 2020)
+ICBINB (NeurIPS: 2020, 2021)
+Neural Compression (ICLR: 2021)
+Score Based Methods (NeurIPS: 2022)
+Images2Symbols (CogSci: 2022) +
+ +## Lighthouse PageSpeed Insights + +[![Google PageSpeed](https://raw.githubusercontent.com/alshedivat/al-folio/master/assets/img/pagespeed.svg)](https://pagespeed.web.dev/report?url=https%3A%2F%2Falshedivat.github.io%2Fal-folio%2F&form_factor=desktop) + +## Table Of Contents + +- [al-folio](#al-folio) + - [User community](#user-community) + - [Lighthouse PageSpeed Insights](#lighthouse-pagespeed-insights) + - [Table Of Contents](#table-of-contents) + - [Getting started](#getting-started) + - [Installation](#installation) + - [Local setup using Docker (Recommended on Windows)](#local-setup-using-docker-recommended-on-windows) + - [Local Setup (Standard)](#local-setup-standard) + - [Deployment](#deployment) + - [Upgrading from a previous version](#upgrading-from-a-previous-version) + - [FAQ](#faq) + - [Features](#features) + - [Publications](#publications) + - [Collections](#collections) + - [Layouts](#layouts) + - [The iconic style of Distill](#the-iconic-style-of-distill) + - [Full support for math \& code](#full-support-for-math--code) + - [Photos](#photos) + - [Other features](#other-features) + - [GitHub's repositories and user stats](#githubs-repositories-and-user-stats) + - [Theming](#theming) + - [Social media previews](#social-media-previews) + - [Atom (RSS-like) Feed](#atom-rss-like-feed) + - [Related posts](#related-posts) + - [Contributing](#contributing) + - [Maintainers](#maintainers) + - [License](#license) + +## Getting started + +Want to learn more about Jekyll? Check out [this tutorial](https://www.taniarascia.com/make-a-static-website-with-jekyll/). +Why Jekyll? Read [Andrej Karpathy's blog post](https://karpathy.github.io/2014/07/01/switching-to-jekyll/)! + +### Installation + +For a hands-on walkthrough of al-folio installation, check out [this cool video tutorial](https://www.youtube.com/watch?v=g6AJ9qPPoyc) by one of the community members! 🎬 🍿 + +The preferred way of using this template is by clicking in [Use this template](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template#creating-a-repository-from-a-template) above the file list. +Then, create a new repository at `github.com:/`. If you plan to upload your site to `.github.io`, +note that the name of your repository must be `.github.io` or `.github.io`, as stated in the [GitHub pages docs](https://docs.github.com/en/pages/getting-started-with-github-pages/about-github-pages#types-of-github-pages-sites). +For more information on how to deploy your site, check the [Deployment](#deployment) section below. After you created your new repository, just download it to your machine: + +```bash +$ git clone git@github.com:/.git +$ cd +``` + +--- + +#### Local setup using Docker (Recommended on Windows) + +You need to take the following steps to get `al-folio` up and running in your local machine: + +- First, install [docker](https://docs.docker.com/get-docker/) and [docker-compose](https://docs.docker.com/compose/install/). +- Finally, run the following command that will pull a pre-built image from DockerHub and will run your website. + +```bash +$ docker-compose up +``` + +Note that when you run it for the first time, it will download a docker image of size 300MB or so. + +Now, feel free to customize the theme however you like (don't forget to change the name!). After you are done, you can use the same command (`docker-compose up`) to render the webpage with all you changes. Also, make sure to commit your final changes. + +> To change port number, you can edit `docker-compose.yml` file. + +
(click to expand) Build your own docker image: + +> Note: this approach is only necessary if you would like to build an older or very custom version of al-folio. + +Build and run a new docker image using: + +```bash +$ docker-compose -f docker-local.yml up +``` + +> If you want to update jekyll, install new ruby packages, etc., all you have to do is build the image again using `--force-recreate` argument at the end of previous command! It will download ruby and jekyll and install all ruby packages again from scratch. + +
+ +--- + +#### Local Setup (Standard) + +Assuming you have [Ruby](https://www.ruby-lang.org/en/downloads/) and [Bundler](https://bundler.io/) installed on your system (*hint: for ease of managing ruby gems, consider using [rbenv](https://github.com/rbenv/rbenv)*). + +```bash +$ bundle install +$ bundle exec jekyll serve --lsi +``` + +Now, feel free to customize the theme however you like (don't forget to change the name!). +After you are done, **commit** your final changes. + +--- + +#### Deployment + +Deploying your website to [GitHub Pages](https://pages.github.com/) is the most popular option. +Starting version [v0.3.5](https://github.com/alshedivat/al-folio/releases/tag/v0.3.5), **al-folio** will automatically re-deploy your webpage each time you push new changes to your repository! :sparkles: + +**For personal and organization webpages:** + +1. The name of your repository **MUST BE** `.github.io` or `.github.io`. +2. In `_config.yml`, set `url` to `https://.github.io` and leave `baseurl` empty. +3. Set up automatic deployment of your webpage (see instructions below). +4. Make changes, commit, and push! +5. After deployment, the webpage will become available at `.github.io`. + +**For project pages:** + +1. In `_config.yml`, set `url` to `https://.github.io` and `baseurl` to `//`. +2. Set up automatic deployment of your webpage (see instructions below). +3. Make changes, commit, and push! +4. After deployment, the webpage will become available at `.github.io//`. + +**To enable automatic deployment:** + +1. Click on **Actions** tab and **Enable GitHub Actions**; do not worry about creating any workflows as everything has already been set for you. +2. Go to Settings -> Actions -> General -> Workflow permissions, and give **Read and write permissions** to GitHub Actions +3. Make any other changes to your webpage, commit, and push. This will automatically trigger the **Deploy** action. +4. Wait for a few minutes and let the action complete. You can see the progress in the **Actions** tab. If completed successfully, in addition to the `master` branch, your repository should now have a newly built `gh-pages` branch. +5. Finally, in the **Settings** of your repository, in the Pages section, set the branch to `gh-pages` (**NOT** to `master`). For more details, see [Configuring a publishing source for your GitHub Pages site](https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#choosing-a-publishing-source). + +If you keep your site on another branch, open `.github/workflows/deploy.yml` **on the branch you keep your website on** and change on->push->branches and on->pull\_request->branches to the branch you keep your website on. This will trigger the action on pulls/pushes on that branch. The action will then deploy the website on the branch it was triggered from. + +
(click to expand) Manual deployment to GitHub Pages: + +If you need to manually re-deploy your website to GitHub pages, go to Actions, click "Deploy" in the left sidebar, then "Run workflow." + +
+ +
(click to expand) Deployment to another hosting server (non GitHub Pages): + +If you decide to not use GitHub Pages and host your page elsewhere, simply run: + +```bash +$ bundle exec jekyll build --lsi +``` + +which will (re-)generate the static webpage in the `_site/` folder. +Then simply copy the contents of the `_site/` directory to your hosting server. + +**Note:** Make sure to correctly set the `url` and `baseurl` fields in `_config.yml` before building the webpage. If you are deploying your webpage to `your-domain.com/your-project/`, you must set `url: your-domain.com` and `baseurl: /your-project/`. If you are deploying directly to `your-domain.com`, leave `baseurl` blank. + +
+ +
(click to expand) Deployment to a separate repository (advanced users only): + +**Note:** Do not try using this method unless you know what you are doing (make sure you are familiar with [publishing sources](https://help.github.com/en/github/working-with-github-pages/about-github-pages#publishing-sources-for-github-pages-sites)). This approach allows to have the website's source code in one repository and the deployment version in a different repository. + +Let's assume that your website's publishing source is a `publishing-source` subdirectory of a git-versioned repository cloned under `$HOME/repo/`. +For a user site this could well be something like `$HOME/.github.io`. + +Firstly, from the deployment repo dir, checkout the git branch hosting your publishing source. + +Then from the website sources dir (commonly your al-folio fork's clone): + +```bash +$ bundle exec jekyll build --lsi --destination $HOME/repo/publishing-source +``` + +This will instruct jekyll to deploy the website under `$HOME/repo/publishing-source`. + +**Note:** Jekyll will clean `$HOME/repo/publishing-source` before building! + +The quote below is taken directly from the [jekyll configuration docs](https://jekyllrb.com/docs/configuration/options/): + +> Destination folders are cleaned on site builds +> +> The contents of `` are automatically cleaned, by default, when the site is built. Files or folders that are not created by your site will be removed. Some files could be retained by specifying them within the `` configuration directive. +> +> Do not use an important location for ``; instead, use it as a staging area and copy files from there to your web server. + +If `$HOME/repo/publishing-source` contains files that you want jekyll to leave untouched, specify them under `keep_files` in `_config.yml`. +In its default configuration, al-folio will copy the top-level `README.md` to the publishing source. If you want to change this behavior, add `README.md` under `exclude` in `_config.yml`. + +**Note:** Do _not_ run `jekyll clean` on your publishing source repo as this will result in the entire directory getting deleted, irrespective of the content of `keep_files` in `_config.yml`. + +
+ +--- + +#### Upgrading from a previous version + +If you installed **al-folio** as described above, you can configure a [GitHub action](https://github.com/AndreasAugustin/actions-template-sync) to automatically sync your repository with the latest version of the theme. + +Go to Settings -> Actions -> General -> Workflow permissions, give Read and write permissions to GitHub Actions, check "Allow GitHub Actions to create and approve pull requests", and save your changes. + +Then go to Actions -> New workflow -> set up a workflow yourself, setup the following workflow and commit your changes: + +```yaml +name: Sync from template +on: + # cronjob trigger + schedule: + - cron: "0 0 1 * *" + # manual trigger + workflow_dispatch: +jobs: + repo-sync: + runs-on: ubuntu-latest + steps: + # To use this repository's private action, you must check out the repository + - name: Checkout + uses: actions/checkout@v3 + - name: actions-template-sync + uses: AndreasAugustin/actions-template-sync@v0.7.3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + source_repo_path: alshedivat/al-folio + upstream_branch: master +``` + +You will receive a pull request within your repository if there are some changes available in the template. + +Another option is to manually update your code by following the steps below: + +```bash +# Assuming the current directory is +$ git remote add upstream https://github.com/alshedivat/al-folio.git +$ git fetch upstream +$ git rebase v0.9.0 +``` + +If you have extensively customized a previous version, it might be trickier to upgrade. +You can still follow the steps above, but `git rebase` may result in merge conflicts that must be resolved. +See [git rebase manual](https://help.github.com/en/github/using-git/about-git-rebase) and how to [resolve conflicts](https://help.github.com/en/github/using-git/resolving-merge-conflicts-after-a-git-rebase) for more information. +If rebasing is too complicated, we recommend re-installing the new version of the theme from scratch and port over your content and changes from the previous version manually. + +--- + +### FAQ + +Here are some frequently asked questions. +If you have a different question, please ask using [Discussions](https://github.com/alshedivat/al-folio/discussions/categories/q-a). + +1. **Q:** After I create a new repository from this template and setup the repo, I get a deployment error. + Isn't the website supposed to correctly deploy automatically?
+ **A:** Yes, if you are using release `v0.3.5` or later, the website will automatically and correctly re-deploy right after your first commit. + Please make some changes (e.g., change your website info in `_config.yml`), commit, and push. + Make sure to follow [deployment instructions](https://github.com/alshedivat/al-folio#deployment) in the previous section. + (Relevant issue: [209](https://github.com/alshedivat/al-folio/issues/209#issuecomment-798849211).) + +2. **Q:** I am using a custom domain (e.g., `foo.com`). + My custom domain becomes blank in the repository settings after each deployment. + How do I fix that?
+ **A:** You need to add `CNAME` file to the `master` or `source` branch of your repository. + The file should contain your custom domain name. + (Relevant issue: [130](https://github.com/alshedivat/al-folio/issues/130).) + +3. **Q:** My webpage works locally. + But after deploying, it is not displayed correctly (CSS and JS is not loaded properly). + How do I fix that?
+ **A:** Make sure to correctly specify the `url` and `baseurl` paths in `_config.yml`. + Set `url` to `https://.github.io` or to `https://` if you are using a custom domain. + If you are deploying a personal or organization website, leave `baseurl` blank. + If you are deploying a project page, set `baseurl: //`. + +4. **Q:** Atom feed doesn't work. Why? +
+ **A:** Make sure to correctly specify the `url` and `baseurl` paths in `_config.yml`. + RSS Feed plugin works with these correctly set up fields: `title`, `url`, `description` and `author`. + Make sure to fill them in an appropriate way and try again. + +5. **Q:** My site doesn't work when I enable `related_blog_posts`. Why?
+ **A:** This is probably due to the [classifier reborn](https://github.com/jekyll/classifier-reborn) plugin, which is used to calculate + related posts. If the error states `Liquid Exception: Zero vectors can not be normalized...`, it means that it could not calculate related + posts for a specific post. This is usually caused by [empty or minimal blog posts](https://github.com/jekyll/classifier-reborn/issues/64) + without meaningful words (i.e. only [stop words](https://en.wikipedia.org/wiki/Stop_words)) or even + [specific characters](https://github.com/jekyll/classifier-reborn/issues/194) you used in your posts. Also, the calculus for similar posts are + made for every `post`, which means every page that uses `layout: post`, including the announcements. To change this behavior, simply add + `related_posts: false` to the front matter of the page you don't want to display related posts on. + +## Features + +### Publications + +Your publications' page is generated automatically from your BibTex bibliography. +Simply edit `_bibliography/papers.bib`. +You can also add new `*.bib` files and customize the look of your publications however you like by editing `_pages/publications.md`. + +

+ +
(click to expand) Author annotation: + +In publications, the author entry for yourself is identified by string array `scholar:last_name` and string array `scholar:first_name` in `_config.yml`: + +```yaml +scholar: + last_name: [Einstein] + first_name: [Albert, A.] +``` + +If the entry matches one form of the last names and the first names, it will be underlined. +Keep meta-information about your co-authors in `_data/coauthors.yml` and Jekyll will insert links to their webpages automatically. +The co-author data format in `_data/coauthors.yml` is as follows, + +```yaml +"Adams": + - firstname: ["Edwin", "E.", "E. P.", "Edwin Plimpton"] + url: https://en.wikipedia.org/wiki/Edwin_Plimpton_Adams + +"Podolsky": + - firstname: ["Boris", "B.", "B. Y.", "Boris Yakovlevich"] + url: https://en.wikipedia.org/wiki/Boris_Podolsky + +"Rosen": + - firstname: ["Nathan", "N."] + url: https://en.wikipedia.org/wiki/Nathan_Rosen + +"Bach": + - firstname: ["Johann Sebastian", "J. S."] + url: https://en.wikipedia.org/wiki/Johann_Sebastian_Bach + + - firstname: ["Carl Philipp Emanuel", "C. P. E."] + url: https://en.wikipedia.org/wiki/Carl_Philipp_Emanuel_Bach +``` + +If the entry matches one of the combinations of the last names and the first names, it will be highlighted and linked to the url provided. + +
+ +
(click to expand) Buttons (through custom bibtex keywords): + +There are several custom bibtex keywords that you can use to affect how the entries are displayed on the webpage: + +- `abbr`: Adds an abbreviation to the left of the entry. You can add links to these by creating a venue.yaml-file in the _data folder and adding entries that match. +- `abstract`: Adds an "Abs" button that expands a hidden text field when clicked to show the abstract text +- `arxiv`: Adds a link to the Arxiv website (Note: only add the arxiv identifier here - the link is generated automatically) +- `bibtex_show`: Adds a "Bib" button that expands a hidden text field with the full bibliography entry +- `html`: Inserts an "HTML" button redirecting to the user-specified link +- `pdf`: Adds a "PDF" button redirecting to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory) +- `supp`: Adds a "Supp" button to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory) +- `blog`: Adds a "Blog" button redirecting to the specified link +- `code`: Adds a "Code" button redirecting to the specified link +- `poster`: Adds a "Poster" button redirecting to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory) +- `slides`: Adds a "Slides" button redirecting to a specified file (if a full link is not specified, the file will be assumed to be placed in the /assets/pdf/ directory) +- `website`: Adds a "Website" button redirecting to the specified link +- `altmetric`: Adds an [Altmetric](https://www.altmetric.com/) badge (Note: if DOI is provided just use `true`, otherwise only add the altmetric identifier here - the link is generated automatically) +- `dimensions`: Adds a [Dimensions](https://www.dimensions.ai/) badge (Note: if DOI or PMID is provided just use `true`, otherwise only add the Dimensions' identifier here - the link is generated automatically) + +You can implement your own buttons by editing the bib.html file. + +
+ +--- + +### Collections + +This Jekyll theme implements `collections` to let you break up your work into categories. +The theme comes with two default collections: `news` and `projects`. +Items from the `news` collection are automatically displayed on the home page. +Items from the `projects` collection are displayed on a responsive grid on projects page. + +

+ +You can easily create your own collections, apps, short stories, courses, or whatever your creative work is. +To do this, edit the collections in the `_config.yml` file, create a corresponding folder, and create a landing page for your collection, similar to `_pages/projects.md`. + +--- + +### Layouts + +**al-folio** comes with stylish layouts for pages and blog posts. + +#### The iconic style of Distill + +The theme allows you to create blog posts in the [distill.pub](https://distill.pub/) style: + +

+ +For more details on how to create distill-styled posts using `` tags, please refer to [the example](https://alshedivat.github.io/al-folio/blog/2021/distill/). + +#### Full support for math & code + +**al-folio** supports fast math typesetting through [MathJax](https://www.mathjax.org/) and code syntax highlighting using [GitHub style](https://github.com/jwarby/jekyll-pygments-themes): + +

+ + +

+ +#### Photos + +Photo formatting is made simple using [Bootstrap's grid system](https://getbootstrap.com/docs/4.4/layout/grid/). +Easily create beautiful grids within your blog posts and project pages: + +

+ + + +

+ +--- + +### Other features + +#### GitHub's repositories and user stats + +**al-folio** uses [github-readme-stats](https://github.com/anuraghazra/github-readme-stats) and [github-profile-trophy](https://github.com/ryo-ma/github-profile-trophy) +to display GitHub repositories and user stats on the `/repositories/` page. + +Edit the `_data/repositories.yml` and change the `github_users` and `github_repos` lists to include your own GitHub profile and repositories to the `/repositories/` page. + +You may also use the following codes for displaying this in any other pages. + +```html + +{% if site.data.repositories.github_users %} +
+ {% for user in site.data.repositories.github_users %} + {% include repository/repo_user.html username=user %} + {% endfor %} +
+{% endif %} + + +{% if site.repo_trophies.enabled %} +{% for user in site.data.repositories.github_users %} + {% if site.data.repositories.github_users.size > 1 %} +

{{ user }}

+ {% endif %} +
+ {% include repository/repo_trophies.html username=user %} +
+{% endfor %} +{% endif %} + + +{% if site.data.repositories.github_repos %} +
+ {% for repo in site.data.repositories.github_repos %} + {% include repository/repo.html repository=repo %} + {% endfor %} +
+{% endif %} +``` + +#### Theming + +A variety of beautiful theme colors have been selected for you to choose from. +The default is purple, but you can quickly change it by editing the +`--global-theme-color` variable in the `_sass/_themes.scss` file. +Other color variables are listed there as well. +The stock theme color options available can be found at `_sass/variables.scss`. +You can also add your own colors to this file assigning each a name for ease of +use across the template. + +#### Social media previews + +**al-folio** supports preview images on social media. +To enable this functionality you will need to set `serve_og_meta` to `true` in your `_config.yml`. +Once you have done so, all your site's pages will include Open Graph data in the HTML head element. + +You will then need to configure what image to display in your site's social media previews. +This can be configured on a per-page basis, by setting the `og_image` page variable. +If for an individual page this variable is not set, then the theme will fall back to a site-wide `og_image` variable, configurable in your `_config.yml`. +In both the page-specific and site-wide cases, the `og_image` variable needs to hold the URL for the image you wish to display in social media previews. + +#### Atom (RSS-like) Feed + +It generates an Atom (RSS-like) feed of your posts, useful for Atom and RSS readers. +The feed is reachable simply by typing after your homepage `/feed.xml`. +E.g. assuming your website mountpoint is the main folder, you can type `yourusername.github.io/feed.xml` + +#### Related posts + +By default, there will be a related posts section on the bottom of the blog posts. +These are generated by selecting the `max_related` most recent posts that share at least `min_common_tags` tags with the current post. +If you do not want to display related posts on a specific post, simply add `related_posts: false` to the front matter of the post. +If you want to disable it for all posts, simply set `enabled` to false in the `related_blog_posts` section in `_config.yml`. + +## Contributing + +Contributions to al-folio are very welcome! +Before you get started, please take a look at [the guidelines](CONTRIBUTING.md). + +If you would like to improve documentation, add your webpage to the list below, or fix a minor inconsistency or bug, please feel free to send a PR directly to `master`. +For more complex issues/bugs or feature requests, please open an issue using the appropriate template. + +### Maintainers + +Our most active contributors are welcome to join the maintainers team. +If you are interested, please reach out! + + + + + + + + + + + + + +

Maruan

Rohan Deb Sarkar

Amir Pourmand

George
+ + + + + + +## License + +The theme is available as open source under the terms of the [MIT License](https://github.com/alshedivat/al-folio/blob/master/LICENSE). + +Originally, **al-folio** was based on the [\*folio theme](https://github.com/bogoli/-folio) (published by [Lia Bogoev](https://liabogoev.com) and under the MIT license). +Since then, it got a full re-write of the styles and many additional cool features. diff --git a/_planning/migration-report.md b/_planning/migration-report.md new file mode 100644 index 0000000000000..c01a659915c19 --- /dev/null +++ b/_planning/migration-report.md @@ -0,0 +1,116 @@ +# Migration inventory and decisions + +## Academic refinement, 2026-09-09 + +Owner deferred AI education and requested an academic-first site. Homepage now +centers the verified role, PhD, research directions, recent news, four selected +papers with full authors and resources, and academic community contributions. +Research provides methods and scoped findings for six representative projects, +plus context for MetaIC and the benchmark position paper. Education and writing +remain available at their existing URLs without primary navigation promotion. + +Corrected the service migration: the previous dataset retained only 2021. The +dataset now includes all 20 original entries in five years (2021-2025), covered +by a regression test comparing rendered records to `_layouts/services.html`. + +Research provenance checked against public paper metadata and project READMEs: + +- SWE-ABS: https://arxiv.org/abs/2603.00520 (v1); filled all 12 authors and paper links. +- UTBoost: https://aclanthology.org/2025.acl-long.189/ and the UTBoost repository; + added proceedings, pages, DOI, and official PDF. +- Retromorphic: https://arxiv.org/abs/2310.06433; retained preprint status. +- ROME: https://arxiv.org/abs/2306.02228; TIN: https://arxiv.org/abs/2308.07937. +- LightAD: https://github.com/BoxiYu/LightAD and existing local publication metadata. +- Position paper: https://arxiv.org/abs/2501.10711v5; updated title and used its + 672-benchmark scope, preserving the citation key and historical news wording. + +No new employment dates, honors, courses, or CV were invented. The legacy example +PDF is not presented as a current CV. Venue acceptance remains based on the +owner's existing bibliography and announcements. + +Date: 2026-09-08 +Branch: codex/research-education-site +Baseline: 5b12a018464201cee4c0b2bf148779c425289b0d +Audience confirmed by owner: English technical readers, research interpretation +and engineering practice. + +## Migrated content + +| Source | Destination | Disposition | +| ---------------------------------------- | ------------------------------------- | ------------------------------------------------------------ | +| _pages/about.md | / and /about/ | Academic facts preserved; owner-confirmed AI education added | +| _bibliography/papers.bib | /publications/ and /papers.bib | All 11 records and citation anchors retained | +| assets/pdf/* | /assets/pdf/* | Every existing PDF retained byte-for-byte | +| assets/img/prof_pic.jpg | same path | Portrait reused | +| _news/*.md | /news/ and /news/announcement_N/ | All 8 announcements retained | +| _talks/utboost.md | /talks/ and /talks/utboost/ | One talk retained | +| _layouts/services.html | src/data/services.json and /services/ | Rendered 2021-2025 records migrated | +| _pages/teaching.md | /teaching/ | Four assistantships retained | +| /blog/, /blog/2022/, /blog/2023/, /2022/ | compatibility pages | Explicit links to /writing/ | +| /feed.xml | writing RSS | Published articles only | +| /sitemap.xml and /404.html | new sitemap and 404 | Current site equivalents | + +Old generated output includes theme/demo routes and repository source files. +Those are outside the retained personal content. Demo projects, example CV, +stock images, Distill scripts and my-awesome-site remain in source for reference +but are not shipped. Old generated image variants are not recreated; the canonical +portrait URL is retained. + +## New material + +- Research overview connects coding-agent evaluation, test oracles, and AI testing. +- Education provides a deterministic Python reasoning exercise. It does not claim + a course, workshop, student outcome, or live AI evaluation. +- Two English Markdown explainers are draft and excluded from production. +- Writing supports topic/search filtering, references, related reading, series, + per-article language, and Markdown/MDX authoring. +- Responsive layouts, self-hosted Latin fonts, metadata, RSS, and a social card. + +## Editorial follow-ups + +- Review the homepage positioning, education explanation, and two draft explainers. +- SWE-ABS retains the incomplete source author list and has no resource link in + source. Add verified authors/resources when available. +- Corrected TIN's Code link to https://github.com/RobustNLP/TestNER and ROME's to + https://github.com/RobustNLP/TestIC after checking both official repository READMEs. +- No current CV was supplied. The old CV points to example_pdf.pdf, which is not + presented as the owner's CV in the redesign. +- The academic contact email is unchanged from source; update it if needed. + +## Design rationale + +White, ink blue, and cobalt support technical reading. Source Serif 4 carries the +main question; Source Sans 3 carries explanations and navigation. The small test +experiment connects research to education and serves as the memorable element. + +```text +Name Research Writing Education About +Research + education positioning Portrait +Investigate Understand Experiment +Why passing tests can mislead Interactive example +Two editorial selections (released posts only in production) +Three research highlights +Two recent updates + archive +Contact and research profiles +``` + +## Release state + +Local implementation and preview only. No commit, push, or production deployment. +Verification completed locally: + +- Astro type checks: zero errors, warnings, or hints. +- Production build: 24 pages, with no draft routes or content. +- Five integration tests: publication/author/citation/PDF preservation; all generated + internal links and fragments; draft exclusion; legacy routes; isolated Markdown + and MDX publishing including RSS, series links, and future-date exclusion. +- Browser layout checks: homepage, publications, education, writing index, and + article at 360, 390, 768, and 1440 px; no horizontal overflow or broken images. +- Browser interaction checks: topic and text filtering, no-match states, keyboard + operation and reset of the teaching example, and readable article layout. +- No browser console errors observed during those checks. +- Dependency audit: zero known vulnerabilities at validation time. + +The Pages workflow is prepared but has not run remotely; production hosting and +external resource availability beyond the two corrected repositories are not +validated by these local checks. Review the real site before release. diff --git a/_planning/site-refinement-plan.md b/_planning/site-refinement-plan.md new file mode 100644 index 0000000000000..7956d0e34c646 --- /dev/null +++ b/_planning/site-refinement-plan.md @@ -0,0 +1,195 @@ +# Personal Website Refinement Plan + +Date: 2026-09-08 +Status: locally implemented on codex/research-education-site; release review pending + +Owner confirmed the first audience as English technical readers, focusing on +research interpretation and engineering practice. See migration-report.md for +implementation scope and verification, and ../WEBSITE.md for authoring instructions. + +## Objective + +Build a personal website that connects Boxi Yu's research, AI education work, +and public writing. Readers should quickly understand his focus, find credible +research, discover accessible explanations, and follow a useful learning path. + +Working editorial theme: understanding, using, and evaluating AI reliably. +This is a proposed framing, not a confirmed description of the education work. + +## Working Assumptions + +- Academic peers need English research information and direct publication access. +- Writing may be Chinese or English; support per-article language without requiring + every article to be translated or building duplicate empty language sites. +- Initial education audiences and existing materials still need to be established. + Do not invent courses, teaching results, testimonials, enrollment, or metrics. +- Keep the existing GitHub Pages domain and preserve public resource URLs. +- Recommend Astro static output with Markdown, optional MDX, and custom CSS. + Validate this choice in the prototype before migrating the whole site. +- Planning does not authorize publishing, replacing the live site, or removing + existing content. Prepare a concrete preview before the production cutover. + +## Current Findings + +- Jekyll/al-folio homepage prioritizes biography and news over research or writing. +- Nine of eleven bibliography records are selected for the homepage. +- Publications reuse the theme's year-heading class for topic names, producing + visibly overlapping headings on the live page. +- Contact links appear after the selected publication list; the footer is fixed. +- Writing is disabled on the homepage, while template blog configuration remains. +- Teaching lists historical assistantships, distinct from the new AI education work. +- Some publication records lack complete author or resource metadata. Audit before + presenting them in the new design; absence does not justify inventing links. +- The repository contains template examples and overlapping sources of content. + Establish which data actually renders before migration or cleanup. + +## Information Architecture + +Primary navigation: Home, Research, Writing, Education, About. +Provide prominent Publications and CV links without requiring menu discovery. + +| Route | Purpose | First release content | +| --- | --- | --- | +| / | Introduce the person and guide both audiences | Positioning, writing, research, education, contact | +| /research/ | Explain connected research questions | Three representative projects and publication link | +| /publications/ | Complete scholarly record | All existing papers, dates, resources, citations | +| /writing/ | Discover individual articles | Featured posts, chronological list, topic navigation | +| /writing// | Read and share an article | Readable content, references, related or series links | +| /education/ | Follow structured learning | Real learning paths, course/workshop resources if available | +| /about/ | Background and professional information | Biography, CV if current, service, talks, teaching, contact | + +If there is no complete educational resource, integrate the initial learning +series into Writing and defer the standalone Education navigation item. +Do not launch empty sections to match a sitemap. + +Retain existing /talks/, /services/, /teaching/, /news/ and detail URLs as useful +archive pages or explicit static compatibility pages. Keep publication fragment +IDs and assets/pdf resource paths where feasible. GitHub Pages does not provide +arbitrary server-side redirects; verify any static redirect approach separately. + +## Homepage and Visual Direction + +Proposed order: identity and short positioning; direct audience entry links; +selected writing; education resource; selected research; compact news/contact. +Keep a direct Publications link in the opening section. If an imminent academic +application becomes the primary goal, move research before writing. + +- Display 2-3 selected articles and 2-3 research highlights, not exhaustive lists. +- First-screen copy connects research and education without overstating either. +- Preserve a human portrait; remove the heavy portrait shadow and fixed footer. +- Use method diagrams and concrete examples as visual identity, not stock AI art. +- Initial palette: white #FFFFFF, pale blue-grey #F3F6FA, ink #243247, + cobalt #2454C6, secondary text #536176, border #D8E0EA. Check contrast in use. +- Prototype Source Sans 3 with Source Serif 4 for English; evaluate Noto Sans SC + with selective Noto Serif SC for Chinese, including font payload and fallbacks. +- Keep prose at roughly 65-75 Latin characters per line; validate Chinese line + length independently. Use a single column on phones and a restrained desktop grid. +- Use clear focus styles and respect reduced motion. Core reading needs no animation. + +## Content Model and Editorial Workflow + +Articles: title, stable slug, description, publishedAt, optional updatedAt, +language, topics, audience, optional series/order, draft, featured, references, +and optional translation relationship. Keep display labels human-readable. + +Education paths: title, intended audience, prerequisites, learning outcomes, +ordered references to existing articles/materials, and exercises where available. +An article can belong to a path without duplicating its content. + +Research: retain BibTeX as the bibliographic source; add project summaries, +verified findings, diagrams, related paper keys, and explicit display priority in +separate structured metadata. Validate missing or duplicate references at build time. + +Writing workflow: create a Markdown draft, preview locally, check references and +examples, publish through the repository, and update RSS and sitemap automatically. +Use MDX only for content needing an interactive component. Drafts must be excluded +from public pages, feeds, search indexes, and sitemaps. + +## Delivery Phases + +### Phase 1: Content and URL Inventory + +- Inventory existing routes, anchors, papers, PDF/slides, portrait, news and talks. +- Identify live content sources, template-only content, and metadata needing repair. +- Establish the education audience and collect existing drafts or teaching material. +- Select 2-3 research highlights, up to 3 real launch articles, and one learning + series if available. Treat these as editorial targets, not fabricated launch content. +- Draft positioning and a keep/move/archive mapping for existing pages. + +Deliverables: content inventory, URL compatibility map, first-release sitemap, +and copy outline. Complete when every live resource has a migration disposition +and missing user-owned facts are explicitly recorded. + +### Phase 2: Real-Content Prototype + +- Create an isolated codex/ branch and build a local Astro prototype. +- Prototype homepage, article page, and research/publication presentation. +- Use an actual draft if available; otherwise clearly mark sample prose as a + prototype fixture and exclude it from production output. +- Compare desktop and phone layouts, Chinese and English reading, navigation, + long titles, figures, code blocks, and scholarly citations. +- Review the design against the actual research and education material; revise + generic or decorative elements before extending the design to all routes. + +Deliverables: runnable preview and inspected desktop/mobile views. Complete when +the audience entry points, hierarchy, reading experience, and stack fit are clear. + +### Phase 3: Content Platform and Migration + +- Implement validated content collections and reusable article/project layouts. +- Import all bibliography entries; preserve citation keys and resource paths. +- Implement Writing, series navigation, and Education when content supports it. +- Migrate background, service, talks and news into their planned destinations. +- Add RSS, sitemap, canonical URLs, per-page language, social previews, and a 404. +- Add topic navigation first; introduce static search when the article inventory + makes it useful. Search must handle Chinese and English content if both exist. +- Replace template dependencies and examples only after migration parity is checked. + +Deliverable: complete local site and migration report. Complete when all retained +content is accessible and one new article can be added without editing layout code. + +### Phase 4: Verification and Release Preparation + +- Run the production build and check internal links, fragments, asset references, + duplicate slugs, series ordering, and draft exclusion from generated artifacts. +- Inspect representative pages at 360, 390, 768, and 1440 px widths; check long + Chinese/English titles, tables, code, portrait, bibliography, and navigation. +- Verify keyboard navigation, visible focus, contrast, image alternative text, + zoom/reflow, and reduced motion. Scope horizontal scrolling to wide code/tables. +- Verify article metadata, RSS links, canonical URLs, and old inbound URLs. +- Measure production-build loading and layout stability; optimize actual bottlenecks. + Keep non-interactive routes free of unnecessary hydrated UI and external font bloat. +- Prepare the GitHub Pages workflow, preview diff, retained old deployment/ref, + and documented rollback procedure. PR validation must not publish to production. +- Obtain release authorization for the concrete preview before switching production. + +Deliverables: reviewable release, verification results, compatibility report, +and rollback instructions. After an authorized deployment, smoke-check live routes. + +### Phase 5: Ongoing Publishing + +- Publish one coherent learning series before expanding topic taxonomy. +- Connect articles to relevant research and educational resources. +- Review navigation after enough content exists to observe real discovery problems. +- Add search, subscriptions, or richer interactive examples only for established needs. + +## First Release Boundaries + +Include: a coherent homepage, research and full publications, a dependable writing +workflow, content-backed education, background/contact, responsive reading, +basic discovery and sharing, and preserved inbound links. + +Defer: accounts, paid courses, learning progress, comments, automatic translation, +newsletter provider integration, custom CMS, AI chat, elaborate animation, and +large interactive demos. RSS provides a subscription option without a new service. + +## Decisions to Resolve Before Dependent Work + +1. Who is the first education audience, and what should they learn to do? +2. Is the writing primarily Chinese, English, or mixed? +3. Which drafts, courses, workshops, or learning materials already exist? +4. Is academic recruitment, educational reach, or collaboration the near-term priority? + +Inventory, URL mapping, publication cleanup proposals, and layout scaffolding can +proceed while these are unresolved. Public education claims, final homepage order, +and launch content depend on the answers. diff --git a/astro.config.mjs b/astro.config.mjs new file mode 100644 index 0000000000000..97ea520cf9152 --- /dev/null +++ b/astro.config.mjs @@ -0,0 +1,11 @@ +import { defineConfig } from 'astro/config'; +import mdx from '@astrojs/mdx'; + +export default defineConfig({ + site: 'https://boxiyu.github.io', + output: 'static', + trailingSlash: 'always', + devToolbar: { enabled: false }, + integrations: [mdx()], + markdown: { shikiConfig: { theme: 'github-light' } }, +}); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000000..2ed38e39261c8 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,5896 @@ +{ + "name": "boxi-yu-website", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "boxi-yu-website", + "version": "1.0.0", + "dependencies": { + "@astrojs/mdx": "8.0.1", + "@astrojs/rss": "^4.0.19", + "@fontsource/source-sans-3": "^5.3.0", + "@fontsource/source-serif-4": "^5.3.0", + "astro": "7.3.2", + "bibtex-parse-js": "0.0.23", + "gray-matter": "^4.0.3", + "marked": "^18.0.12" + }, + "devDependencies": { + "@astrojs/check": "^0.9.10", + "@types/node": "^26.5.0", + "cheerio": "^1.2.0", + "prettier": "^3.9.6", + "prettier-plugin-astro": "^0.14.1", + "sharp": "^0.35.4", + "typescript": "^5.9.3" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/@astrojs/check": { + "version": "0.9.10", + "resolved": "https://registry.npmjs.org/@astrojs/check/-/check-0.9.10.tgz", + "integrity": "sha512-zgx/UQMozdjOa3bOxjgeCFdtpE3c9rRX6xHwa+2QXvy8z8Akifu2AtubHyv/zzC2znO8dl8fFWL4K+Ba9kS8HQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@astrojs/language-server": "^2.16.7", + "chokidar": "^4.0.3", + "kleur": "^4.1.5", + "yargs": "^18.0.0" + }, + "bin": { + "astro-check": "bin/astro-check.js" + }, + "peerDependencies": { + "typescript": "^5.0.0 || ^6.0.0" + } + }, + "node_modules/@astrojs/check/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@astrojs/check/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@astrojs/check/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/@astrojs/compiler": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/@astrojs/compiler/-/compiler-2.13.1.tgz", + "integrity": "sha512-f3FN83d2G/v32ipNClRKgYv30onQlMZX1vCeZMjPsMMPl1mDpmbl0+N5BYo4S/ofzqJyS5hvwacEo0CCVDn/Qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@astrojs/compiler-binding": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding/-/compiler-binding-0.4.0.tgz", + "integrity": "sha512-x2RjDUuWfwLNtc3mjAdSRInwqh/rqbLar9cm/5FOMbHvmYZB7yfKewzSclAxWjIZsypJDXv1lhaP2WG+P8TK3g==", + "license": "MIT", + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@astrojs/compiler-binding-darwin-arm64": "0.4.0", + "@astrojs/compiler-binding-darwin-x64": "0.4.0", + "@astrojs/compiler-binding-linux-arm64-gnu": "0.4.0", + "@astrojs/compiler-binding-linux-arm64-musl": "0.4.0", + "@astrojs/compiler-binding-linux-x64-gnu": "0.4.0", + "@astrojs/compiler-binding-linux-x64-musl": "0.4.0", + "@astrojs/compiler-binding-wasm32-wasi": "0.4.0", + "@astrojs/compiler-binding-win32-arm64-msvc": "0.4.0", + "@astrojs/compiler-binding-win32-x64-msvc": "0.4.0" + } + }, + "node_modules/@astrojs/compiler-binding-darwin-arm64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-darwin-arm64/-/compiler-binding-darwin-arm64-0.4.0.tgz", + "integrity": "sha512-ZVUwHundaQyFNjE6uoa0usaC0WOCitDCLS/4mdb4rOiJXwVUuKJBMxI5WMzXLWmamsXtK/Z//ifLXvV5Yeh4Hw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-darwin-x64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-darwin-x64/-/compiler-binding-darwin-x64-0.4.0.tgz", + "integrity": "sha512-FI6G8AY8u6fR1SI/QRR5yGMwtvZwP34CDmZpZ5HwJGa50UM1VISTLhqkhV4a476pmgd25X1Aur2dqw6hUnrlKA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-linux-arm64-gnu": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-arm64-gnu/-/compiler-binding-linux-arm64-gnu-0.4.0.tgz", + "integrity": "sha512-lB9gLFJK7m82EnjaU8nlRBEfcwGNeHidW3sSjODTUjMNaoewVuUz9fwwdY5M4jiSXIqWLH3yl6TX8FTDKA74Sw==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-linux-arm64-musl": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-arm64-musl/-/compiler-binding-linux-arm64-musl-0.4.0.tgz", + "integrity": "sha512-HPbvWqbxFxyaoQJhLxCaSjtYBx9KBo7JGVzEFZCmMl968a2PsSH0UfiODYgYPXofTOIsIH2aoCcrHXML0IA3ig==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-linux-x64-gnu": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-x64-gnu/-/compiler-binding-linux-x64-gnu-0.4.0.tgz", + "integrity": "sha512-tQKolMxoJ/+0AmLWm1PmJ/i+z3i10ZU1bNuVjEDulCf48azEMtUNjTZgHJ5MPtpYRNc7dlETr8QujUfduzoC7Q==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-linux-x64-musl": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-linux-x64-musl/-/compiler-binding-linux-x64-musl-0.4.0.tgz", + "integrity": "sha512-5v5YymudsxMHp3NBLCS8BUlu5CRqeLtWD9cKS/4nIhIEHCbpz9okmVV6I0HWqmBAPhWYcDa3vw/vltYPrOQCTA==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-wasm32-wasi": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-wasm32-wasi/-/compiler-binding-wasm32-wasi-0.4.0.tgz", + "integrity": "sha512-m/phuH3x3PREvv1OnkM44NoPh4MatUadix1fB1u5SvMLCyDTUZykDJbKnWf1cjnYmHdlB8HcjTjl6JrCqAIXcw==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.2.2" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@astrojs/compiler-binding-win32-arm64-msvc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-win32-arm64-msvc/-/compiler-binding-win32-arm64-msvc-0.4.0.tgz", + "integrity": "sha512-B9zYf3okEY83kM8gydlpH2BHP00w4ifxPqlYlWrgTwuD6wnkrJDCwBlgy1q31cERjCJRXN1lrE2VmkLvFjv/6g==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-binding-win32-x64-msvc": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-binding-win32-x64-msvc/-/compiler-binding-win32-x64-msvc-0.4.0.tgz", + "integrity": "sha512-zB0Nrv0dGc0zZWPGDRmmETTPhDRqyZjAjk+gWMlVrJX5U89obpB3VUUE1ZiHxOCN5LQojeLK6O8L/dnoHolvNQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@astrojs/compiler-rs": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@astrojs/compiler-rs/-/compiler-rs-0.4.0.tgz", + "integrity": "sha512-koVikeon1kreEy+/JzLQRy3vzHHQVOjycs4degg4vFufKApZOwMZvSSAEztYNhmcQVfNVsVZZI4cEge3cexAbQ==", + "license": "MIT", + "dependencies": { + "@astrojs/compiler-binding": "0.4.0" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/@astrojs/internal-helpers": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@astrojs/internal-helpers/-/internal-helpers-0.11.0.tgz", + "integrity": "sha512-3rzxJ+xbo0+8YyqOzLziIN32wmsHdCjEVz2sGOpRxJ+Ben/KiLph4ItxBy1abEL+E8fkRzqjg0rfXmaHJGw9JA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.4", + "@types/mdast": "^4.0.4", + "js-yaml": "^4.3.0", + "picomatch": "^4.0.4", + "retext-smartypants": "^6.2.0", + "shiki": "^4.0.2", + "smol-toml": "^1.6.0", + "unified": "^11.0.5" + } + }, + "node_modules/@astrojs/language-server": { + "version": "2.16.16", + "resolved": "https://registry.npmjs.org/@astrojs/language-server/-/language-server-2.16.16.tgz", + "integrity": "sha512-KuS17AOOqH/M5mHXPmKvtp8L+NNteARC7Xjf395+9R9dtJOBndqdStwU4V+OKzYZpgZ+hliV13knzx/oMtFl7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.13.1", + "@astrojs/yaml2ts": "^0.2.4", + "@jridgewell/sourcemap-codec": "^1.5.5", + "@volar/kit": "~2.4.28", + "@volar/language-core": "~2.4.28", + "@volar/language-server": "~2.4.28", + "@volar/language-service": "~2.4.28", + "muggle-string": "^0.4.1", + "tinyglobby": "^0.2.16", + "volar-service-css": "0.0.71", + "volar-service-emmet": "0.0.71", + "volar-service-html": "0.0.71", + "volar-service-prettier": "0.0.71", + "volar-service-typescript": "0.0.71", + "volar-service-typescript-twoslash-queries": "0.0.71", + "volar-service-yaml": "0.0.71", + "vscode-html-languageservice": "^5.6.2", + "vscode-uri": "^3.1.0" + }, + "bin": { + "astro-ls": "bin/nodeServer.js" + }, + "peerDependencies": { + "prettier": "^3.0.0", + "prettier-plugin-astro": ">=0.11.0" + }, + "peerDependenciesMeta": { + "prettier": { + "optional": true + }, + "prettier-plugin-astro": { + "optional": true + } + } + }, + "node_modules/@astrojs/markdown-satteri": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@astrojs/markdown-satteri/-/markdown-satteri-0.4.1.tgz", + "integrity": "sha512-EniHbFNa6SQHDih7JnpPos3NWXO6hdt4raBcOosfGmlfc3gP9CI/sESA3VOf1PgJZ7SFfewlZW9Livn0JugEZg==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.11.0", + "@astrojs/prism": "4.0.2", + "github-slugger": "^2.0.0", + "satteri": "^0.10.3" + } + }, + "node_modules/@astrojs/mdx": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@astrojs/mdx/-/mdx-8.0.1.tgz", + "integrity": "sha512-VKodp/f3+XE6L0950K+ZOAolY47vdt0R78Ao+L2RdJ1hfAdYffL7IEjc/MsoyuS7CPVvCsd5/I3RP0ZyAIewdQ==", + "license": "MIT", + "dependencies": { + "@astrojs/internal-helpers": "0.11.0", + "@astrojs/markdown-satteri": "0.4.1", + "es-module-lexer": "^2.0.0" + }, + "engines": { + "node": ">=22.12.0" + }, + "peerDependencies": { + "@astrojs/markdown-remark": "^7.3.0", + "@astrojs/markdown-satteri": "^0.4.0", + "astro": "^7.2.6" + }, + "peerDependenciesMeta": { + "@astrojs/markdown-remark": { + "optional": true + } + } + }, + "node_modules/@astrojs/prism": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@astrojs/prism/-/prism-4.0.2.tgz", + "integrity": "sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA==", + "license": "MIT", + "dependencies": { + "prismjs": "^1.30.0" + }, + "engines": { + "node": ">=22.12.0" + } + }, + "node_modules/@astrojs/rss": { + "version": "4.0.19", + "resolved": "https://registry.npmjs.org/@astrojs/rss/-/rss-4.0.19.tgz", + "integrity": "sha512-e+z5wYeYtffQdHQO8c2tkSd2JEBdAuRXJV4ZEU5IxkYeE6e39woDd7nw1PH1Kk2tEYNCYuKdylnnbhGmt61awA==", + "license": "MIT", + "dependencies": { + "fast-xml-parser": "^5.5.7", + "piccolore": "^0.1.3", + "zod": "^4.3.6" + } + }, + "node_modules/@astrojs/telemetry": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@astrojs/telemetry/-/telemetry-3.3.3.tgz", + "integrity": "sha512-C1TLn5sPJr0x4vk56piHWKbnqlEB8BKyte5Y45V02U+D7BGO5eMqZDH5aPjnkXQWJggvmsTXxH03QMZ9NgWLzQ==", + "license": "MIT", + "dependencies": { + "ci-info": "^4.4.0", + "dset": "^3.1.4", + "is-docker": "^4.0.0", + "package-manager-detector": "^1.6.0" + }, + "engines": { + "node": "18.20.8 || ^20.3.0 || >=22.0.0" + } + }, + "node_modules/@astrojs/yaml2ts": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@astrojs/yaml2ts/-/yaml2ts-0.2.4.tgz", + "integrity": "sha512-8oddpOae35pJsXPQXhTkM0ypfKPskVsh2bCxRtbf7e+/Epw2nReakFYpLKjZMEr75CsoF203PMnCocpfz0s69A==", + "dev": true, + "license": "MIT", + "dependencies": { + "yaml": "^2.8.3" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz", + "integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz", + "integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.29.8" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/types": { + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bruits/satteri-darwin-arm64": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-darwin-arm64/-/satteri-darwin-arm64-0.10.5.tgz", + "integrity": "sha512-27KTVl4TJkVahMy/ohyA7qd4938G5UNneFUz/PsScYfpIhj0IVAS23mpcJXdPF44sa6nva198lmV/cKIb2YPyA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@bruits/satteri-darwin-x64": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-darwin-x64/-/satteri-darwin-x64-0.10.5.tgz", + "integrity": "sha512-IjnLe3nKspq6qaeqGgjT7MT8VrTV74yWRlaag7ZdNsI8TDAYZ0iPxMCo+9KQZHUk5EyVB+reBI/PFWL5KuFw9Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@bruits/satteri-linux-arm64-gnu": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-linux-arm64-gnu/-/satteri-linux-arm64-gnu-0.10.5.tgz", + "integrity": "sha512-glkYXZCJywjP13v67eAyAMSJdF+ncvEbYvgi/wOtffL9tQ27lr/zsyzUfgs+ovjJ9d8JNQKiXeiArJcX8PJL9w==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@bruits/satteri-linux-arm64-musl": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-linux-arm64-musl/-/satteri-linux-arm64-musl-0.10.5.tgz", + "integrity": "sha512-yWdgG1g17Nh2QyGVlFUxGRa3FEFwiMcpZEyMNWkbM3deC94cmVc+/i9OuyFpdKuWo3GkgoCtYVOoxk1uCnCZIA==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@bruits/satteri-linux-x64-gnu": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-linux-x64-gnu/-/satteri-linux-x64-gnu-0.10.5.tgz", + "integrity": "sha512-FVaLoPT1fBgGl0J+AYebyyXJYBachGl8Oyyrf1lye4RTqCB4S0Gwkj1uM9RJyThUOvx5VUmAT1CnNh1SFHA+kw==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@bruits/satteri-linux-x64-musl": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-linux-x64-musl/-/satteri-linux-x64-musl-0.10.5.tgz", + "integrity": "sha512-EHpVAx2bqW3GINHTKkljtxVfQmVDGWIuwOYOP5YghTj+0PkBa2o8oKPRtQ9Kbsr1Fye8jtUcDjhwj2jMNugZKg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@bruits/satteri-wasm32-wasi": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-wasm32-wasi/-/satteri-wasm32-wasi-0.10.5.tgz", + "integrity": "sha512-ypz8c/Zmipxp4IoeDa228Gstv6TLzVmNs3yC6wKCoNSOjx1iwpgzu87Y3hTkXFdwChVGU85qeUDuOIarGUZQLw==", + "cpu": [ + "wasm32" + ], + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.11.1", + "@emnapi/runtime": "1.11.1", + "@napi-rs/wasm-runtime": "^1.2.3" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@bruits/satteri-wasm32-wasi/node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@bruits/satteri-wasm32-wasi/node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@bruits/satteri-wasm32-wasi/node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@bruits/satteri-win32-arm64-msvc": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-win32-arm64-msvc/-/satteri-win32-arm64-msvc-0.10.5.tgz", + "integrity": "sha512-siTV88nb0LRqNpkL2gXboqCwVdq95sLtzMHS1/3eONV2gLbB3NAK46wmSMvCO/yquBvI2lvaFIfd8P12ecsxBw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@bruits/satteri-win32-x64-msvc": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/@bruits/satteri-win32-x64-msvc/-/satteri-win32-x64-msvc-0.10.5.tgz", + "integrity": "sha512-C3IfPvfvMXmlzBxaMPKFS1XiuV9pu2mC7YqkPk7PSvTgPZ8gbdASIpHpztDLvTTQjqZ0z1Ol8tK5X+V6XXC0wQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@capsizecss/unpack": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@capsizecss/unpack/-/unpack-4.0.1.tgz", + "integrity": "sha512-CuNiSqg7+e1cO/GjffyMOm5Tt2jUF9CWHHnvQ/UkqvtkGfHdgwEC0wpmq7fkN3gxwpRnrAN0WzO3vREKmNolMQ==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@clack/core": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@clack/core/-/core-1.5.0.tgz", + "integrity": "sha512-zNikCcd8BbcEvzzG1sbXFrRHFk5kHPrpwZwksPvf9qyQO1Teb7JaXaOAxXZei9nZLDW0gaZawiuTCji88bTBhw==", + "license": "MIT", + "dependencies": { + "fast-wrap-ansi": "^0.2.0", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 20.12.0" + } + }, + "node_modules/@clack/prompts": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@clack/prompts/-/prompts-1.8.0.tgz", + "integrity": "sha512-PXzLZ8N34rxmuo4dJg3xtOXhcBse94qGjDqsteoEYrFrrZ5FSjIGwMAuOcv64ln8rHVBBD06XeVGr+/JX+plcA==", + "license": "MIT", + "dependencies": { + "@clack/core": "1.5.0", + "fast-string-width": "^3.0.2", + "fast-wrap-ansi": "^0.2.0", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 20.12.0" + } + }, + "node_modules/@emmetio/abbreviation": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@emmetio/abbreviation/-/abbreviation-2.3.3.tgz", + "integrity": "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emmetio/scanner": "^1.0.4" + } + }, + "node_modules/@emmetio/css-abbreviation": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/@emmetio/css-abbreviation/-/css-abbreviation-2.1.8.tgz", + "integrity": "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emmetio/scanner": "^1.0.4" + } + }, + "node_modules/@emmetio/css-parser": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@emmetio/css-parser/-/css-parser-0.4.1.tgz", + "integrity": "sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emmetio/stream-reader": "^2.2.0", + "@emmetio/stream-reader-utils": "^0.1.0" + } + }, + "node_modules/@emmetio/html-matcher": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@emmetio/html-matcher/-/html-matcher-1.3.0.tgz", + "integrity": "sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@emmetio/scanner": "^1.0.0" + } + }, + "node_modules/@emmetio/scanner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@emmetio/scanner/-/scanner-1.0.4.tgz", + "integrity": "sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@emmetio/stream-reader": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@emmetio/stream-reader/-/stream-reader-2.2.0.tgz", + "integrity": "sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@emmetio/stream-reader-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/@emmetio/stream-reader-utils/-/stream-reader-utils-0.1.0.tgz", + "integrity": "sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@emnapi/core": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.3.tgz", + "integrity": "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.3.tgz", + "integrity": "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==", + "license": "MIT", + "optional": true, + "peer": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.2.tgz", + "integrity": "sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.2.tgz", + "integrity": "sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.2.tgz", + "integrity": "sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.2.tgz", + "integrity": "sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.2.tgz", + "integrity": "sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.2.tgz", + "integrity": "sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.2.tgz", + "integrity": "sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.2.tgz", + "integrity": "sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.2.tgz", + "integrity": "sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.2.tgz", + "integrity": "sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.2.tgz", + "integrity": "sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.2.tgz", + "integrity": "sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.2.tgz", + "integrity": "sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.2.tgz", + "integrity": "sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.2.tgz", + "integrity": "sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==", + "cpu": [ + "riscv64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.2.tgz", + "integrity": "sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==", + "cpu": [ + "s390x" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.2.tgz", + "integrity": "sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.2.tgz", + "integrity": "sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.2.tgz", + "integrity": "sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.2.tgz", + "integrity": "sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.2.tgz", + "integrity": "sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.2.tgz", + "integrity": "sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.2.tgz", + "integrity": "sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.2.tgz", + "integrity": "sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.2.tgz", + "integrity": "sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.2.tgz", + "integrity": "sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@fontsource/source-sans-3": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource/source-sans-3/-/source-sans-3-5.3.0.tgz", + "integrity": "sha512-VrWixSgF93kOVSEkwjs9ImnAbxrBew4PgcnaJYEitG9TyJSwxjFUNJIgzB1XFP/acyAWcTDg7+sWe7JI8LTB9w==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@fontsource/source-serif-4": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource/source-serif-4/-/source-serif-4-5.3.0.tgz", + "integrity": "sha512-yQz8xmIgMzks8zQbpuca3UYtjxK798XCyQAGdDXmzBgvV7sdoK6d0YvE9F9kiYxORCEMRBgGZDZsSYcXj5KvwA==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz", + "integrity": "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.3.3" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz", + "integrity": "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.3.3" + } + }, + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz", + "integrity": "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==", + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "dependencies": { + "@img/sharp-wasm32": "0.35.4" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz", + "integrity": "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz", + "integrity": "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz", + "integrity": "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz", + "integrity": "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz", + "integrity": "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz", + "integrity": "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz", + "integrity": "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz", + "integrity": "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz", + "integrity": "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz", + "integrity": "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz", + "integrity": "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==", + "cpu": [ + "arm" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz", + "integrity": "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz", + "integrity": "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz", + "integrity": "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==", + "cpu": [ + "riscv64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz", + "integrity": "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz", + "integrity": "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.3.3" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz", + "integrity": "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz", + "integrity": "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.3.3" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz", + "integrity": "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==", + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.3" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz", + "integrity": "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/sharp-wasm32": "0.35.4" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz", + "integrity": "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz", + "integrity": "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz", + "integrity": "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", + "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "license": "MIT" + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.3.tgz", + "integrity": "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==", + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" + } + }, + "node_modules/@nodable/entities": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-3.0.0.tgz", + "integrity": "sha512-8L9xFeTYKhm49xfIypoe2W5wV1m/3Z58kT+7kR9A8OyFxcPduI4VmxaUMQyKYrRjUoLLSXv6EKKID5Tvj9cUVw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/nodable" + } + ], + "license": "MIT" + }, + "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/@oxc-project/types": { + "version": "0.148.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.148.0.tgz", + "integrity": "sha512-Nm4s/jB+4FpFsPhWGEC4h7rzksesmtnMXomo6rCMcg/b8zLQuOziRgkCS1fxDCXOlJB/6Q8oABOZ/OP6RIPj9A==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/oxc-project" + } + }, + "node_modules/@rolldown/binding-android-arm-eabi": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.7.tgz", + "integrity": "sha512-EypzgnYCwyVY4NDHKzGmNJT5b+XaQEBniHxsMdeIQLB/tcCzZnhqrzHpZFbX9iaxx+5RiB8caATBtfvZP7zVxQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.7.tgz", + "integrity": "sha512-l17HE9EweWaqJZhuUuNBN/FzM62xw+DECVnJyvMsxn8vJFAGLy5QfLDoYAcronkAN8VxKZHezDpulHDPx95vFw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.7.tgz", + "integrity": "sha512-8ED8ELFvHXc6OCETIn4gXObPiaR6bckM/ipXtbzlPVDRMBfEGjCKgO90F9YtfdpDatVx/ZQw7aZ1vUMf/+T3Mw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.7.tgz", + "integrity": "sha512-/WPripjtiAIZ2tWY7ddijORT0Ujg87wxWW/qcoFVCKAWVDPhtY0xr7Dj0M3GyNGz60jGwTElhro/mkF9dT7dDQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.7.tgz", + "integrity": "sha512-14DI4NcqpvbICxSnGLx3PmtDaWqRP/KGSGb6C+JLLVPeZRl6dKdHba3pGsqT3vpdTqhEYIPG0MMQ8c0xYqoJxA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.7.tgz", + "integrity": "sha512-bxrWIRvHWQvbJwi+VIie/kDJmQxcNE6xxWwZdqF/ExVAigtHkv54WTLQPb+QsZdnFy18fg7JPfWGL0RH6vwIlQ==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.7.tgz", + "integrity": "sha512-toOY2BChBZyuxU7OYX6Tn389di4IzAqPTycVcci0O7FSfBqzRB3RZn+K5Is6ANf4tmgRd/K1yZTsNTXbkXsnLg==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.7.tgz", + "integrity": "sha512-lAIXTH/aiLRLxsTgQvfhjo4K1ydWIp00+V0voOr9beb/9ZmkUFrSIb03dXNFRgMNvkE6oGsF10ioQ6UsI+vS5Q==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.7.tgz", + "integrity": "sha512-kdnwS28Pkenp/mZMRwjXXXwxQ7pIsm+bF919LUK93BOyhcLsrVKdP2p9fxpiPNPAbNuch8ypQt0pm2P2LYCAGg==", + "cpu": [ + "ppc64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.7.tgz", + "integrity": "sha512-516OdsyLdr5E65paF3yBF55t8mfm9+gmtCsK3xI7XKXIT7EfRlHhxL8K/NR6Hu8BWSgF5+1w74lTL0+nxcc8Qw==", + "cpu": [ + "s390x" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.7.tgz", + "integrity": "sha512-r8/z8n7GFaYRln3xmP1Cxy0HH/HLM0uBUPkEuSVEfKGDA89M0FsZRZJRSwe/tJjRx+fpH/gjorfhB8tmEbSFLA==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.7.tgz", + "integrity": "sha512-pAsE8iiDxUg1xBqdhrTfg45AVDVpirjz00sblEYClGNNcMnDb+e8beQgqIAw6LvauX/APvgxUnwrgun/YYGBhw==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.7.tgz", + "integrity": "sha512-lTcIYmmnQQA8Or/2DatS6oSqcdLHvendjS+zLu+FwgToynWMRSmQdpM65fTANJgIS4mjbMOo5KT2lnT9SAb96w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.7.tgz", + "integrity": "sha512-e3Gu3WxbNk/UqQhxqU7YIYO+9ZBvWNz3U+h/qRFosscMFzdRPbXYSaSWgSnklv2fz1TgzBTcti2z35c/7irsHw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.7.tgz", + "integrity": "sha512-W/jg5qoRSqjsEv0+dZi4e687mcHqmVuU0P4fK6qS/xjetW2Gmc1W8j//z5nAeNcC8Ttm0hV46IjcYeuVwYhuiw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "license": "MIT" + }, + "node_modules/@shikijs/core": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/core/-/core-4.4.3.tgz", + "integrity": "sha512-QCR4q2ZO/ILJEuwiBMel4wdcTDb1JGwfjKTxPDF6x8ixOaluPrVqIn06C99AcRPhmYlBR56d/Fb+GN58GzExpg==", + "license": "MIT", + "dependencies": { + "@shikijs/primitive": "4.4.3", + "@shikijs/types": "4.4.3", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.5", + "hast-util-to-html": "^9.0.5" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/engine-javascript": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/engine-javascript/-/engine-javascript-4.4.3.tgz", + "integrity": "sha512-FbOjFJp9VLdo1Wevs10BBtVxiTWwNLqZh5Gkhjgda/ioL15YOgeSl9n+6XMa3qRlPQzfhFNe641SrynFHYG0nQ==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.4.3", + "@shikijs/vscode-textmate": "^10.0.2", + "oniguruma-to-es": "^4.3.6" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/engine-oniguruma": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-4.4.3.tgz", + "integrity": "sha512-EcOQkxdxGQrc1Row/cC2c96/v1dbZqGnEVu1qTuT/MJmp6+cXCvQussowVmCv5Tqr3KuY3c7IbM6HTW3LJ1k9w==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.4.3", + "@shikijs/vscode-textmate": "^10.0.2" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/langs": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/langs/-/langs-4.4.3.tgz", + "integrity": "sha512-ePic0yfAJGOF83D5wBHK/00EjK65oahBYxFk5epgq33WRv7X9UuxLEV8PtR0szC0z8dl7INIpIodB99JRFlR+A==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.4.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/primitive": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/primitive/-/primitive-4.4.3.tgz", + "integrity": "sha512-m0wBeLDQDeIxRdUmrCPdQqfuUamDwRL5isCfYbguKD6NiaKpVbsv+3J81DyIKgNW5h4WAIIr8T4EkgQrBBxvaQ==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.4.3", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.5" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/themes": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/themes/-/themes-4.4.3.tgz", + "integrity": "sha512-w8UHjeUnIR965KMWJHUPXOc2mNJUnK3vpVLYLvw5IYU2mnTTJ89E24OrJDBNiJDQ0qzb0tc4l7mrIXx5cFeIyw==", + "license": "MIT", + "dependencies": { + "@shikijs/types": "4.4.3" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@shikijs/types": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/@shikijs/types/-/types-4.4.3.tgz", + "integrity": "sha512-UEJxmRR++MAGR6hugn0vgVS2W/6lWAts84FFSrnlH9sP0LNol7E5+NQ792pH8liWUhyMyjhTgSUH3k7iD7tc5g==", + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.5" + }, + "engines": { + "node": ">=20" + } + }, + "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/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "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": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz", + "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "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/@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/@types/node": { + "version": "26.5.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.5.0.tgz", + "integrity": "sha512-dVSGpriSoCgz8WnDNTuSSuSv1PC/ALXihO4ulRZt7Md8k9mlbdin3lGOcDE8SnWOgf513ByWlXd7BK4azmyg/A==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "undici-types": "~8.9.0" + } + }, + "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/@ungap/structured-clone": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.4.0.tgz", + "integrity": "sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==", + "license": "ISC" + }, + "node_modules/@volar/kit": { + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/kit/-/kit-2.4.28.tgz", + "integrity": "sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-service": "2.4.28", + "@volar/typescript": "2.4.28", + "typesafe-path": "^0.2.2", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/@volar/language-core": { + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.28.tgz", + "integrity": "sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/source-map": "2.4.28" + } + }, + "node_modules/@volar/language-server": { + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/language-server/-/language-server-2.4.28.tgz", + "integrity": "sha512-NqcLnE5gERKuS4PUFwlhMxf6vqYo7hXtbMFbViXcbVkbZ905AIVWhnSo0ZNBC2V127H1/2zP7RvVOVnyITFfBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.28", + "@volar/language-service": "2.4.28", + "@volar/typescript": "2.4.28", + "path-browserify": "^1.0.1", + "request-light": "^0.7.0", + "vscode-languageserver": "^9.0.1", + "vscode-languageserver-protocol": "^3.17.5", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@volar/language-service": { + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/language-service/-/language-service-2.4.28.tgz", + "integrity": "sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.28", + "vscode-languageserver-protocol": "^3.17.5", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@volar/source-map": { + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.28.tgz", + "integrity": "sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@volar/typescript": { + "version": "2.4.28", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.28.tgz", + "integrity": "sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "2.4.28", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vscode/emmet-helper": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@vscode/emmet-helper/-/emmet-helper-2.11.0.tgz", + "integrity": "sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "emmet": "^2.4.3", + "jsonc-parser": "^2.3.0", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-languageserver-types": "^3.15.1", + "vscode-uri": "^3.0.8" + } + }, + "node_modules/@vscode/l10n": { + "version": "0.0.18", + "resolved": "https://registry.npmjs.org/@vscode/l10n/-/l10n-0.0.18.tgz", + "integrity": "sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-i18n": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/ajv-i18n/-/ajv-i18n-4.2.0.tgz", + "integrity": "sha512-v/ei2UkCEeuKNXh8RToiFsUclmU+G57LO1Oo22OagNMENIw+Yb8eMwvHu7Vn9fmkjJyv6XclhJ8TbuigSglPkg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^8.0.0-beta.0" + } + }, + "node_modules/am-i-vibing": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/am-i-vibing/-/am-i-vibing-0.4.0.tgz", + "integrity": "sha512-MxT4XZL7pzLHpuvhDKdMaQHMGGkJDLluKBLsbstn+8wv9sWcFT6h+0ve9qkml95amVTZtZV83gQe2hY+ojgHLg==", + "license": "MIT", + "dependencies": { + "process-ancestry": "^0.1.0" + }, + "bin": { + "am-i-vibing": "dist/cli.mjs" + } + }, + "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==", + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/anynum": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/anynum/-/anynum-1.0.1.tgz", + "integrity": "sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "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/astro": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/astro/-/astro-7.3.2.tgz", + "integrity": "sha512-ysTcdpGP61XZpHoMRYC/CK19DQ94qkBvzXMtXEo0gEqPNkmOU/Tv++CtWmzaI4nF2Ck8RXFdiWvdlTWa2oOr9w==", + "license": "MIT", + "dependencies": { + "@astrojs/compiler-rs": "^0.4.0", + "@astrojs/internal-helpers": "0.11.0", + "@astrojs/markdown-satteri": "0.4.1", + "@astrojs/telemetry": "3.3.3", + "@capsizecss/unpack": "^4.0.0", + "@clack/prompts": "^1.1.0", + "@oslojs/encoding": "^1.1.0", + "am-i-vibing": "^0.4.0", + "aria-query": "^5.3.2", + "axobject-query": "^4.1.0", + "ci-info": "^4.4.0", + "clsx": "^2.1.1", + "common-ancestor-path": "^2.0.0", + "cookie": "^2.0.1", + "devalue": "^5.8.1", + "diff": "^9.0.0", + "dset": "^3.1.4", + "es-module-lexer": "^2.0.0", + "esbuild": "^0.28.0", + "find-proc": "0.1.0", + "flattie": "^1.1.1", + "fontace": "~0.4.1", + "get-tsconfig": "5.0.0-beta.4", + "github-slugger": "^2.0.0", + "html-escaper": "3.0.3", + "http-cache-semantics": "^4.2.0", + "js-yaml": "^4.3.0", + "jsonc-parser": "^3.3.1", + "magic-string": "^1.0.0", + "magicast": "^0.5.2", + "mrmime": "^2.0.1", + "neotraverse": "^1.0.1", + "obug": "^2.1.1", + "p-limit": "^7.3.0", + "p-queue": "^9.1.0", + "package-manager-detector": "^1.6.0", + "piccolore": "^0.1.3", + "picomatch": "^4.0.4", + "semver": "^7.7.4", + "shiki": "^4.0.2", + "smol-toml": "^1.6.0", + "svgo": "^4.0.1", + "tinyclip": "^0.1.12", + "tinyexec": "^1.0.4", + "tinyglobby": "^0.2.15", + "ultrahtml": "^1.6.0", + "unifont": "~0.7.5", + "unstorage": "^1.17.5", + "vite": "^8.0.13", + "vitefu": "^1.1.2", + "xxhash-wasm": "^1.1.0", + "yargs-parser": "^22.0.0", + "zod": "^4.5.4" + }, + "bin": { + "astro": "bin/astro.mjs" + }, + "engines": { + "node": ">=22.12.0", + "npm": ">=9.6.5", + "pnpm": ">=7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/astrodotbuild" + }, + "optionalDependencies": { + "sharp": "^0.35.4" + }, + "peerDependencies": { + "@astrojs/markdown-remark": "^7.3.0" + }, + "peerDependenciesMeta": { + "@astrojs/markdown-remark": { + "optional": true + } + } + }, + "node_modules/astro/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" + }, + "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/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/bibtex-parse-js": { + "version": "0.0.23", + "resolved": "https://registry.npmjs.org/bibtex-parse-js/-/bibtex-parse-js-0.0.23.tgz", + "integrity": "sha512-mX5dOwMblO1Bh8Kcht2hxUdJ9xzZNzpxYTDG9H5y9utte2P4Y+ZggZkniGV8GIyEF8kFUzqBoCbmVH5OIoQKVw==", + "license": "MIT", + "dependencies": { + "xml2js": "*" + } + }, + "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/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "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==", + "license": "MIT", + "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==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/cheerio": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", + "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio-select/node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio-select/node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cheerio/node_modules/undici": { + "version": "7.29.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.1.tgz", + "integrity": "sha512-RYONW2MeafgYlkVOKYKkA/Ag7BmXqgIWCa8t1m0JcxrQg9pI9lEqRhAOruOBCbAohOa/gkCF+iPi9hrgvTzu6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/ci-info": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.4.0.tgz", + "integrity": "sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "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/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/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/common-ancestor-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-2.0.0.tgz", + "integrity": "sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">= 18" + } + }, + "node_modules/cookie": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-2.0.1.tgz", + "integrity": "sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==", + "license": "MIT", + "engines": { + "node": ">=22" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/cookie-es": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-1.2.3.tgz", + "integrity": "sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==", + "license": "MIT" + }, + "node_modules/crossws": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/crossws/-/crossws-0.3.5.tgz", + "integrity": "sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==", + "license": "MIT", + "dependencies": { + "uncrypto": "^0.1.3" + } + }, + "node_modules/css-select": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-6.0.0.tgz", + "integrity": "sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==", + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^7.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "nth-check": "^2.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/css-what": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-7.0.0.tgz", + "integrity": "sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==", + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/csso": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", + "license": "MIT", + "dependencies": { + "css-tree": "~2.2.0" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==", + "license": "CC0-1.0" + }, + "node_modules/defu": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz", + "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==", + "license": "MIT" + }, + "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": ">=6" + } + }, + "node_modules/destr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/destr/-/destr-2.0.5.tgz", + "integrity": "sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==", + "license": "MIT" + }, + "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/devalue": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.9.2.tgz", + "integrity": "sha512-po4PAY5c53tw5XMocSnf8A/5OHhbbUftpr93aEN6BBoAdntUmK7vu7wOATqvt7cXO7m1Cl4gMVn6p7n6n4mj0w==", + "license": "MIT" + }, + "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": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diff": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-9.0.0.tgz", + "integrity": "sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "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": ">=4" + } + }, + "node_modules/emmet": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/emmet/-/emmet-2.4.11.tgz", + "integrity": "sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==", + "dev": true, + "license": "MIT", + "workspaces": [ + "./packages/scanner", + "./packages/abbreviation", + "./packages/css-abbreviation", + "./" + ], + "dependencies": { + "@emmetio/abbreviation": "^2.3.3", + "@emmetio/css-abbreviation": "^2.1.8" + } + }, + "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==", + "dev": true, + "license": "MIT" + }, + "node_modules/encoding-sniffer": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz", + "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-module-lexer": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", + "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.28.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.2.tgz", + "integrity": "sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==", + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.2", + "@esbuild/android-arm": "0.28.2", + "@esbuild/android-arm64": "0.28.2", + "@esbuild/android-x64": "0.28.2", + "@esbuild/darwin-arm64": "0.28.2", + "@esbuild/darwin-x64": "0.28.2", + "@esbuild/freebsd-arm64": "0.28.2", + "@esbuild/freebsd-x64": "0.28.2", + "@esbuild/linux-arm": "0.28.2", + "@esbuild/linux-arm64": "0.28.2", + "@esbuild/linux-ia32": "0.28.2", + "@esbuild/linux-loong64": "0.28.2", + "@esbuild/linux-mips64el": "0.28.2", + "@esbuild/linux-ppc64": "0.28.2", + "@esbuild/linux-riscv64": "0.28.2", + "@esbuild/linux-s390x": "0.28.2", + "@esbuild/linux-x64": "0.28.2", + "@esbuild/netbsd-arm64": "0.28.2", + "@esbuild/netbsd-x64": "0.28.2", + "@esbuild/openbsd-arm64": "0.28.2", + "@esbuild/openbsd-x64": "0.28.2", + "@esbuild/openharmony-arm64": "0.28.2", + "@esbuild/sunos-x64": "0.28.2", + "@esbuild/win32-arm64": "0.28.2", + "@esbuild/win32-ia32": "0.28.2", + "@esbuild/win32-x64": "0.28.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "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": ">=4" + } + }, + "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/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": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-string-truncated-width": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", + "integrity": "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==", + "license": "MIT" + }, + "node_modules/fast-string-width": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/fast-string-width/-/fast-string-width-3.0.2.tgz", + "integrity": "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==", + "license": "MIT", + "dependencies": { + "fast-string-truncated-width": "^3.0.2" + } + }, + "node_modules/fast-uri": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.7.tgz", + "integrity": "sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fast-wrap-ansi": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/fast-wrap-ansi/-/fast-wrap-ansi-0.2.2.tgz", + "integrity": "sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==", + "license": "MIT", + "dependencies": { + "fast-string-width": "^3.0.2" + } + }, + "node_modules/fast-xml-builder": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.3.1.tgz", + "integrity": "sha512-pIM/1n3ntFXKYrUZwW7QCK0gAW7XY+wzj1YMIV3tLDvPj/V+zTGJK5e3/4WJfwj0qWw2ElNXiTixda/R+3YSug==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "path-expression-matcher": "^1.6.2", + "xml-naming": "^0.3.0" + } + }, + "node_modules/fast-xml-parser": { + "version": "5.11.1", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.11.1.tgz", + "integrity": "sha512-TBw6K/fxoQGGjCmZDw9w/ZwP3uDcnTM4YH/g+PFRWr8sbe5idXtxNN6vITh4+1ruCZaho6uBFurElsA7F0zzgw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "@nodable/entities": "^3.0.0", + "fast-xml-builder": "^1.2.0", + "is-unsafe": "^2.0.0", + "path-expression-matcher": "^1.6.2", + "strnum": "^2.4.2", + "xml-naming": "^0.3.0" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/find-proc": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/find-proc/-/find-proc-0.1.0.tgz", + "integrity": "sha512-OaOpEYv2PiQ7SQ5LIrl+deA1XaWcxEjnpM6VuWXTUvn+teIXxeFTLDmu18/zDQpFmHN4o3oDBX+BT0AGwEhemg==", + "license": "MIT", + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "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/fontace": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/fontace/-/fontace-0.4.1.tgz", + "integrity": "sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==", + "license": "MIT", + "dependencies": { + "fontkitten": "^1.0.2" + } + }, + "node_modules/fontkitten": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fontkitten/-/fontkitten-1.0.3.tgz", + "integrity": "sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==", + "license": "MIT", + "dependencies": { + "tiny-inflate": "^1.0.3" + }, + "engines": { + "node": ">=20" + } + }, + "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/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.6.0.tgz", + "integrity": "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-tsconfig": { + "version": "5.0.0-beta.4", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-5.0.0-beta.4.tgz", + "integrity": "sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==", + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "engines": { + "node": ">=20.20.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "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/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": { + "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==", + "license": "MIT", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.15.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz", + "integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==", + "license": "MIT", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/h3": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/h3/-/h3-1.15.11.tgz", + "integrity": "sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==", + "license": "MIT", + "dependencies": { + "cookie-es": "^1.2.3", + "crossws": "^0.3.5", + "defu": "^6.1.6", + "destr": "^2.0.5", + "iron-webcrypto": "^1.2.1", + "node-mock-http": "^1.0.4", + "radix3": "^1.1.2", + "ufo": "^1.6.3", + "uncrypto": "^0.1.3" + } + }, + "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/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/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/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "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/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/iron-webcrypto": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz", + "integrity": "sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/brc-dd" + } + }, + "node_modules/is-docker": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-4.0.0.tgz", + "integrity": "sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==", + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=20" + }, + "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==", + "license": "MIT", + "engines": { + "node": ">=0.10.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==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unsafe": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-unsafe/-/is-unsafe-2.0.2.tgz", + "integrity": "sha512-HgbIHPBH0KHHCcjLfGsCvhtPTVxjaAZlXjwdz7/GQC40SjSe4sfQsar8J5VFo8JOSbarkpV0OLG95bbaNd9aAQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonc-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.3.1.tgz", + "integrity": "sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==", + "dev": true, + "license": "MIT" + }, + "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" + } + }, + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/magic-string": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-1.2.3.tgz", + "integrity": "sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==", + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/magicast": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.4.tgz", + "integrity": "sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.29.7", + "@babel/types": "^7.29.7", + "source-map-js": "^1.2.1" + } + }, + "node_modules/marked": { + "version": "18.0.12", + "resolved": "https://registry.npmjs.org/marked/-/marked-18.0.12.tgz", + "integrity": "sha512-LEm4ga2YeI2T3GVHj9b0BaDPPk93LLTHMFeMyQbNIzPxc8vCI0y/scy0ZA6z6lXKyT9j9Nhl/OC6ZYKYGuFScA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, + "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" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "license": "CC0-1.0" + }, + "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" + } + }, + "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" + }, + "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" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "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" + }, + "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" + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/muggle-string": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", + "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.18", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", + "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", + "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" + } + }, + "node_modules/neotraverse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-1.0.1.tgz", + "integrity": "sha512-WmmLty1YWwJl9yZi77v2dVIV6X2kuYV8YYBI/G3LWGKdGHmHUvL1z7FW0iDvEvGAwNEoc5x1tOOOyDnf5jJw/w==", + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "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" + } + }, + "node_modules/node-fetch-native": { + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/node-fetch-native/-/node-fetch-native-1.6.7.tgz", + "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==", + "license": "MIT" + }, + "node_modules/node-mock-http": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.5.tgz", + "integrity": "sha512-KQyt/wLjG3TAc7DOUhpqWzgd4ERxR80JOlTK5VE5R1S12IaPVN5qkj4klBce9HPG1Njuup4Sb5bljaT34lIyjw==", + "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==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "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" + } + }, + "node_modules/obug": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.4.tgz", + "integrity": "sha512-4a+OsYv9UktOJKE+l1A4OufDgdRF9PifWj+tJnHURo/P+WOxpG4GzUFL9qCalmWauao6ogiG+QvnCovwPoyAWA==", + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, + "node_modules/ofetch": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-1.5.1.tgz", + "integrity": "sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==", + "license": "MIT", + "dependencies": { + "destr": "^2.0.5", + "node-fetch-native": "^1.6.7", + "ufo": "^1.6.1" + } + }, + "node_modules/ohash": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.12.tgz", + "integrity": "sha512-65S/5gk9YSsaRjcyf7Nfa6h/d3E8/1gslpXfI4W7Dxn/oap8IKRuNT5VXkLQ1YFKIEg4apRY4Pj6aiwFzrDdmw==", + "license": "MIT" + }, + "node_modules/oniguruma-parser": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/oniguruma-parser/-/oniguruma-parser-0.12.2.tgz", + "integrity": "sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==", + "license": "MIT" + }, + "node_modules/oniguruma-to-es": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/oniguruma-to-es/-/oniguruma-to-es-4.3.6.tgz", + "integrity": "sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==", + "license": "MIT", + "dependencies": { + "oniguruma-parser": "^0.12.2", + "regex": "^6.1.0", + "regex-recursion": "^6.0.2" + } + }, + "node_modules/p-limit": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-7.3.2.tgz", + "integrity": "sha512-Ll0w3fU24vYpXoZmjjZIee6bJQDgG0oAyo1PdmFYI8UDwJJddaHAypxIH9avUu+t+lSsAwKVsb1jDCMIIChliw==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.2.1" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue": { + "version": "9.3.3", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-9.3.3.tgz", + "integrity": "sha512-NXAOdnEe5FsZJfT4oK84lE1Y5cFFdWlRuOo5tww8DyNMxyRXwn39fIkUtNLKppcPC+UYU/bXujNCUGDv01y7CA==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^5.0.4", + "p-timeout": "^7.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-timeout": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-7.0.1.tgz", + "integrity": "sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==", + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/package-manager-detector": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.8.0.tgz", + "integrity": "sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==", + "license": "MIT" + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-expression-matcher": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.6.2.tgz", + "integrity": "sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/piccolore": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/piccolore/-/piccolore-0.1.3.tgz", + "integrity": "sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==", + "license": "ISC" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/postcss": { + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "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.18", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/prettier": { + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", + "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/prettier-plugin-astro": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/prettier-plugin-astro/-/prettier-plugin-astro-0.14.1.tgz", + "integrity": "sha512-RiBETaaP9veVstE4vUwSIcdATj6dKmXljouXc/DDNwBSPTp8FRkLGDSGFClKsAFeeg+13SB0Z1JZvbD76bigJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@astrojs/compiler": "^2.9.1", + "prettier": "^3.0.0", + "sass-formatter": "^0.7.6" + }, + "engines": { + "node": "^14.15.0 || >=16.0.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" + } + }, + "node_modules/process-ancestry": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/process-ancestry/-/process-ancestry-0.1.0.tgz", + "integrity": "sha512-tGqJW/UnclpYASFcM6Xh8D8l/BMtaQ9+CSG0vlJSJTcdMM4lDRv4c6H0Pdcsfted+bVczdYSfk2fdukg2gQkZg==", + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/property-information": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.2.0.tgz", + "integrity": "sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/radix3": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/radix3/-/radix3-1.1.2.tgz", + "integrity": "sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==", + "license": "MIT" + }, + "node_modules/readdirp": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.1.1.tgz", + "integrity": "sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==", + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/regex/-/regex-6.1.0.tgz", + "integrity": "sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.0" + } + }, + "node_modules/regex-recursion": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/regex-recursion/-/regex-recursion-6.0.2.tgz", + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "license": "MIT", + "dependencies": { + "regex-utilities": "^2.3.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/request-light": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.7.0.tgz", + "integrity": "sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "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" + } + }, + "node_modules/rolldown": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.7.tgz", + "integrity": "sha512-g0EtLvBjTUB7jhyV0S/TCup3v/XSVl45vUIGbOGU4QPiyjTenCe4mKuFvW9fEgYmS2Fo42AUssRmNuMziXdrig==", + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.148.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm-eabi": "1.2.7", + "@rolldown/binding-android-arm64": "1.2.7", + "@rolldown/binding-darwin-arm64": "1.2.7", + "@rolldown/binding-darwin-x64": "1.2.7", + "@rolldown/binding-freebsd-x64": "1.2.7", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.7", + "@rolldown/binding-linux-arm64-gnu": "1.2.7", + "@rolldown/binding-linux-arm64-musl": "1.2.7", + "@rolldown/binding-linux-ppc64-gnu": "1.2.7", + "@rolldown/binding-linux-s390x-gnu": "1.2.7", + "@rolldown/binding-linux-x64-gnu": "1.2.7", + "@rolldown/binding-linux-x64-musl": "1.2.7", + "@rolldown/binding-openharmony-arm64": "1.2.7", + "@rolldown/binding-win32-arm64-msvc": "1.2.7", + "@rolldown/binding-win32-x64-msvc": "1.2.7" + } + }, + "node_modules/s.color": { + "version": "0.0.15", + "resolved": "https://registry.npmjs.org/s.color/-/s.color-0.0.15.tgz", + "integrity": "sha512-AUNrbEUHeKY8XsYr/DYpl+qk5+aM+DChopnWOPEzn8YKzOhv4l2zH6LzZms3tOZP3wwdOyc0RmTciyi46HLIuA==", + "dev": true, + "license": "MIT" + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sass-formatter": { + "version": "0.7.9", + "resolved": "https://registry.npmjs.org/sass-formatter/-/sass-formatter-0.7.9.tgz", + "integrity": "sha512-CWZ8XiSim+fJVG0cFLStwDvft1VI7uvXdCNJYXhDvowiv+DsbD1nXLiQ4zrE5UBvj5DWZJ93cwN0NX5PMsr1Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "suf-log": "^2.5.3" + } + }, + "node_modules/satteri": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/satteri/-/satteri-0.10.5.tgz", + "integrity": "sha512-Ao1LKpAEa9Wdg0otgbVKViZHEq9ebdXe4DMrp3s9vQAU0HNIuHnFEuMuOcm0ZIXyV0Yzxj91NvhLpvXZJO/5ZQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.5", + "@types/hast": "^3.0.5", + "@types/mdast": "^4.0.4", + "@types/unist": "^3.0.3" + }, + "optionalDependencies": { + "@bruits/satteri-darwin-arm64": "0.10.5", + "@bruits/satteri-darwin-x64": "0.10.5", + "@bruits/satteri-linux-arm64-gnu": "0.10.5", + "@bruits/satteri-linux-arm64-musl": "0.10.5", + "@bruits/satteri-linux-x64-gnu": "0.10.5", + "@bruits/satteri-linux-x64-musl": "0.10.5", + "@bruits/satteri-wasm32-wasi": "0.10.5", + "@bruits/satteri-win32-arm64-msvc": "0.10.5", + "@bruits/satteri-win32-x64-msvc": "0.10.5" + } + }, + "node_modules/sax": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.1.tgz", + "integrity": "sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.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": { + "extend-shallow": "^2.0.1", + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.4.tgz", + "integrity": "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==", + "devOptional": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.1.0", + "detect-libc": "^2.1.2", + "semver": "^7.8.5" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.35.4", + "@img/sharp-darwin-x64": "0.35.4", + "@img/sharp-freebsd-wasm32": "0.35.4", + "@img/sharp-libvips-darwin-arm64": "1.3.3", + "@img/sharp-libvips-darwin-x64": "1.3.3", + "@img/sharp-libvips-linux-arm": "1.3.3", + "@img/sharp-libvips-linux-arm64": "1.3.3", + "@img/sharp-libvips-linux-ppc64": "1.3.3", + "@img/sharp-libvips-linux-riscv64": "1.3.3", + "@img/sharp-libvips-linux-s390x": "1.3.3", + "@img/sharp-libvips-linux-x64": "1.3.3", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", + "@img/sharp-libvips-linuxmusl-x64": "1.3.3", + "@img/sharp-linux-arm": "0.35.4", + "@img/sharp-linux-arm64": "0.35.4", + "@img/sharp-linux-ppc64": "0.35.4", + "@img/sharp-linux-riscv64": "0.35.4", + "@img/sharp-linux-s390x": "0.35.4", + "@img/sharp-linux-x64": "0.35.4", + "@img/sharp-linuxmusl-arm64": "0.35.4", + "@img/sharp-linuxmusl-x64": "0.35.4", + "@img/sharp-webcontainers-wasm32": "0.35.4", + "@img/sharp-win32-arm64": "0.35.4", + "@img/sharp-win32-ia32": "0.35.4", + "@img/sharp-win32-x64": "0.35.4" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/shiki": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/shiki/-/shiki-4.4.3.tgz", + "integrity": "sha512-Mb/GvXPHBAXdgGIcnfU5L3ldpn1XcxrGkPHwqgRx17/I2XRfqlFKk2vGkHWINn1kdXvzJZeuO3is6I9KLPFm0g==", + "license": "MIT", + "dependencies": { + "@shikijs/core": "4.4.3", + "@shikijs/engine-javascript": "4.4.3", + "@shikijs/engine-oniguruma": "4.4.3", + "@shikijs/langs": "4.4.3", + "@shikijs/themes": "4.4.3", + "@shikijs/types": "4.4.3", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.5" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "license": "MIT" + }, + "node_modules/smol-toml": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.8.0.tgz", + "integrity": "sha512-kCZr2V3ch9i00x8zXRhjUNVcjG9ijES5dDudkXvUVCT5QlJNQWElSJdZqyPemffHoLNUYwOcou0Fy+ojN0uHSQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, + "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" + } + }, + "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" + } + }, + "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" + }, + "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==", + "dev": true, + "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" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=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" + } + }, + "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" + } + }, + "node_modules/strnum": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.4.2.tgz", + "integrity": "sha512-rDG3Ah4TV0k1hWvLSzkZtMmLN9+eS+h3knq4MP6A42Y3Yh5qGNnOUs1jJkoSr8FG5dsL28c7KgkIBzSEykqtuw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "anynum": "^1.0.1" + } + }, + "node_modules/suf-log": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/suf-log/-/suf-log-2.5.3.tgz", + "integrity": "sha512-KvC8OPjzdNOe+xQ4XWJV2whQA0aM1kGVczMQ8+dStAO6KfEB140JEVQ9dE76ONZ0/Ylf67ni4tILPJB41U0eow==", + "dev": true, + "license": "MIT", + "dependencies": { + "s.color": "0.0.15" + } + }, + "node_modules/svgo": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.1.0.tgz", + "integrity": "sha512-bkxnTg1kSU0guhIBmibA6UUhrQmPVA1XsQLN+ylCd+UWzbnLkySOcXpyk1mrl05f+pcaCx2eHb+sp6BgMZWX+Q==", + "license": "MIT", + "dependencies": { + "commander": "^11.1.0", + "css-select": "^6.0.0", + "css-tree": "^3.0.1", + "css-what": "^7.0.0", + "csso": "^5.0.5", + "picocolors": "^1.1.1", + "sax": "1.6.1" + }, + "bin": { + "svgo": "bin/svgo.js" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" + } + }, + "node_modules/tiny-inflate": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", + "license": "MIT" + }, + "node_modules/tinyclip": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/tinyclip/-/tinyclip-0.1.15.tgz", + "integrity": "sha512-uo33abH+Ays0xYaDysoBt494Hb3hsEczMpcC0MwFl773pazORx4fmvKhclhR1wonUbB6vvpRsvVMwnhfqeMc+A==", + "license": "MIT", + "engines": { + "node": "^16.14.0 || >= 17.3.0" + } + }, + "node_modules/tinyexec": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.3.1.tgz", + "integrity": "sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "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" + } + }, + "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" + } + }, + "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/typesafe-path": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/typesafe-path/-/typesafe-path-0.2.2.tgz", + "integrity": "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-auto-import-cache": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/typescript-auto-import-cache/-/typescript-auto-import-cache-0.3.6.tgz", + "integrity": "sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.3.8" + } + }, + "node_modules/ufo": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.4.tgz", + "integrity": "sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==", + "license": "MIT" + }, + "node_modules/ultrahtml": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/ultrahtml/-/ultrahtml-1.7.0.tgz", + "integrity": "sha512-2xRd0VHoAQE4M+vF/DvFFB7pUV0ZxTW1TLi7lHQWnF/Sb5TPeEUV/l+hxcNnGO00ZXGnR0voCMmYRKQf+rvJ2g==", + "license": "MIT" + }, + "node_modules/uncrypto": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/uncrypto/-/uncrypto-0.1.3.tgz", + "integrity": "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==", + "license": "MIT" + }, + "node_modules/undici": { + "version": "8.10.2", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.10.2.tgz", + "integrity": "sha512-/y4/bH9YNU5hi9NIrpOuvGXFcxrj3CMrV+/AYpowAYTpHn8gX/XPFjNy766FPoYY0miQhdW977JFWKGNhBdwyQ==", + "license": "MIT", + "engines": { + "node": ">=22.19.0" + } + }, + "node_modules/undici-types": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz", + "integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==", + "devOptional": true, + "license": "MIT" + }, + "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" + } + }, + "node_modules/unifont": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/unifont/-/unifont-0.7.5.tgz", + "integrity": "sha512-ULe/Cs+ZIsq+dcFofNkhqielCrUJnb5mr+Yc4EBM2VlL+6OZR6+cjtI2mT1bJvRBrVncqHAbLURxmPLcCXzWMg==", + "license": "MIT", + "dependencies": { + "css-tree": "^3.1.0", + "ohash": "^2.0.11", + "undici": "^8.0.0" + } + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "node_modules/unstorage": { + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-1.17.5.tgz", + "integrity": "sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==", + "license": "MIT", + "dependencies": { + "anymatch": "^3.1.3", + "chokidar": "^5.0.0", + "destr": "^2.0.5", + "h3": "^1.15.10", + "lru-cache": "^11.2.7", + "node-fetch-native": "^1.6.7", + "ofetch": "^1.5.1", + "ufo": "^1.6.3" + }, + "peerDependencies": { + "@azure/app-configuration": "^1.8.0", + "@azure/cosmos": "^4.2.0", + "@azure/data-tables": "^13.3.0", + "@azure/identity": "^4.6.0", + "@azure/keyvault-secrets": "^4.9.0", + "@azure/storage-blob": "^12.26.0", + "@capacitor/preferences": "^6 || ^7 || ^8", + "@deno/kv": ">=0.9.0", + "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", + "@planetscale/database": "^1.19.0", + "@upstash/redis": "^1.34.3", + "@vercel/blob": ">=0.27.1", + "@vercel/functions": "^2.2.12 || ^3.0.0", + "@vercel/kv": "^1 || ^2 || ^3", + "aws4fetch": "^1.0.20", + "db0": ">=0.2.1", + "idb-keyval": "^6.2.1", + "ioredis": "^5.4.2", + "uploadthing": "^7.4.4" + }, + "peerDependenciesMeta": { + "@azure/app-configuration": { + "optional": true + }, + "@azure/cosmos": { + "optional": true + }, + "@azure/data-tables": { + "optional": true + }, + "@azure/identity": { + "optional": true + }, + "@azure/keyvault-secrets": { + "optional": true + }, + "@azure/storage-blob": { + "optional": true + }, + "@capacitor/preferences": { + "optional": true + }, + "@deno/kv": { + "optional": true + }, + "@netlify/blobs": { + "optional": true + }, + "@planetscale/database": { + "optional": true + }, + "@upstash/redis": { + "optional": true + }, + "@vercel/blob": { + "optional": true + }, + "@vercel/functions": { + "optional": true + }, + "@vercel/kv": { + "optional": true + }, + "aws4fetch": { + "optional": true + }, + "db0": { + "optional": true + }, + "idb-keyval": { + "optional": true + }, + "ioredis": { + "optional": true + }, + "uploadthing": { + "optional": true + } + } + }, + "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" + } + }, + "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" + } + }, + "node_modules/vite": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz", + "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", + "license": "MIT", + "dependencies": { + "lightningcss": "^1.33.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.26", + "rolldown": "~1.2.4", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.4.0 || ^0.5.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vitefu": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/vitefu/-/vitefu-1.1.3.tgz", + "integrity": "sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==", + "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 || ^8.0.0" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, + "node_modules/volar-service-css": { + "version": "0.0.71", + "resolved": "https://registry.npmjs.org/volar-service-css/-/volar-service-css-0.0.71.tgz", + "integrity": "sha512-wRRFt9BpjMKCazcgOh67MSjUjiWUCAh99DyYSDIOTuxaRjEtDC7PpB0k1Y1wbJIW/pVtMUSVbpPo3UGSm0Byxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-css-languageservice": "^6.3.0", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-emmet": { + "version": "0.0.71", + "resolved": "https://registry.npmjs.org/volar-service-emmet/-/volar-service-emmet-0.0.71.tgz", + "integrity": "sha512-zqjzt6bN95e3CUstBm0PBFAJnrfz0ZAARka87fart46/gNCLLuP3Vujy8V/J8HEziTFLnfkgIASLFYPUhonJcA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@emmetio/css-parser": "^0.4.1", + "@emmetio/html-matcher": "^1.3.0", + "@vscode/emmet-helper": "^2.9.3", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-html": { + "version": "0.0.71", + "resolved": "https://registry.npmjs.org/volar-service-html/-/volar-service-html-0.0.71.tgz", + "integrity": "sha512-e8tHPhgQ7ooLfudAEIku+kgd9pWkq3SSz8RbnQDI1+Eb8wbenkLGHqoirLqz5ORLV6wIMr2Iv08RWBG5eOcgpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-html-languageservice": "^5.3.0", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-prettier": { + "version": "0.0.71", + "resolved": "https://registry.npmjs.org/volar-service-prettier/-/volar-service-prettier-0.0.71.tgz", + "integrity": "sha512-Rz7JVH3qD108UCdmIEiZvOBNljMt2nLFdbN8AXcDfn7xD9F5I2aCIsDVqBbXw21PsnxG0b7MfwtNF+zPS/NKUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0", + "prettier": "^2.2 || ^3.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + }, + "prettier": { + "optional": true + } + } + }, + "node_modules/volar-service-typescript": { + "version": "0.0.71", + "resolved": "https://registry.npmjs.org/volar-service-typescript/-/volar-service-typescript-0.0.71.tgz", + "integrity": "sha512-yTtM/BVT6hoyEYnDtaCyAtNhdNeS/mhTTABlBOdw3NNiRBUin3IznFJpgfjer4c6RYopiPjjQjc9VFhxVl1mLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-browserify": "^1.0.1", + "semver": "^7.6.2", + "typescript-auto-import-cache": "^0.3.5", + "vscode-languageserver-textdocument": "^1.0.11", + "vscode-nls": "^5.2.0", + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-typescript-twoslash-queries": { + "version": "0.0.71", + "resolved": "https://registry.npmjs.org/volar-service-typescript-twoslash-queries/-/volar-service-typescript-twoslash-queries-0.0.71.tgz", + "integrity": "sha512-9K2k72s4n7rV9s4bX0MyjbX9iBribvKZbBJKuEmTCZfeWJXs6Yh7bGpY4eoc7UufAjvpheBqwyZCOIPBvxCv0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-uri": "^3.0.8" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/volar-service-yaml": { + "version": "0.0.71", + "resolved": "https://registry.npmjs.org/volar-service-yaml/-/volar-service-yaml-0.0.71.tgz", + "integrity": "sha512-qYGWGuVpUTnZGu5P/CR4KLK4aIR8RrcVnmfZ2eRcj9q/I8VZCoC5yy9FtEvfNvnDp4MU17yhdJcvpQPIqhJS2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-uri": "^3.0.8", + "yaml-language-server": "~1.23.0" + }, + "peerDependencies": { + "@volar/language-service": "~2.4.0" + }, + "peerDependenciesMeta": { + "@volar/language-service": { + "optional": true + } + } + }, + "node_modules/vscode-css-languageservice": { + "version": "6.3.10", + "resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-6.3.10.tgz", + "integrity": "sha512-eq5N9Er3fC4vA9zd9EFhyBG90wtCCuXgRSpAndaOgXMh1Wgep5lBgRIeDgjZBW9pa+332yC9+49cZMW8jcL3MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vscode/l10n": "^0.0.18", + "vscode-languageserver-textdocument": "^1.0.12", + "vscode-languageserver-types": "3.17.5", + "vscode-uri": "^3.1.0" + } + }, + "node_modules/vscode-css-languageservice/node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-html-languageservice": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-5.6.2.tgz", + "integrity": "sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vscode/l10n": "^0.0.18", + "vscode-languageserver-textdocument": "^1.0.12", + "vscode-languageserver-types": "^3.17.5", + "vscode-uri": "^3.1.0" + } + }, + "node_modules/vscode-json-languageservice": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/vscode-json-languageservice/-/vscode-json-languageservice-4.1.8.tgz", + "integrity": "sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsonc-parser": "^3.0.0", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-languageserver-types": "^3.16.0", + "vscode-nls": "^5.0.0", + "vscode-uri": "^3.0.2" + }, + "engines": { + "npm": ">=7.0.0" + } + }, + "node_modules/vscode-json-languageservice/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-jsonrpc": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-9.0.2.tgz", + "integrity": "sha512-SbQSV9yRemARxeXw6LU5sS6Zq0e9/DgCCX5yelH263ZQWukbTk8EF8fjTrr1dziasf4GwlJbvTwFnTrnQFWZXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.18.3", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.18.3.tgz", + "integrity": "sha512-DF49+WeV5py4zO5hhobp60jjsDSK0lAqA0OuKBLBvp423HPWQcCbhZz3JgyfIewsEz2f8U+X75xNIFHdiXZm2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "9.0.2", + "vscode-languageserver-types": "3.18.3" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.14.tgz", + "integrity": "sha512-EQyqJMi552E4ZTf46izQ4Fj6XquqxCySR3J5ZSD1SisMf6RfpeOWHxGBE8Gr6V0/3GHIGdAzDn8F8+1nTGCnoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.18.3", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.18.3.tgz", + "integrity": "sha512-XIlzJ7Qp/jzSI1ds7/FwPAWrPeTZA7pAtlW4hdJ1J6xXWJL6dR9QYnDhJOdLzdKhUQ5Mm6mvUMw+3DcOQQasPw==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-languageserver/node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver/node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "dev": true, + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver/node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-nls": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-5.2.0.tgz", + "integrity": "sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==", + "dev": true, + "license": "MIT" + }, + "node_modules/vscode-uri": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.2.0.tgz", + "integrity": "sha512-m2gXo3bn0G1kT9InzMf07fTbqMbGtyckj3bH5ktLO+1Ssv+yiATZ4dhwaQv9UZWxJh6E9IFGnQyjgWVDWVBDrg==", + "dev": true, + "license": "MIT" + }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "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" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/xml-naming": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.3.0.tgz", + "integrity": "sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/xml2js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", + "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "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" + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yaml": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", + "devOptional": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yaml-language-server": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/yaml-language-server/-/yaml-language-server-1.23.0.tgz", + "integrity": "sha512-3qVyCOexLCWw06PQa5kRPwvMWMZ/eZeCRWUvgD6a0OkqL/4iCnxy2WumbWifa937Uo5xhyWJ0uxlU39ljhNh7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vscode/l10n": "^0.0.18", + "ajv": "^8.17.1", + "ajv-draft-04": "^1.0.0", + "ajv-i18n": "^4.2.0", + "prettier": "^3.8.1", + "request-light": "^0.5.7", + "vscode-json-languageservice": "4.1.8", + "vscode-languageserver": "^9.0.0", + "vscode-languageserver-textdocument": "^1.0.1", + "vscode-languageserver-types": "^3.16.0", + "vscode-uri": "^3.0.2", + "yaml": "2.8.3" + }, + "bin": { + "yaml-language-server": "bin/yaml-language-server" + } + }, + "node_modules/yaml-language-server/node_modules/request-light": { + "version": "0.5.8", + "resolved": "https://registry.npmjs.org/request-light/-/request-light-0.5.8.tgz", + "integrity": "sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==", + "dev": true, + "license": "MIT" + }, + "node_modules/yaml-language-server/node_modules/yaml": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/yargs": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.1.0.tgz", + "integrity": "sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^8.2.1", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", + "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.2.tgz", + "integrity": "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.5.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", + "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "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": "4.5.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.5.4.tgz", + "integrity": "sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==", + "license": "MIT", + "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==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000000000..afee1311ba6b1 --- /dev/null +++ b/package.json @@ -0,0 +1,38 @@ +{ + "name": "boxi-yu-website", + "version": "1.0.0", + "private": true, + "type": "module", + "scripts": { + "prepare:assets": "node scripts/prepare-assets.mjs", + "dev": "npm run prepare:assets && astro dev --host 127.0.0.1", + "dev:drafts": "CONTENT_PREVIEW=true npm run dev", + "check": "astro check", + "build": "npm run prepare:assets && astro build", + "preview": "astro preview --host 127.0.0.1", + "test": "node --test tests/*.test.mjs", + "verify": "npm run check && npm run build && npm test" + }, + "engines": { + "node": ">=22.12.0" + }, + "dependencies": { + "@astrojs/mdx": "8.0.1", + "@astrojs/rss": "^4.0.19", + "@fontsource/source-sans-3": "^5.3.0", + "@fontsource/source-serif-4": "^5.3.0", + "astro": "7.3.2", + "bibtex-parse-js": "0.0.23", + "gray-matter": "^4.0.3", + "marked": "^18.0.12" + }, + "devDependencies": { + "@astrojs/check": "^0.9.10", + "@types/node": "^26.5.0", + "cheerio": "^1.2.0", + "prettier": "^3.9.6", + "prettier-plugin-astro": "^0.14.1", + "sharp": "^0.35.4", + "typescript": "^5.9.3" + } +} diff --git a/public/.nojekyll b/public/.nojekyll new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/public/favicon.svg b/public/favicon.svg new file mode 100644 index 0000000000000..1a40324daf540 --- /dev/null +++ b/public/favicon.svg @@ -0,0 +1 @@ + diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000000000..1a905c05aa636 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://boxiyu.github.io/sitemap.xml diff --git a/public/social-card.svg b/public/social-card.svg new file mode 100644 index 0000000000000..e45eaaad1c3b0 --- /dev/null +++ b/public/social-card.svg @@ -0,0 +1,11 @@ + + + + Senior Research Fellow / Lero, Ireland + Boxi Yu + Software testing & trustworthy AI + Coding agents, test oracles, and rigorous evaluation + boxiyu.github.io + + + diff --git a/scripts/prepare-assets.mjs b/scripts/prepare-assets.mjs new file mode 100644 index 0000000000000..b7f6b6ecf2dc1 --- /dev/null +++ b/scripts/prepare-assets.mjs @@ -0,0 +1,11 @@ +import { cp, mkdir, readFile, writeFile } from 'node:fs/promises'; +import sharp from 'sharp'; + +await mkdir('public/assets/img', { recursive: true }); +await cp('assets/pdf', 'public/assets/pdf', { recursive: true }); +for (const image of ['prof_pic.jpg', 'parrot.png']) { + await cp(`assets/img/${image}`, `public/assets/img/${image}`); +} +const bibliography = await readFile('_bibliography/papers.bib', 'utf8'); +await writeFile('public/papers.bib', bibliography.replace(/^---\s*\n---\s*\n/, '')); +await sharp('public/social-card.svg').png().toFile('public/social-card.png'); diff --git a/src/components/ArticleCard.astro b/src/components/ArticleCard.astro new file mode 100644 index 0000000000000..6c9ca9e784ab9 --- /dev/null +++ b/src/components/ArticleCard.astro @@ -0,0 +1,31 @@ +--- +import type { CollectionEntry } from 'astro:content'; +import { formatDate } from '../lib/writing'; +interface Props { + entry: CollectionEntry<'writing'>; + heading?: 'h2' | 'h3'; +} +const { entry, heading: Heading = 'h3' } = Astro.props; +--- + +
+ + {entry.data.title} +

{entry.data.description}

+
diff --git a/src/components/ResearchList.astro b/src/components/ResearchList.astro new file mode 100644 index 0000000000000..daaad10fabe4c --- /dev/null +++ b/src/components/ResearchList.astro @@ -0,0 +1,50 @@ +--- +import { projects } from '../data/site'; +import { publications } from '../lib/publications'; +interface Props { + selected?: string[]; +} +const { selected = ['swe-abs', 'utboost', 'retromorphic-testing', 'lightad'] } = Astro.props; +--- + +
+ { + projects + .filter((project) => selected.includes(project.id)) + .map((project) => { + const paper = publications.find((paper) => paper.id === project.paper)!; + return ( +
+
+ + {project.venue} {project.year} + + {project.name} + {project.venue === 'arXiv' && Preprint} +
+
+

+ {paper.title} +

+

+ {paper.authors.map((author, i) => ( + <> + {i > 0 && ', '} + {author === 'Boxi Yu' ? {author} : author} + + ))} +

+

{project.summary}

+ +
+
+ ); + }) + } +
diff --git a/src/components/ResearchMap.astro b/src/components/ResearchMap.astro new file mode 100644 index 0000000000000..1c6678a8f79b2 --- /dev/null +++ b/src/components/ResearchMap.astro @@ -0,0 +1,176 @@ +--- +import { researchGroups, empiricalResearch } from '../data/research'; +import { projects } from '../data/site'; +--- + +
+
+ How do we establish that software and AI behave correctly? +
+
+ { + researchGroups.map((group) => ( +
+

+ {group.title} +

+

{group.description}

+ +
+ )) + } +
+
+ {empiricalResearch.title}

+ LightAD examines model choice, preprocessing, and efficiency in log anomaly detection. +

+
+
+ Connected research themes, with links to individual works. The grouping describes shared + questions rather than a chronological sequence. +
+
+ + diff --git a/src/components/TestLab.astro b/src/components/TestLab.astro new file mode 100644 index 0000000000000..71dd124cb331c --- /dev/null +++ b/src/components/TestLab.astro @@ -0,0 +1,198 @@ +--- +interface Props { + compact?: boolean; +} +const { compact = false } = Astro.props; +--- + + +
+ A small test of confidencePython +
+
+ # Return the largest number
{'def '} + largest(numbers):
    best = 0
    for n in numbers:
        best = max(best, n)
    return best
+
+
+
+ Test inputExpectedResult +
+
[2, 7, 4]7Pass
+
[0, 3, 1]3Pass
+ +
+
+ 2 / 2 passed +
+

+ All tests pass. Is the function correct? +

+ +
+ + + + diff --git a/src/content.config.ts b/src/content.config.ts new file mode 100644 index 0000000000000..03da2c04cdc3c --- /dev/null +++ b/src/content.config.ts @@ -0,0 +1,27 @@ +import { defineCollection } from 'astro:content'; +import { z } from 'astro/zod'; +import { glob } from 'astro/loaders'; + +const writing = defineCollection({ + loader: glob({ pattern: '**/*.{md,mdx}', base: './src/content/writing' }), + schema: z + .object({ + title: z.string(), + description: z.string(), + publishedAt: z.coerce.date(), + updatedAt: z.coerce.date().optional(), + language: z.enum(['en', 'zh-CN']).default('en'), + topics: z.array(z.string()).min(1), + audience: z.string(), + draft: z.boolean().default(true), + featured: z.boolean().default(false), + series: z.string().optional(), + order: z.number().int().positive().optional(), + translationOf: z.string().optional(), + }) + .refine((data) => Boolean(data.series) === Boolean(data.order), { + message: 'A series and its order must be supplied together.', + }), +}); + +export const collections = { writing }; diff --git a/src/content/writing/passing-tests-is-not-correctness.md b/src/content/writing/passing-tests-is-not-correctness.md new file mode 100644 index 0000000000000..cdd7e3aeb75ed --- /dev/null +++ b/src/content/writing/passing-tests-is-not-correctness.md @@ -0,0 +1,98 @@ +--- +title: 'Passing tests is not the same as being correct' +description: 'A small function reveals a useful distinction between evidence, coverage, and correctness in AI-assisted programming.' +publishedAt: 2026-09-08 +language: en +topics: [Software testing, Coding agents] +audience: developers and technical students +draft: true +featured: true +series: Evaluating AI in practice +order: 1 +--- + +A coding agent produces a patch. The tests pass. Is the task solved? + +The answer depends on what the tests establish. A green result means that the program met the assertions in the cases that actually ran, under the conditions of that run. It does not automatically mean that the program satisfies the intended specification. + +This distinction is easier to see in a very small program. + +## A bug hiding in plain sight + +Suppose the contract is to return the largest integer in a non-empty list of integers: + +```python +def largest(numbers): + best = 0 + for n in numbers: + best = max(best, n) + return best +``` + +Both of these checks pass: + +```python +assert largest([2, 7, 4]) == 7 +assert largest([0, 3, 1]) == 3 +``` + +Yet the function is incorrect. On `[-8, -2, -5]`, it returns `0`. The expected answer is `-2`. The initial value silently assumed that the answer would never be negative. + +You can [step through this example](/education/) before reading on. + +## What the green result actually told us + +The two checks provide evidence about two inputs. Both exercise a similar assumption: at least one input is non-negative. Adding many more positive-only cases could preserve that blind spot. + +The issue is not simply the number of tests. It is whether the inputs and assertions distinguish a correct implementation from plausible incorrect ones. + +Code coverage is useful, but it answers a different question. Executing the return statement, or even every line in this function, does not establish that the initial value was appropriate for every input class. + +## Start with the contract + +A better workflow begins with a question: what must be true of the result? + +For this function, given a non-empty list of integers: + +- The result must be an element of the input. +- No input element may be greater than the result. + +Those properties immediately make the negative-only case interesting. They also suggest cases involving a single element, repeated maxima, and zero. Empty input is outside this contract; the interface should reject it or specify a separate behavior. + +One implementation is: + +```python +def largest(numbers): + if not numbers: + raise ValueError("expected a non-empty list") + best = numbers[0] + for n in numbers[1:]: + best = max(best, n) + return best +``` + +For the stated integer-list contract, initializing from the first element removes the assumption that caused the bug. This does not define behavior for arbitrary Python objects or floating-point values such as NaN; those require separate decisions. + +## Carry the distinction into AI evaluation + +When a test suite scores a generated patch, the same distinction matters. A passing patch may implement the intended behavior, or it may happen to satisfy an incomplete set of assertions. The score alone does not tell us which explanation applies. + +Useful evaluation questions include: + +- Which behaviors are represented by the tests? +- What plausible incorrect patches could still pass? +- Are the checks independent of the system producing the answer? +- Have the tests themselves been checked for errors? + +These questions motivate work on more rigorous coding-agent evaluation, including [UTBoost](/publications/#yu2025utboost) and [SWE-ABS](/publications/#yu2026sweabs). The toy example here illustrates the general distinction; it is not an experiment from either paper. + +## Try it yourself + +Write an incorrect version of `largest` that passes the original two checks in a different way. Then add the smallest test that separates it from the intended implementation. + +The exercise changes the question from "Do I have enough tests?" to "Which mistakes can my tests detect?" + +## References + +- [UTBoost: Rigorous Evaluation of Coding Agents on SWE-Bench](https://arxiv.org/abs/2506.09289) +- [Retromorphic Testing: A New Approach to the Test Oracle Problem](https://arxiv.org/abs/2310.06433) diff --git a/src/content/writing/reading-a-coding-agent-benchmark.md b/src/content/writing/reading-a-coding-agent-benchmark.md new file mode 100644 index 0000000000000..c2f327ba91d19 --- /dev/null +++ b/src/content/writing/reading-a-coding-agent-benchmark.md @@ -0,0 +1,71 @@ +--- +title: 'Before trusting a benchmark score, inspect the benchmark' +description: 'A practical reading guide to tasks, tests, execution conditions, and the conclusions a coding-agent result can support.' +publishedAt: 2026-09-08 +language: en +topics: [AI evaluation, Coding agents] +audience: developers and research readers +draft: true +featured: true +series: Evaluating AI in practice +order: 2 +--- + +A headline score compresses many choices into one number. For a coding agent, those choices include the task set, available tools, execution budget, test suite, and rule used to count a task as resolved. + +The number is useful when we understand what it measures. Here is a practical way to read the evidence behind it. + +## Begin with the unit of success + +Find the exact condition that marks an individual task as successful. Is it a set of passing tests? A human review? A combination of checks? Does success require avoiding regressions as well as fixing the reported issue? + +"Resolved" is an operational definition. It becomes meaningful when the benchmark documents how it is computed. + +The [previous article](/writing/passing-tests-is-not-correctness/) explains why test success and correctness are related but different claims. + +## Inspect the task distribution + +Look at the repositories, languages, task types, and time period represented in the benchmark. A result on a particular set of repository issues does not by itself establish performance on every kind of engineering work. + +Ask whether the tasks resemble the work you need the agent to do. A tool that performs well on small bug fixes may need separate evaluation for requirements discovery, security review, or long-running maintenance. + +## Read the execution conditions + +Two reported scores can be difficult to compare if the systems received different resources. + +Record the model version, tool access, context available to the agent, retry policy, time or token budget, and number of attempts. Check whether the result describes one attempt per task or selection among multiple attempts. + +These details do not make a result good or bad by themselves. They determine which comparison is justified and what cost accompanies it. + +## Examine the tests as measurement instruments + +Tests can miss incorrect behavior. Tests can also encode a mistaken expectation or depend on an unstable environment. Stronger evaluation requires checking the tests as well as the generated patches. + +Look for evidence of manual inspection, independent test construction, adversarial checks, or an analysis of false positives and false negatives. No one technique guarantees a perfect benchmark. Each can make a different weakness easier to see. + +Research such as [UTBoost](/publications/#yu2025utboost) investigates more rigorous evaluation of coding agents on SWE-Bench. Use the paper's actual methodology and scope when interpreting its findings; a title or aggregate score is not a substitute for that detail. + +## Keep a comparison record + +For the next benchmark result you read, write down: + +1. The task set and its version. +2. The success condition. +3. The execution environment and resource budget. +4. The number of attempts and any selection procedure. +5. Known limitations of the evaluation. + +If an item is not reported, record it as unknown. Avoid silently filling the gap with an assumption that makes the comparison easier. + +## Bring the question back to your own work + +A benchmark can help select candidates for a local evaluation. It cannot replace checking whether an agent handles your repositories, requirements, tools, and failure costs. + +Start with a small, representative set of tasks. Inspect both successes and failures. Keep the prompts and evaluation conditions reproducible. Expand the evaluation when you discover a new failure class. + +The useful question is specific: what evidence supports using this system for this task, under these conditions? + +## References + +- [UTBoost: Rigorous Evaluation of Coding Agents on SWE-Bench](https://arxiv.org/abs/2506.09289) +- [How Should We Build A Benchmark? Revisiting 274 Code-Related Benchmarks For LLMs](https://arxiv.org/abs/2501.10711) diff --git a/src/data/research.ts b/src/data/research.ts new file mode 100644 index 0000000000000..80009253404b7 --- /dev/null +++ b/src/data/research.ts @@ -0,0 +1,35 @@ +export const researchGroups = [ + { + id: 'coding-agents', + title: 'Evaluating coding agents', + question: 'What does a passing benchmark establish?', + description: 'Strengthening tests and examining the reliability of benchmark results.', + projects: ['swe-abs', 'utboost'], + related: [{ name: 'Benchmark design', href: '/publications/#cao2025' }], + }, + { + id: 'test-oracles', + title: 'Constructing test oracles', + question: 'How can we test without a known answer?', + description: 'Using relations between programs and executions to detect inconsistencies.', + projects: ['retromorphic-testing'], + related: [], + }, + { + id: 'ai-systems', + title: 'Testing AI systems', + question: 'Which changes should an AI system respond to?', + description: 'Controlled transformations reveal errors in vision and language systems.', + projects: ['rome', 'tin'], + related: [{ name: 'MetaIC', href: '/publications/#yu2022automated' }], + }, +]; + +export const empiricalResearch = { + id: 'aiops', + title: 'AIOps & empirical evaluation', + question: 'When is a simpler model enough?', + description: 'Studying accuracy, preprocessing, and computational cost in log anomaly detection.', + projects: ['lightad'], + related: [], +}; diff --git a/src/data/services.json b/src/data/services.json new file mode 100644 index 0000000000000..e3b93fd6eebe3 --- /dev/null +++ b/src/data/services.json @@ -0,0 +1,47 @@ +[ + { + "year": 2025, + "items": [ + "Shadow Research Track Program Committee – IEEE International Conference on Software Engineering (ICSE 2025)", + "Program Committee – IEEE International Conference on Software Analysis, Evolution and Engineering (SANER 2025)" + ] + }, + { + "year": 2024, + "items": [ + "Artifact Evaluation Committee – 18th USENIX Symposium on Operating Systems Design and Implementation (OSDI 2024)", + "Artifact Evaluation Committee – 2024 USENIX Annual Technical Conference (ATC 2024)", + "Reviewer – IEEE Transactions on Software Engineering", + "Reviewer – ACM Transactions on Software Engineering and Methodology", + "Reviewer – Journal of Systems and Software", + "External Reviewer – 46th International Conference on Software Engineering (ICSE 2024)", + "External Reviewer – ACM International Conference on the Foundations of Software Engineering (FSE 2024)", + "Artifact Evaluation Committee – ACM SIGPLAN International Conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA 2024)", + "Artifact Evaluation Committee – ACM SIGSOFT International Symposium on Software Testing and Analysis (ISSTA 2024)" + ] + }, + { + "year": 2023, + "items": [ + "Artifact Evaluation Committee – 17th USENIX Symposium on Operating Systems Design and Implementation (OSDI 2023)", + "Artifact Evaluation Committee – 2023 USENIX Annual Technical Conference (ATC 2023)", + "External Reviewer – 32nd ACM Joint European Software Engineering Conference and Symposium on the Foundations of Software Engineering (ESEC/FSE 2023)", + "External Artifact Evaluation Reviewer – ACM SIGPLAN International Conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA 2023)" + ] + }, + { + "year": 2022, + "items": [ + "Artifact Evaluation Committee – 16th USENIX Symposium on Operating Systems Design and Implementation (OSDI 2022)", + "Artifact Evaluation Committee – 2022 USENIX Annual Technical Conference (ATC 2022)", + "External Artifact Evaluation Reviewer – ACM SIGPLAN International Conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA 2022)", + "External Artifact Evaluation Reviewer – 49th ACM SIGPLAN Symposium on Principles of Programming Languages (POPL 2022)" + ] + }, + { + "year": 2021, + "items": [ + "External Artifact Evaluation Reviewer – ACM SIGPLAN International Conference on Object-Oriented Programming Systems, Languages, and Applications (OOPSLA 2021)" + ] + } +] diff --git a/src/data/site.ts b/src/data/site.ts new file mode 100644 index 0000000000000..5a48558e0da72 --- /dev/null +++ b/src/data/site.ts @@ -0,0 +1,129 @@ +export const site = { + name: 'Boxi Yu', + url: 'https://boxiyu.github.io', + role: 'Senior Research Fellow at Lero, Ireland', + email: 'boxi.yu@lero.ie', + description: + 'Boxi Yu, Senior Research Fellow at Lero, Ireland. Research on software testing, trustworthy AI, and the evaluation of coding agents.', + scholar: 'https://scholar.google.com/citations?user=Tat3jMQAAAAJ', + github: 'https://github.com/BoxiYu', + orcid: 'https://orcid.org/0000-0001-5213-7189', +}; + +export const projects = [ + { + id: 'swe-abs', + paper: 'yu2026sweabs', + name: 'SWE-ABS', + year: '2026', + venue: 'ICML', + question: 'What does a passing benchmark really prove?', + summary: + 'Coverage- and mutation-driven test augmentation rejected 19.71% of previously passing patches in our evaluation of 30 agents on SWE-Bench Verified.', + method: + 'SWE-ABS first uses program slicing to guide tests toward untested code, then uses plausible incorrect patches to generate adversarial tests that expose semantic blind spots.', + finding: + "The study strengthened tests for 50.2% of the 500 benchmark instances. The leading evaluated agent's success rate fell from 78.80% to 62.20%, and the previously top-ranked agent moved to fifth place. These figures describe the systems and benchmark evaluated in the paper.", + links: [{ label: 'Paper', href: 'https://arxiv.org/abs/2603.00520' }], + topic: 'Coding agent evaluation', + }, + { + id: 'utboost', + paper: 'yu2025utboost', + name: 'UTBoost', + year: '2025', + venue: 'ACL', + question: 'How rigorously do we evaluate coding agents?', + summary: + 'Generated unit tests exposed 345 erroneous patches that had originally passed SWE-Bench evaluation, showing how test quality changes conclusions about coding agents.', + method: + 'UTGenerator analyzes project code and dependencies to generate executable unit tests for real Python projects. UTBoost augments the benchmark test suites and re-evaluates agent patches against the stronger tests.', + finding: + 'The study identified 36 instances with insufficient tests and 345 erroneous patches previously classified as passing. Re-evaluation changed 18 leaderboard positions on SWE-Bench Lite and 11 on Verified in the studied submissions.', + links: [ + { label: 'ACL paper', href: 'https://aclanthology.org/2025.acl-long.189/' }, + { label: 'Code & test artifacts', href: 'https://github.com/CUHK-Shenzhen-SE/UTBoost' }, + { + label: 'Verified dataset', + href: 'https://huggingface.co/datasets/Bertsekas/SWE-Bench_Verified_UTBoost', + }, + ], + topic: 'Benchmark reliability', + }, + { + id: 'retromorphic-testing', + paper: 'yu2023Retro', + name: 'Retromorphic Testing', + year: '2023', + venue: 'arXiv', + question: 'How do we test without a known answer?', + summary: + 'A dual-program approach to constructing test oracles: transform an input, map the output back to the input domain, and check the resulting relation.', + method: + 'Inspired by inverse functions, a forward program and a backward program connect inputs and outputs. An auxiliary program can serve either role, allowing a relation between the original and transformed inputs to reveal inconsistencies.', + finding: + 'The paper develops three testing modes and illustrates applications to algorithms, traditional software, and AI systems. The relation depends on the programs and task; it does not require every pair of programs to be exact inverses.', + links: [ + { label: 'Preprint', href: 'https://arxiv.org/abs/2310.06433' }, + { label: 'Code', href: 'https://github.com/CUHK-Shenzhen-SE/RetromorphicTesting' }, + ], + topic: 'Automated testing', + }, + { + id: 'rome', + paper: 'yu2023rome', + name: 'ROME', + year: '2023', + venue: 'ISSTA', + question: 'Can controlled image changes reveal captioning errors?', + summary: + 'Object removal and inpainting create natural-looking image pairs for testing the consistency of image captions.', + method: + 'ROME recursively removes and inpaints objects in an image, then compares the objects mentioned in captions before and after the transformation. This turns expected changes in image content into a metamorphic test oracle.', + finding: + 'Across one commercial captioning API and four algorithms, the study reported 9,121 erroneous issues from 226 seed images, with precision ranging from 86.47% to 92.17%.', + topic: 'Trustworthy AI', + links: [ + { label: 'Paper', href: 'https://arxiv.org/abs/2306.02228' }, + { label: 'Code', href: 'https://github.com/RobustNLP/TestIC' }, + ], + }, + { + id: 'tin', + paper: 'yu2023tin', + name: 'TIN', + year: '2023', + venue: 'ESEC/FSE', + question: 'Can consistency checks both detect and repair NER errors?', + summary: + 'Metamorphic relations across similar contexts and entities support automated testing and improvement of named entity recognition systems.', + method: + 'TIN compares entity predictions across related contexts and entities, using inconsistencies to report errors and guide automatic repairs.', + finding: + 'In the evaluation of two models and the Azure and AWS APIs, 702 of 784 manually inspected reports were confirmed as errors. Automatic repair reduced errors by 26.8% to 50.6% across the evaluated systems.', + topic: 'Trustworthy AI', + links: [ + { label: 'Paper', href: 'https://arxiv.org/abs/2308.07937' }, + { label: 'Code', href: 'https://github.com/RobustNLP/TestNER' }, + ], + }, + { + id: 'lightad', + paper: 'yu2024LightAD', + name: 'LightAD', + year: '2024', + venue: 'ICSE', + question: 'When is a simpler model enough for log anomaly detection?', + summary: + 'An empirical comparison of classical and deep learning approaches examines accuracy and computational cost across five log datasets.', + method: + 'The study compares methods on HDFS, BGL, Spirit, Liberty, and Thunderbird. The accompanying LightAD toolkit combines preprocessing, deduplication, and automated model selection.', + finding: + 'LightAD makes the trade-off between F1, training time, and inference time explicit in model selection. The comparison motivates evaluating classical baselines and preprocessing choices alongside deep learning models for log-based anomaly detection.', + topic: 'AIOps', + links: [ + { label: 'Paper', href: '/assets/pdf/LightAD.pdf' }, + { label: 'Code', href: 'https://github.com/BoxiYu/LightAD' }, + ], + }, +]; diff --git a/src/env.d.ts b/src/env.d.ts new file mode 100644 index 0000000000000..a3c4e9ee490b0 --- /dev/null +++ b/src/env.d.ts @@ -0,0 +1,10 @@ +/// +declare module 'bibtex-parse-js' { + export interface BibEntry { + citationKey: string; + entryType: string; + entryTags: Record; + } + export function toJSON(input: string): BibEntry[]; + export function toBibtex(input: BibEntry[]): string; +} diff --git a/src/layouts/Base.astro b/src/layouts/Base.astro new file mode 100644 index 0000000000000..6fabc586af084 --- /dev/null +++ b/src/layouts/Base.astro @@ -0,0 +1,104 @@ +--- +import '@fontsource/source-sans-3/latin-400.css'; +import '@fontsource/source-sans-3/latin-500.css'; +import '@fontsource/source-sans-3/latin-600.css'; +import '@fontsource/source-serif-4/latin-400.css'; +import '@fontsource/source-serif-4/latin-400-italic.css'; +import '../styles/global.css'; +import { site } from '../data/site'; +import { previewDrafts } from '../lib/writing'; +interface Props { + title?: string; + description?: string; + language?: string; + noindex?: boolean; + article?: boolean; +} +const { + title, + description = site.description, + language = 'en', + noindex = false, + article = false, +} = Astro.props; +const path = Astro.url.pathname === '/404/' ? '/404.html' : Astro.url.pathname; +const canonical = new URL(path, site.url); +const navigation = [ + ['Research', '/research/'], + ['Publications', '/publications/'], + ['Service', '/services/'], + ['About', '/about/'], +]; +const fullTitle = title ? `${title} | Boxi Yu` : 'Boxi Yu | Software Testing & Trustworthy AI'; +--- + + + + + + + + {fullTitle} + + {(noindex || previewDrafts) && } + + + + + + + + + + + + + + + { + previewDrafts && ( +
+ Local editorial preview. Draft articles are excluded from the published site. +
+ ) + } + +
+ + + diff --git a/src/lib/legacy.ts b/src/lib/legacy.ts new file mode 100644 index 0000000000000..e2063535e2aa5 --- /dev/null +++ b/src/lib/legacy.ts @@ -0,0 +1,34 @@ +import { readFileSync, readdirSync } from 'node:fs'; +import { resolve } from 'node:path'; +import matter from 'gray-matter'; +import { marked } from 'marked'; + +export function legacyCollection(directory: string) { + const root = resolve(process.cwd(), directory); + return readdirSync(root) + .filter((file) => file.endsWith('.md')) + .map((file) => { + const { data, content } = matter(readFileSync(resolve(root, file), 'utf8')); + const dateString = String(data.date); + const date = + data.date instanceof Date + ? data.date + : new Date( + dateString.replace( + /^(\d{4})-(\d{1,2})-(\d{1,2})$/, + (_, y, m, d) => `${y}-${m.padStart(2, '0')}-${d.padStart(2, '0')}T00:00:00Z`, + ), + ); + return { + id: file.replace(/\.md$/, ''), + date, + html: marked.parse(content) as string, + content: content.trim(), + place: data.place as string | undefined, + }; + }) + .sort((a, b) => b.date.getTime() - a.date.getTime()); +} + +export const news = legacyCollection('_news'); +export const talks = legacyCollection('_talks'); diff --git a/src/lib/publications.ts b/src/lib/publications.ts new file mode 100644 index 0000000000000..bda0b886fd43c --- /dev/null +++ b/src/lib/publications.ts @@ -0,0 +1,55 @@ +import { readFileSync } from 'node:fs'; +import { resolve } from 'node:path'; +import bibtex from 'bibtex-parse-js'; + +const source = readFileSync(resolve(process.cwd(), '_bibliography/papers.bib'), 'utf8').replace( + /^---\s*\n---\s*\n/, + '', +); +const clean = (value = '') => + value.replace(/\\%/g, '%').replace(/[{}]/g, '').replace(/\s+/g, ' ').trim(); +const topics: Record = { + CodeAgents: 'Code agents', + AutomatedTesting: 'Automated testing', + TrustworthyAI: 'Trustworthy AI', + AIOps: 'AIOps', +}; +const localResource = (value: string) => + /^https?:\/\//.test(value) ? value : `/assets/pdf/${value}`; + +export const publications = bibtex + .toJSON(source) + .filter((entry) => entry.citationKey) + .map((entry) => { + const tags = entry.entryTags; + const links: { label: string; href: string }[] = []; + if (tags.pdf) links.push({ label: 'Paper', href: localResource(tags.pdf) }); + else if (tags.html || tags.url) links.push({ label: 'Paper', href: tags.html || tags.url }); + else if (tags.arxiv) + links.push({ label: 'Paper', href: `https://arxiv.org/abs/${tags.arxiv}` }); + if (tags.code) links.push({ label: 'Code', href: tags.code }); + if (tags.slides) links.push({ label: 'Slides', href: localResource(tags.slides) }); + return { + id: entry.citationKey, + title: clean(tags.title), + year: Number(tags.year), + authors: clean(tags.author) + .split(' and ') + .map((name) => { + if (name === 'others') return 'et al.'; + const [last, first] = name.split(', '); + return first ? `${first} ${last}` : name; + }), + venue: clean(tags.abbr || tags.journal || tags.booktitle), + topic: topics[tags.topic] || tags.topic, + abstract: clean(tags.abstract), + links, + bibtex: bibtex.toBibtex([entry]), + }; + }) + .sort((a, b) => b.year - a.year || a.title.localeCompare(b.title)); + +if (new Set(publications.map((p) => p.id)).size !== publications.length) + throw new Error('Duplicate publication keys.'); +if (publications.some((p) => !p.title || !Number.isFinite(p.year))) + throw new Error('Invalid publication metadata.'); diff --git a/src/lib/writing.ts b/src/lib/writing.ts new file mode 100644 index 0000000000000..ed5e9beea21db --- /dev/null +++ b/src/lib/writing.ts @@ -0,0 +1,39 @@ +import { getCollection } from 'astro:content'; + +// Preview drafts only in local development; production output always excludes them. +export const previewDrafts = import.meta.env.DEV && import.meta.env.CONTENT_PREVIEW === 'true'; + +export async function getWriting() { + const all = await getCollection('writing'); + const seriesPositions = new Set(); + for (const entry of all) { + if (entry.data.series) { + const position = `${entry.data.series}:${entry.data.order}`; + if (seriesPositions.has(position)) + throw new Error(`Duplicate article position in series: ${position}`); + seriesPositions.add(position); + } + if ( + entry.data.translationOf && + !all.some((other) => other.id === entry.data.translationOf && other.id !== entry.id) + ) { + throw new Error(`Invalid translation reference in ${entry.id}`); + } + } + const entries = all.filter( + ({ data }) => previewDrafts || (!data.draft && data.publishedAt.getTime() <= Date.now()), + ); + return entries.sort( + (a, b) => + b.data.publishedAt.getTime() - a.data.publishedAt.getTime() || a.id.localeCompare(b.id), + ); +} + +export function formatDate(date: Date) { + return new Intl.DateTimeFormat('en', { + year: 'numeric', + month: 'short', + day: 'numeric', + timeZone: 'UTC', + }).format(date); +} diff --git a/src/pages/404.astro b/src/pages/404.astro new file mode 100644 index 0000000000000..de3a8fc505263 --- /dev/null +++ b/src/pages/404.astro @@ -0,0 +1,16 @@ +--- +import Base from '../layouts/Base.astro'; +--- + +
+ +
diff --git a/src/pages/[...legacy].astro b/src/pages/[...legacy].astro new file mode 100644 index 0000000000000..7465934ec23fb --- /dev/null +++ b/src/pages/[...legacy].astro @@ -0,0 +1,18 @@ +--- +import Base from '../layouts/Base.astro'; +export function getStaticPaths() { + return ['blog', 'blog/2022', 'blog/2023', '2022'].map((legacy) => ({ params: { legacy } })); +} +--- + +
+ +
diff --git a/src/pages/about.astro b/src/pages/about.astro new file mode 100644 index 0000000000000..588e3979f76de --- /dev/null +++ b/src/pages/about.astro @@ -0,0 +1,118 @@ +--- +import Base from '../layouts/Base.astro'; +import { site } from '../data/site'; +--- + + +
+
+ +
+

+ I am a Senior Research Fellow at Lero, the Irish software + research centre, directed by Prof. Lionel C. Briand. +

+ I obtained my Ph.D. from The Chinese University of Hong Kong, Shenzhen in 2025, supervised by Prof. Pinjia He. +

+ My research focuses on trustworthy AI, code agents, and automated testing. I proposed + Retromorphic Testing, a technique for automatically constructing test oracles for modern + software. My work has appeared at ICML, ICSE, ISSTA, ESEC/FSE, and ACL. +

+ My recent work on UTBoost and SWE-ABS investigates how weaknesses in benchmark tests can + inflate the measured success of coding agents. Earlier work develops automated testing + methods for image captioning and named entity recognition, and examines the trade-offs + between classical and deep learning models for log anomaly detection. +

+

Research and community

+
+

Contact

+

For research discussions and collaboration enquiries:

+

{site.email}

+ +

+ You can also paste the address into your preferred email service. +

+

+
+ +
+
+
+ Portrait of Boxi Yu
Boxi Yu{site.role}
+
+
+ + + + + diff --git a/src/pages/education.astro b/src/pages/education.astro new file mode 100644 index 0000000000000..3c362b2ad539e --- /dev/null +++ b/src/pages/education.astro @@ -0,0 +1,117 @@ +--- +import Base from '../layouts/Base.astro'; +import TestLab from '../components/TestLab.astro'; +import ArticleCard from '../components/ArticleCard.astro'; +import { getWriting } from '../lib/writing'; +const entries = (await getWriting()) + .filter((entry) => entry.data.series === 'Evaluating AI in practice') + .sort((a, b) => (a.data.order || 0) - (b.data.order || 0)); +--- + + +
+ +
+
+ Start with an experiment

+ A passing test suite.
An incorrect function. +

+

+ This Python function is meant to return the largest value in a non-empty list of + integers. Two tests pass. Before adding a third, predict an input that could expose a + bug. +

+ You will practice: identifying an untested input class and distinguishing + test success from a correctness claim. +

+ Prerequisite: basic Python. This is a deterministic teaching example, not a live AI + model or a reproduction of a research benchmark. +

+
+
+ +
+
+

What changed
when the test changed?

+
    +
  1. + State the contract.

    + The answer must be an element of the non-empty input list and must be at least as + large as every other element. +

    +
  2. + Challenge the assumption.

    + Initializing the result to zero works on these positive examples. It fails when every + input is negative. +

    +
  3. + Improve the implementation and the tests.

    + Initialize from the first element, then test negative values, duplicates, zero, and + single-element lists. Define empty-input behavior explicitly. +

    +
  4. + Keep the conclusion proportional.

    + Broader tests provide stronger evidence. They do not establish that every possible + behavior of a complex AI system is correct. +

    +
  5. +
+ See a corrected implementation
{`def largest(numbers):
+    if not numbers:
+        raise ValueError("expected a non-empty list")
+    best = numbers[0]
+    for n in numbers[1:]:
+        best = max(best, n)
+    return best`}

+ This contract is for lists of integers. Other input types need their own specification. +

+
+
+
+
+
+

From example to research

Explore the research +
+

+ The same question becomes more consequential when tests are used to score coding agents. + UTBoost studies rigorous evaluation on SWE-Bench; SWE-ABS examines inflated success rates + on test-based benchmarks. +

+
+
+ { + entries.length > 0 && ( +
+ <> +
+

Evaluating AI in practice

+
+

+ Read in order: begin with the evidence a test provides, then examine the benchmark + built around it. +

+
+ {entries.map((entry) => ( + + ))} +
+ +
+ ) + } +
+ diff --git a/src/pages/feed.xml.ts b/src/pages/feed.xml.ts new file mode 100644 index 0000000000000..bbd68a009f893 --- /dev/null +++ b/src/pages/feed.xml.ts @@ -0,0 +1,24 @@ +import rss from '@astrojs/rss'; +import { getCollection } from 'astro:content'; +import { site } from '../data/site'; + +export async function GET() { + const entries = ( + await getCollection( + 'writing', + ({ data }) => !data.draft && data.publishedAt.getTime() <= Date.now(), + ) + ).sort((a, b) => b.data.publishedAt.getTime() - a.data.publishedAt.getTime()); + return rss({ + title: 'Boxi Yu - Writing', + description: site.description, + site: site.url, + items: entries.map((entry) => ({ + title: entry.data.title, + description: entry.data.description, + pubDate: entry.data.publishedAt, + link: `/writing/${entry.id}/`, + })), + customData: 'en', + }); +} diff --git a/src/pages/index.astro b/src/pages/index.astro new file mode 100644 index 0000000000000..c87ea3a7959d1 --- /dev/null +++ b/src/pages/index.astro @@ -0,0 +1,199 @@ +--- +import Base from '../layouts/Base.astro'; +import ResearchList from '../components/ResearchList.astro'; +import ResearchMap from '../components/ResearchMap.astro'; +import { researchGroups, empiricalResearch } from '../data/research'; +import { site } from '../data/site'; +import { formatDate } from '../lib/writing'; +import { news } from '../lib/legacy'; +--- + + +
+
+
+

Boxi Yu

+

+ Senior Research Fellow · Lero, Ireland +

+

+ I study how to test and evaluate software and AI systems, with a focus on coding agents, trustworthy AI, and automated testing. +

+

+ I received my Ph.D. from The Chinese University of Hong Kong, Shenzhen in 2025, advised by Prof. Pinjia He. +

+ +
+
+ Portrait of Boxi Yu +
+ Software engineering & AIBiography & contact +
+
+
+
+
+

Research overview

Methods & findings +
+ +
+
+
+

Recent news

All news +
+
    + { + news.slice(0, 3).map((item) => ( +
  • + <> + +
    + +
  • + )) + } +
+
+
+
+

Selected publications

All publications +
+ { + [...researchGroups, empiricalResearch].map((group) => ( +
+
+ <> +

{group.title}

+ Explore this direction + +
+ +
+ )) + } +
+
+
+

Academic community

+ I contribute to research through program committees, peer review, artifact evaluation, and + teaching. +

+
+
+

Service

+ SANER 2025 program committee and ICSE 2025 shadow research track committee; artifact + evaluation for OSDI, USENIX ATC, OOPSLA, and ISSTA. +

Full service record +
+
+

Teaching & talks

+ Teaching assistantships in software engineering, algorithms, and introductory programming + at CUHK-Shenzhen. +

+
+
+
+ + + diff --git a/src/pages/news/[id].astro b/src/pages/news/[id].astro new file mode 100644 index 0000000000000..78b98b5a34b4a --- /dev/null +++ b/src/pages/news/[id].astro @@ -0,0 +1,20 @@ +--- +import Base from '../../layouts/Base.astro'; +import { news } from '../../lib/legacy'; +import { formatDate } from '../../lib/writing'; +export function getStaticPaths() { + return news.map((item) => ({ params: { id: item.id }, props: { item } })); +} +const { item } = Astro.props; +const title = `Research update, ${formatDate(item.date)}`; +--- + +
+
+
diff --git a/src/pages/news/index.astro b/src/pages/news/index.astro new file mode 100644 index 0000000000000..cd611dc0261c0 --- /dev/null +++ b/src/pages/news/index.astro @@ -0,0 +1,28 @@ +--- +import Base from '../../layouts/Base.astro'; +import { news } from '../../lib/legacy'; +import { formatDate } from '../../lib/writing'; +--- + +
+
+ +
+
diff --git a/src/pages/publications.astro b/src/pages/publications.astro new file mode 100644 index 0000000000000..ab6efd1daa92a --- /dev/null +++ b/src/pages/publications.astro @@ -0,0 +1,145 @@ +--- +import Base from '../layouts/Base.astro'; +import { publications } from '../lib/publications'; +const topics = [...new Set(publications.map((p) => p.topic))]; +--- + + +
+ +
+ +
+ { + publications.map((p) => ( +
+
{p.year}
+
+ <> +

{p.title}

+

+ {p.authors.map((author, index) => ( + <> + {index > 0 && ', '} + {author === 'Boxi Yu' ? {author} : author} + + ))} +

+

+ {p.venue} / {p.topic} +

+ + {p.links.length > 0 && ( + + )} + {p.abstract && ( +
+ Abstract +

{p.abstract}

+
+ )} +
+ <> + BibTeX +
+                      {p.bibtex}
+                    
+ + + +
+
+
+ )) + } +
+ +
+
+ + diff --git a/src/pages/research.astro b/src/pages/research.astro new file mode 100644 index 0000000000000..f2664e332653c --- /dev/null +++ b/src/pages/research.astro @@ -0,0 +1,141 @@ +--- +import Base from '../layouts/Base.astro'; +import { projects, site } from '../data/site'; +const themes = [ + { + id: 'coding-agents', + title: 'Evaluating coding agents', + description: + "A patch can pass a benchmark's tests and still be wrong. I investigate how test adequacy affects measured agent performance, and how to make the evaluation harder to satisfy with incorrect behavior.", + projects: ['swe-abs', 'utboost'], + }, + { + id: 'test-oracles', + title: 'Constructing test oracles', + description: + 'For many programs, specifying the right answer is harder than running the program. My work explores relations between executions and between programs as a way to detect failures without enumerating correct outputs.', + projects: ['retromorphic-testing'], + }, + { + id: 'ai-systems', + title: 'Testing AI systems', + description: + 'AI systems produce outputs that can be difficult to assess automatically. Controlled transformations and consistency relations provide practical ways to uncover mistakes in language and vision systems.', + projects: ['rome', 'tin'], + }, + { + id: 'aiops', + title: 'Empirical evaluation for AIOps', + description: + 'Reliable operational tools need evidence about accuracy, efficiency, and the impact of data preprocessing. I study these choices in log-based anomaly detection.', + projects: ['lightad'], + }, +]; +--- + + +
+ + + { + themes.map((theme) => ( +
+
+ <> +

{theme.title}

+

{theme.description}

+ +
+
+ {theme.projects.map((id) => { + const project = projects.find((project) => project.id === id)!; + return ( +
+

+ {project.name} / {project.venue} {project.year} + {project.venue === 'arXiv' ? ' (preprint)' : ''} +

+

{project.question}

+
+
Approach
+
{project.method}
+
Findings & contribution
+
{project.finding}
+
+ {id === 'retromorphic-testing' && ( +
+
    +
  1. Original input
  2. +
  3. Forward program
  4. +
  5. Output
  6. +
  7. Backward program
  8. +
  9. Transformed input
  10. +
+
+ Check the expected relation between the original and transformed inputs. A + conceptual view of the dual-program architecture. +
+
+ )} + +
+ ); + })} + {theme.id === 'coding-agents' && ( + + )} + {theme.id === 'ai-systems' && ( + + )} +
+
+ )) + } +
+ diff --git a/src/pages/services.astro b/src/pages/services.astro new file mode 100644 index 0000000000000..c64bc84c2fcfd --- /dev/null +++ b/src/pages/services.astro @@ -0,0 +1,31 @@ +--- +import Base from '../layouts/Base.astro'; +import services from '../data/services.json'; +--- + +
+
+ { + services.map((section) => ( +
+ <> +

{section.year}

+
    + {section.items.map((item) => ( +
  • {item}
  • + ))} +
+ +
+ )) + } +
+
diff --git a/src/pages/sitemap.xml.ts b/src/pages/sitemap.xml.ts new file mode 100644 index 0000000000000..e3b05d38192d5 --- /dev/null +++ b/src/pages/sitemap.xml.ts @@ -0,0 +1,36 @@ +import { getCollection } from 'astro:content'; +import { site } from '../data/site'; +import { news, talks } from '../lib/legacy'; + +export async function GET() { + const entries = await getCollection( + 'writing', + ({ data }) => !data.draft && data.publishedAt.getTime() <= Date.now(), + ); + const paths = [ + '/', + '/research/', + '/publications/', + '/writing/', + '/education/', + '/about/', + '/services/', + '/teaching/', + '/talks/', + '/news/', + ...news.map((item) => `/news/${item.id}/`), + ...talks.map((item) => `/talks/${item.id}/`), + ...entries.map((entry) => `/writing/${entry.id}/`), + ]; + const xmlEscape = (value: string) => + value + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + return new Response( + `${paths.map((path) => `${xmlEscape(new URL(path, site.url).href)}`).join('')}`, + { headers: { 'Content-Type': 'application/xml' } }, + ); +} diff --git a/src/pages/talks/[id].astro b/src/pages/talks/[id].astro new file mode 100644 index 0000000000000..81eb9fa0f1c8c --- /dev/null +++ b/src/pages/talks/[id].astro @@ -0,0 +1,23 @@ +--- +import Base from '../../layouts/Base.astro'; +import { talks } from '../../lib/legacy'; +import { formatDate } from '../../lib/writing'; +export function getStaticPaths() { + return talks.map((talk) => ({ params: { id: talk.id }, props: { talk } })); +} +const { talk } = Astro.props; +--- + +
+ diff --git a/src/pages/talks/index.astro b/src/pages/talks/index.astro new file mode 100644 index 0000000000000..5ac81ba667db4 --- /dev/null +++ b/src/pages/talks/index.astro @@ -0,0 +1,32 @@ +--- +import Base from '../../layouts/Base.astro'; +import { talks } from '../../lib/legacy'; +import { formatDate } from '../../lib/writing'; +--- + +
+
+
    + { + talks.map((talk) => ( +
  • + <> + +
    + <> +
    +

    {talk.place}

    + Talk details + +
    + +
  • + )) + } +
+
+
diff --git a/src/pages/teaching.astro b/src/pages/teaching.astro new file mode 100644 index 0000000000000..7f10ee5b4a132 --- /dev/null +++ b/src/pages/teaching.astro @@ -0,0 +1,24 @@ +--- +import Base from '../layouts/Base.astro'; +--- + +
+
+
    +
  • 2022-2023, semester 2: CSC4001, Software Engineering
  • + 2022-2023, semester 1: DDA6050, Analysis of Algorithms +
  • 2021-2022, semester 2: CSC4001, Software Engineering
  • + 2021-2022, semester 1: CSC1001, Introduction to Computer Science: Programming + Methodology +
  • +
+
+
diff --git a/src/pages/writing/[...id].astro b/src/pages/writing/[...id].astro new file mode 100644 index 0000000000000..7de57bc19fae3 --- /dev/null +++ b/src/pages/writing/[...id].astro @@ -0,0 +1,100 @@ +--- +import { render } from 'astro:content'; +import Base from '../../layouts/Base.astro'; +import { getWriting, formatDate } from '../../lib/writing'; +export async function getStaticPaths() { + const entries = await getWriting(); + return entries.map((entry) => ({ params: { id: entry.id }, props: { entry, entries } })); +} +const { entry, entries } = Astro.props; +const { Content, headings } = await render(entry); +const series = entry.data.series + ? entries + .filter((item) => item.data.series === entry.data.series) + .sort((a, b) => (a.data.order || 0) - (b.data.order || 0)) + : []; +const related = entries + .filter( + (item) => + item.id !== entry.id && item.data.topics.some((topic) => entry.data.topics.includes(topic)), + ) + .slice(0, 2); +--- + + + { + entry.data.updatedAt && ( + + ) + } +
+ + { + entry.data.draft && ( +
+ Editorial draft. Prepared for review. This article is visible only in + local draft preview and is not included in the published site or RSS feed. +
+ ) + } +
+
+ + { + related.length > 0 && ( + + ) + } +
+
+
+ diff --git a/src/pages/writing/index.astro b/src/pages/writing/index.astro new file mode 100644 index 0000000000000..11db540f1f993 --- /dev/null +++ b/src/pages/writing/index.astro @@ -0,0 +1,104 @@ +--- +import Base from '../../layouts/Base.astro'; +import ArticleCard from '../../components/ArticleCard.astro'; +import { getWriting } from '../../lib/writing'; +const entries = await getWriting(); +const topics = [...new Set(entries.flatMap((entry) => entry.data.topics))]; +--- + + +
+ +
+ { + entries.length ? ( + <> + + <> +
+ {entries.map((entry) => ( + + ))} +
+ + + + ) : ( +
+ <> +
+ <> +

+ The first notes are in preparation. +

+

+ For now, start with a hands-on example of test quality, or explore the research + behind it. New published articles will appear in the RSS feed. +

+ +
+ Explore the example + +
+ ) + } +
+
+ + diff --git a/src/styles/global.css b/src/styles/global.css new file mode 100644 index 0000000000000..93eb4ce510a4e --- /dev/null +++ b/src/styles/global.css @@ -0,0 +1,1143 @@ +@layer reset, base, components, utilities; + +@layer reset { + *, + *::before, + *::after { + box-sizing: border-box; + } + body, + h1, + h2, + h3, + p, + figure { + margin: 0; + } + img, + svg { + display: block; + max-width: 100%; + } + img { + height: auto; + } + button, + input, + select { + font: inherit; + } + button, + a { + -webkit-tap-highlight-color: transparent; + } +} + +@layer base { + :root { + --paper: #fff; + --ink: #243247; + --muted: #536176; + --blue: #2454c6; + --blue-dark: #153f9e; + --wash: #f3f6fa; + --line: #d8e0ea; + --serif: 'Source Serif 4', Georgia, serif; + --sans: 'Source Sans 3', 'Noto Sans SC', sans-serif; + } + html { + scroll-behavior: smooth; + scroll-padding-top: 2rem; + } + body { + font-family: var(--sans); + font-size: 18px; + line-height: 1.6; + color: var(--ink); + background: var(--paper); + } + a { + color: var(--blue); + text-underline-offset: 0.23em; + text-decoration-thickness: 1px; + } + a:hover { + color: var(--blue-dark); + } + :focus-visible { + outline: 3px solid var(--blue); + outline-offset: 5px; + } + h1, + h2, + h3 { + font-weight: 400; + line-height: 1.15; + text-wrap: balance; + } + h1, + h2 { + font-family: var(--serif); + letter-spacing: -0.035em; + } + h1 { + font-size: clamp(2.8rem, 6.4vw, 5.2rem); + } + h2 { + font-size: clamp(2rem, 3.6vw, 3rem); + } + h3 { + font-size: 1.35rem; + font-weight: 600; + letter-spacing: -0.015em; + } + button { + cursor: pointer; + } + ::selection { + background: #dce7ff; + color: var(--ink); + } + [hidden] { + display: none !important; + } +} + +@layer components { + .academic-hero { + padding-block: 58px; + gap: 72px; + } + .academic-hero h1 { + margin-bottom: 8px; + font-size: clamp(3.5rem, 6vw, 4.7rem); + } + .academic-role { + margin-bottom: 24px; + font-size: 20px; + } + .bio-note { + margin-top: 16px; + max-width: 660px; + color: var(--muted); + } + .research-directions { + background: linear-gradient(110deg, var(--wash), var(--paper)); + padding-inline: 20px; + } + .research-item.selected-paper { + grid-template-columns: 145px minmax(0, 1fr); + } + .selected-paper h4 { + margin: 0; + font-size: 1.2rem; + font-weight: 600; + line-height: 1.4; + } + .selected-paper .selected-authors { + font-size: 15px; + line-height: 1.55; + } + .preprint-note { + display: block; + font-size: 13px; + } + .academic-community { + display: grid; + grid-template-columns: 1.1fr 1fr 1fr; + gap: 36px; + } + .academic-community h2 { + font-size: 2.2rem; + } + .academic-community p { + margin-block: 16px; + color: var(--muted); + font-size: 17px; + } + .research-jump { + display: flex; + flex-wrap: wrap; + gap: 12px 28px; + padding-block: 20px; + border-block: 1px solid var(--line); + font-size: 16px; + } + .research-theme { + display: grid; + grid-template-columns: 280px minmax(0, 1fr); + gap: 68px; + } + .theme-heading h2 { + font-size: 2.2rem; + } + .theme-heading p { + margin-top: 20px; + color: var(--muted); + font-size: 17px; + } + .research-detail + .research-detail { + margin-top: 40px; + padding-top: 36px; + border-top: 1px solid var(--line); + } + .paper-context { + color: var(--blue); + font-size: 15px; + margin-bottom: 12px; + } + .research-detail h3 { + font-size: 1.5rem; + line-height: 1.35; + } + .research-detail dl { + margin: 20px 0 0; + } + .research-detail dt { + font-weight: 600; + font-size: 16px; + margin-top: 18px; + } + .research-detail dd { + margin: 4px 0 0; + color: var(--muted); + } + .related-research { + margin-top: 36px; + padding: 24px; + background: var(--wash); + border-left: 2px solid var(--blue); + } + .related-research p { + margin-top: 12px; + font-size: 17px; + } + .related-research .source-note { + color: var(--muted); + font-size: 14px; + } + .oracle-diagram { + margin-top: 24px; + padding: 20px; + border: 1px solid var(--line); + } + .oracle-diagram ol { + display: flex; + align-items: center; + justify-content: space-between; + padding: 0; + margin: 0; + gap: 12px; + list-style: none; + font-size: 14px; + line-height: 1.35; + } + .oracle-diagram li { + flex: 1; + } + .oracle-diagram li + li::before { + content: '\2192'; + display: block; + color: var(--blue); + margin-bottom: 8px; + } + .oracle-diagram figcaption { + border-top: 1px dashed var(--line); + padding-top: 12px; + margin-top: 16px; + font-size: 14px; + color: var(--muted); + } + .service-year { + display: grid; + grid-template-columns: 130px minmax(0, 1fr); + gap: 32px; + border-top: 1px solid var(--line); + padding-block: 28px; + } + .service-year h2 { + font-size: 2rem; + } + .service-year ul { + margin: 0; + padding-left: 20px; + } + .service-year li + li { + margin-top: 12px; + } + @media (max-width: 900px) { + .research-theme { + grid-template-columns: 220px minmax(0, 1fr); + gap: 36px; + } + .academic-community { + grid-template-columns: 1fr 1fr; + } + .academic-community > :first-child { + grid-column: 1 / -1; + } + } + @media (max-width: 640px) { + .research-item.selected-paper, + .research-theme, + .academic-community, + .service-year { + grid-template-columns: minmax(0, 1fr); + gap: 24px; + } + .research-item.selected-paper { + gap: 10px; + } + .academic-role { + font-size: 18px; + } + .research-directions { + padding-inline: 16px; + } + .oracle-diagram ol { + flex-direction: column; + align-items: start; + gap: 8px; + } + .oracle-diagram li + li::before { + content: '\2193'; + margin-bottom: 5px; + } + } + .wrapper { + width: min(1120px, calc(100% - 96px)); + margin-inline: auto; + } + .site-header { + min-height: 108px; + display: flex; + gap: 40px; + align-items: center; + border-bottom: 1px solid var(--line); + } + .wordmark { + display: flex; + align-items: center; + gap: 12px; + font-size: 23px; + font-weight: 600; + text-decoration: none; + color: var(--ink); + white-space: nowrap; + } + .wordmark svg { + color: var(--blue); + } + .site-header nav { + display: flex; + gap: 29px; + margin-left: auto; + } + .site-header nav a { + color: var(--muted); + font-size: 16px; + text-decoration: none; + position: relative; + } + .site-header nav a:hover, + .site-header nav a[aria-current] { + color: var(--blue); + } + .site-header nav a[aria-current]::after { + content: ''; + position: absolute; + bottom: -9px; + left: 0; + right: 0; + height: 2px; + background: var(--blue); + } + .header-contact { + font-size: 15px; + text-decoration: none; + color: var(--ink); + border-left: 1px solid var(--line); + padding-left: 26px; + white-space: nowrap; + } + .header-contact span { + margin-left: 6px; + } + .hero { + padding-block: 78px 66px; + display: grid; + grid-template-columns: 1fr 244px; + gap: 90px; + align-items: center; + } + .hero h1 { + max-width: 780px; + margin-bottom: 26px; + } + .hero .intro { + max-width: 620px; + font-size: 21px; + line-height: 1.65; + color: var(--muted); + } + .hero .intro strong { + font-weight: 600; + color: var(--ink); + } + .hero-links { + display: flex; + flex-wrap: wrap; + gap: 24px; + margin-top: 26px; + font-size: 16px; + } + .portrait { + position: relative; + } + .portrait img { + width: 100%; + aspect-ratio: 4/4.6; + object-fit: cover; + object-position: center 30%; + background: var(--wash); + border-radius: 3px; + } + .portrait figcaption { + font-size: 14px; + padding-top: 20px; + color: var(--muted); + line-height: 1.55; + } + .portrait figcaption strong { + color: var(--ink); + font-size: 16px; + font-weight: 600; + display: block; + } + .entry-links { + display: grid; + grid-template-columns: repeat(3, 1fr); + padding-block: 26px; + border-block: 1px solid var(--line); + gap: 32px; + } + .entry-links a { + color: var(--ink); + text-decoration: none; + display: grid; + grid-template-columns: 1fr auto; + gap: 4px 14px; + } + .entry-links a span { + color: var(--muted); + font-size: 15px; + grid-column: 1; + } + .entry-links a b { + font-weight: 600; + font-size: 19px; + } + .entry-links a i { + grid-column: 2; + grid-row: 1; + color: var(--blue); + font-style: normal; + } + .entry-links a:hover b { + color: var(--blue); + } + .section { + padding-block: 68px; + } + .section + .section { + border-top: 1px solid var(--line); + } + .section-heading { + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 24px; + margin-bottom: 30px; + } + .section-heading > a { + font-size: 16px; + flex-shrink: 0; + } + .section-intro { + color: var(--muted); + max-width: 650px; + margin-top: -10px; + margin-bottom: 30px; + } + .lab-feature { + display: grid; + grid-template-columns: 0.9fr 1.1fr; + gap: 62px; + align-items: center; + } + .lab-feature h2 { + font-size: clamp(2.3rem, 4.5vw, 3.6rem); + } + .lab-feature p { + margin-block: 22px; + color: var(--muted); + max-width: 460px; + } + .text-link { + display: inline-flex; + align-items: center; + gap: 16px; + font-size: 17px; + } + .topic-label { + color: var(--blue); + font-size: 15px; + display: block; + margin-bottom: 15px; + } + .research-list { + display: grid; + gap: 0; + } + .research-item { + display: grid; + grid-template-columns: 160px 1fr auto; + gap: 32px; + padding-block: 28px; + border-top: 1px solid var(--line); + align-items: start; + } + .research-item:first-child { + border-top: 0; + padding-top: 0; + } + .research-item .venue { + color: var(--muted); + font-size: 15px; + } + .research-item .venue b { + display: block; + font-size: 17px; + color: var(--ink); + font-weight: 600; + } + .research-item h4 a { + color: var(--ink); + text-decoration: none; + } + .research-item h4 a:hover { + color: var(--blue); + } + .research-item p { + color: var(--muted); + font-size: 17px; + max-width: 660px; + margin-top: 9px; + } + .research-item > a { + font-size: 16px; + } + .article-list { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 38px; + } + .article-card { + padding: 26px 0; + border-top: 2px solid var(--ink); + } + .article-card :is(h2, h3) { + font-family: var(--serif); + font-size: 1.8rem; + font-weight: 400; + line-height: 1.3; + } + .article-card :is(h2, h3) a { + color: var(--ink); + text-decoration: none; + } + .article-card :is(h2, h3) a:hover { + color: var(--blue); + } + .article-meta { + font-size: 14px; + color: var(--muted); + display: flex; + gap: 12px; + flex-wrap: wrap; + margin-bottom: 16px; + align-items: center; + } + .article-card p { + margin-top: 16px; + color: var(--muted); + font-size: 17px; + } + .draft-tag { + border: 1px solid #b2bfd3; + padding: 1px 7px; + color: var(--muted); + font-size: 12px; + border-radius: 3px; + } + .writing-empty { + background: var(--wash); + padding: 32px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 32px; + } + .writing-empty p { + max-width: 680px; + color: var(--muted); + } + .writing-empty a { + flex-shrink: 0; + } + .news-list { + padding: 0; + list-style: none; + display: grid; + gap: 24px; + } + .news-list li { + display: grid; + grid-template-columns: 130px 1fr; + gap: 24px; + } + .news-list time { + color: var(--muted); + font-size: 15px; + padding-top: 3px; + } + .news-list p { + font-size: 17px; + } + .page-header { + padding-block: 70px 52px; + max-width: 840px; + } + .page-header h1 { + margin-bottom: 22px; + } + .page-header p { + font-size: 21px; + line-height: 1.65; + color: var(--muted); + max-width: 740px; + } + .page-header .back-link { + display: inline-block; + font-size: 15px; + margin-bottom: 26px; + } + .page-body { + padding-bottom: 80px; + } + .resource-links { + display: flex; + flex-wrap: wrap; + gap: 14px 24px; + align-items: center; + font-size: 15px; + margin-top: 18px; + } + .filter-bar { + display: flex; + flex-wrap: wrap; + gap: 14px; + align-items: end; + margin-bottom: 40px; + padding: 20px 24px; + background: var(--wash); + } + .filter-bar label { + font-size: 14px; + display: grid; + gap: 5px; + } + .filter-bar label:first-child { + flex: 1 1 260px; + } + .filter-bar input, + .filter-bar select { + min-height: 44px; + padding: 8px 12px; + border: 1px solid #aab8cc; + border-radius: 3px; + background: white; + color: var(--ink); + min-width: 0; + width: 100%; + } + .filter-bar output { + font-size: 14px; + padding-bottom: 10px; + color: var(--muted); + } + .publication { + display: grid; + grid-template-columns: 90px 1fr; + gap: 25px; + padding: 30px 0; + border-top: 1px solid var(--line); + scroll-margin-top: 24px; + } + .publication:target { + background: var(--wash); + outline: 10px solid var(--wash); + } + .publication .pub-year { + font-family: var(--serif); + font-size: 25px; + } + .publication h2 { + font-family: var(--sans); + font-weight: 600; + font-size: 21px; + line-height: 1.35; + letter-spacing: -0.012em; + } + .publication .authors { + color: var(--muted); + font-size: 16px; + margin-top: 12px; + } + .publication .authors strong { + color: var(--ink); + font-weight: 600; + } + .publication .pub-venue { + color: var(--blue); + font-size: 15px; + margin-top: 8px; + } + details { + margin-top: 16px; + } + summary { + cursor: pointer; + color: var(--blue); + font-size: 15px; + width: fit-content; + } + details > p { + font-size: 16px; + margin-top: 12px; + color: var(--muted); + } + pre { + overflow-x: auto; + padding: 22px; + border: 1px solid var(--line); + border-radius: 4px; + font-size: 14px; + line-height: 1.65; + } + code { + font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', monospace; + font-size: 0.86em; + } + pre code { + font-size: inherit; + } + .copy-button { + margin-top: 8px; + padding: 5px 12px; + background: var(--wash); + color: var(--ink); + border: 1px solid var(--line); + border-radius: 3px; + font-size: 14px; + } + .about-grid { + display: grid; + grid-template-columns: 1fr 250px; + gap: 80px; + align-items: start; + } + .about-grid .portrait { + margin-top: 72px; + } + .prose { + max-width: 720px; + overflow-wrap: break-word; + } + .prose > * + * { + margin-top: 1.25em; + } + .prose h2 { + margin-top: 2em; + font-size: 2rem; + } + .prose h3 { + margin-top: 1.8em; + } + .prose p, + .prose li { + line-height: 1.8; + } + .prose ul, + .prose ol { + padding-left: 1.3em; + } + .prose li + li { + margin-top: 0.5em; + } + .prose blockquote { + margin-left: 0; + padding: 12px 24px; + border-left: 3px solid var(--blue); + color: var(--muted); + background: var(--wash); + } + .prose :not(pre) > code { + padding: 0.15em 0.3em; + background: var(--wash); + border-radius: 3px; + } + .article-layout { + display: grid; + grid-template-columns: minmax(0, 720px) 220px; + gap: 70px; + align-items: start; + padding-bottom: 80px; + } + .article-layout .prose { + font-size: 20px; + } + .article-layout aside { + position: sticky; + top: 32px; + font-size: 15px; + border-left: 1px solid var(--line); + padding-left: 24px; + } + .article-layout aside a { + display: block; + color: var(--muted); + margin-top: 12px; + text-decoration: none; + } + .article-layout aside a:hover { + color: var(--blue); + } + .article-layout aside strong { + font-weight: 600; + } + .article-bottom { + border-top: 1px solid var(--line); + padding-top: 30px; + margin-top: 50px; + } + .notice { + padding: 18px 24px; + border-left: 3px solid var(--blue); + background: var(--wash); + font-size: 16px; + margin-bottom: 30px; + } + .learning-grid { + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + gap: 64px; + align-items: start; + } + .learning-grid .prose { + font-size: 18px; + } + .learning-steps { + padding-left: 24px; + } + .learning-steps li { + margin-bottom: 24px; + padding-left: 8px; + } + .learning-steps li::marker { + color: var(--blue); + font-family: var(--serif); + font-size: 24px; + } + .learning-steps strong { + display: block; + font-weight: 600; + } + .learning-steps p { + color: var(--muted); + margin-top: 5px; + } + .site-footer { + border-top: 1px solid var(--line); + padding-block: 36px 40px; + display: flex; + align-items: start; + gap: 40px; + font-size: 15px; + } + .footer-name { + color: var(--ink); + font-size: 20px; + font-weight: 600; + text-decoration: none; + } + .site-footer p { + color: var(--muted); + margin-top: 5px; + } + .site-footer nav { + margin-left: auto; + display: flex; + gap: 22px; + padding-top: 7px; + } + .site-footer nav a { + color: var(--muted); + text-decoration: none; + } + .site-footer .copyright { + font-size: 13px; + padding-top: 5px; + } + .preview-banner { + padding: 7px 24px; + background: #eaf0ff; + color: #23458c; + text-align: center; + font-size: 13px; + } + .skip-link { + position: absolute; + left: 20px; + top: -100px; + padding: 12px; + background: white; + z-index: 10; + } + .skip-link:focus { + top: 12px; + } + .empty-result { + padding: 36px 0; + color: var(--muted); + } +} + +@layer utilities { + .muted { + color: var(--muted); + } + .sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; + border: 0; + } + .mt { + margin-top: 24px; + } + @media (max-width: 1000px) { + .wrapper { + width: calc(100% - 64px); + } + .hero { + gap: 42px; + grid-template-columns: 1fr 210px; + } + .hero h1 { + font-size: clamp(3rem, 6.5vw, 4.3rem); + } + .header-contact { + display: none; + } + .lab-feature { + gap: 36px; + } + .article-layout { + grid-template-columns: minmax(0, 1fr); + } + .article-layout aside { + display: none; + } + .site-footer { + flex-wrap: wrap; + gap: 24px; + } + .site-footer .copyright { + width: 100%; + } + } + @media (max-width: 680px) { + body { + font-size: 17px; + } + .wrapper { + width: calc(100% - 40px); + } + .site-header { + min-height: auto; + padding-block: 22px 19px; + gap: 20px; + flex-wrap: wrap; + } + .wordmark { + font-size: 22px; + } + .site-header nav { + width: 100%; + margin: 0; + gap: 0; + justify-content: space-between; + } + .site-header nav a { + font-size: 15px; + padding-block: 3px; + } + .site-header nav a[aria-current]::after { + bottom: -4px; + } + .hero { + display: flex; + flex-direction: column; + align-items: start; + gap: 32px; + padding-block: 42px 32px; + } + .hero h1 { + font-size: clamp(2.65rem, 10vw, 4rem); + } + .hero .intro { + font-size: 19px; + } + .hero .portrait { + display: flex; + gap: 17px; + align-items: center; + } + .hero .portrait img { + width: 74px; + height: 84px; + object-position: top; + } + .hero .portrait figcaption { + padding: 0; + } + .hero-links { + gap: 18px; + } + .entry-links { + grid-template-columns: 1fr; + gap: 20px; + padding-block: 23px; + } + .entry-links a b { + font-size: 18px; + } + .entry-links a span { + font-size: 15px; + } + .section { + padding-block: 43px; + } + .section-heading { + align-items: start; + flex-direction: column; + gap: 12px; + margin-bottom: 24px; + } + .section-heading h2 { + font-size: 2.2rem; + } + .lab-feature, + .article-list, + .learning-grid, + .about-grid { + grid-template-columns: 1fr; + gap: 28px; + } + .lab-feature h2 { + font-size: 2.5rem; + } + .research-item { + grid-template-columns: 1fr; + gap: 10px; + } + .research-item .venue b { + display: inline; + margin-right: 12px; + } + .research-item > a { + margin-top: 4px; + } + .article-list { + gap: 8px; + } + .writing-empty { + padding: 24px; + align-items: start; + flex-direction: column; + gap: 15px; + } + .news-list li { + grid-template-columns: 1fr; + gap: 6px; + } + .page-header { + padding-block: 42px 32px; + } + .page-header p { + font-size: 19px; + } + .publication { + grid-template-columns: 1fr; + gap: 10px; + } + .publication .pub-year { + font-size: 20px; + } + .publication h2 { + font-size: 20px; + } + .about-grid .portrait { + display: none; + } + .article-layout .prose { + font-size: 18px; + } + .filter-bar { + padding: 18px; + } + .filter-bar label { + flex: 1 1 100%; + } + .filter-bar output { + padding: 0; + } + .site-footer { + flex-direction: column; + gap: 22px; + } + .site-footer nav { + margin-left: 0; + flex-wrap: wrap; + } + .site-footer .copyright { + padding: 0; + } + } + @media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } + *, + *::before, + *::after { + animation: none !important; + transition: none !important; + } + } +} diff --git a/tests/site.test.mjs b/tests/site.test.mjs new file mode 100644 index 0000000000000..94fd5a6d3b0cc --- /dev/null +++ b/tests/site.test.mjs @@ -0,0 +1,264 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { readFile, readdir, access, mkdtemp, cp, symlink, writeFile, rm } from 'node:fs/promises'; +import { resolve, join, extname } from 'node:path'; +import { tmpdir } from 'node:os'; +import { execFileSync } from 'node:child_process'; +import { load } from 'cheerio'; +import matter from 'gray-matter'; +import bibtex from 'bibtex-parse-js'; + +const root = process.cwd(); +const dist = resolve(root, 'dist'); +const exists = async (path) => + access(path).then( + () => true, + () => false, + ); +async function filesAt(directory) { + const entries = await readdir(directory, { withFileTypes: true }); + return ( + await Promise.all( + entries.map((entry) => + entry.isDirectory() ? filesAt(join(directory, entry.name)) : join(directory, entry.name), + ), + ) + ).flat(); +} +const htmlFiles = (await filesAt(dist)).filter((file) => file.endsWith('.html')); +const routeFile = (pathname) => + join(dist, decodeURIComponent(pathname), extname(pathname) ? '' : 'index.html'); + +test('academic service preserves every legacy year and committee role', async () => { + const legacy = load(await readFile('_layouts/services.html', 'utf8')); + const current = load(await readFile(join(dist, 'services/index.html'), 'utf8')); + const normalize = (text) => text.replace(/\s+/g, ' ').trim(); + const expected = legacy('main section') + .toArray() + .map((section) => ({ + year: normalize(legacy(section).find('h2').text()), + items: legacy(section) + .find('li') + .toArray() + .map((item) => normalize(legacy(item).text())), + })); + const actual = current('.service-year') + .toArray() + .map((section) => ({ + year: normalize(current(section).find('h2').text()), + items: current(section) + .find('li') + .toArray() + .map((item) => normalize(current(item).text())), + })); + assert.deepEqual(actual, expected); +}); + +test('retains publication keys, authors, chronology, citations, and PDF files', async () => { + const source = (await readFile('_bibliography/papers.bib', 'utf8')).replace( + /^---\s*\n---\s*\n/, + '', + ); + const entries = bibtex.toJSON(source).filter((entry) => entry.citationKey); + const $ = load(await readFile(join(dist, 'publications/index.html'), 'utf8')); + assert.equal($('.publication').length, entries.length); + for (const entry of entries) { + const publication = $(`[id="${entry.citationKey}"]`); + assert.equal(publication.length, 1, `Missing publication ${entry.citationKey}`); + assert.ok( + publication + .find('.resource-links a') + .toArray() + .some((link) => $(link).text() === 'Paper'), + `Missing paper link for ${entry.citationKey}`, + ); + assert.equal(publication.find('.authors strong').text(), 'Boxi Yu'); + for (const author of entry.entryTags.author.split(' and ')) { + const [last, first] = author.split(', '); + const display = author === 'others' ? 'et al.' : first ? `${first} ${last}` : last; + assert.ok(publication.find('.authors').text().includes(display), `Missing author ${display}`); + } + assert.equal( + bibtex.toJSON(publication.find('pre code').text())[0].citationKey, + entry.citationKey, + ); + } + const years = $('.pub-year') + .map((_, el) => Number($(el).text())) + .get(); + assert.deepEqual( + years, + [...years].sort((a, b) => b - a), + ); + for (const file of await readdir('assets/pdf')) { + assert.deepEqual( + await readFile(join(dist, 'assets/pdf', file)), + await readFile(join('assets/pdf', file)), + ); + } +}); + +test('generated pages have valid internal links, fragments, assets, and metadata', async () => { + const failures = []; + for (const file of htmlFiles) { + const $ = load(await readFile(file, 'utf8')); + assert.equal($('h1').length, 1, `${file}: expected one h1`); + assert.ok($('html').attr('lang'), `${file}: missing language`); + assert.ok($('meta[name="description"]').attr('content'), `${file}: missing description`); + for (const code of $('.lab-code code').toArray()) { + assert.match( + $(code).text(), + /def\s+largest\(numbers\):/, + `${file}: Python token spacing lost`, + ); + } + const relative = file.slice(dist.length).replace(/index\.html$/, ''); + assert.equal($('link[rel="canonical"]').attr('href'), `https://boxiyu.github.io${relative}`); + const ids = $('[id]') + .map((_, el) => $(el).attr('id')) + .get(); + assert.equal(new Set(ids).size, ids.length, `${file}: duplicate IDs`); + for (const el of $( + 'a[href], link[href], script[src], img[src], meta[property="og:image"]', + ).toArray()) { + const raw = $(el).attr('href') || $(el).attr('src') || $(el).attr('content'); + if (!raw || /^(mailto:|data:|tel:)/.test(raw)) continue; + const url = new URL(raw, `https://boxiyu.github.io${relative}`); + if (url.origin !== 'https://boxiyu.github.io') continue; + const target = routeFile(url.pathname); + if (!(await exists(target))) { + failures.push(`${relative}: missing ${raw}`); + continue; + } + if (url.hash && target.endsWith('.html')) { + const targetDoc = load(await readFile(target, 'utf8')); + const id = decodeURIComponent(url.hash.slice(1)); + if ( + !targetDoc('[id]') + .toArray() + .some((node) => targetDoc(node).attr('id') === id) + ) + failures.push(`${relative}: missing fragment ${raw}`); + } + } + } + assert.deepEqual(failures, []); +}); + +test('draft content is absent from every production artifact', async () => { + const articleFiles = (await filesAt('src/content/writing')).filter((path) => + /\.mdx?$/.test(path), + ); + const artifacts = (await filesAt(dist)).filter((file) => /\.(html|xml|json|js)$/.test(file)); + const combined = (await Promise.all(artifacts.map((file) => readFile(file, 'utf8')))).join('\n'); + for (const file of articleFiles) { + const { data } = matter(await readFile(file, 'utf8')); + if (data.draft) assert.ok(!combined.includes(data.title), `Draft title leaked: ${data.title}`); + } + assert.ok(!combined.includes('Editorial draft')); + assert.ok(!combined.includes('Local editorial preview')); +}); + +test('legacy routes and feeds remain available without shipping template source', async () => { + for (const path of [ + '/about/', + '/publications/', + '/services/', + '/teaching/', + '/talks/', + '/talks/utboost/', + '/news/', + '/blog/', + '/blog/2022/', + '/blog/2023/', + '/feed.xml', + '/sitemap.xml', + '/404.html', + ]) { + assert.ok(await exists(routeFile(path)), `Missing compatibility URL ${path}`); + } + for (const file of await readdir('_news')) { + if (file.endsWith('.md')) assert.ok(await exists(routeFile(`/news/${file.slice(0, -3)}/`))); + } + for (const file of [ + 'README.md', + 'Gemfile', + 'bibtex-ruby-6.1.0.gem', + 'jekyll-scholar-7.3.0.gem', + '_planning/site-refinement-plan.md', + ]) { + assert.ok(!(await exists(join(dist, file))), `Repository artifact shipped: ${file}`); + } + assert.ok(await exists(join(dist, '.nojekyll'))); +}); + +test( + 'publishing Markdown and MDX produces routes, series links, RSS, and sitemap', + { timeout: 60000 }, + async () => { + const fixture = await mkdtemp(join(tmpdir(), 'boxiyu-publishing-')); + try { + for (const path of [ + 'src', + '_bibliography', + '_news', + '_talks', + 'public', + 'astro.config.mjs', + 'package.json', + 'tsconfig.json', + ]) { + await cp(join(root, path), join(fixture, path), { recursive: true }); + } + await symlink(join(root, 'node_modules'), join(fixture, 'node_modules'), 'dir'); + const contentRoot = join(fixture, 'src/content/writing'); + // Exercise real templates with published fixtures in an isolated checkout. + for (const [id, extension, order] of [ + ['release-check-one', 'md', 1], + ['release-check-two', 'mdx', 2], + ]) { + await writeFile( + join(contentRoot, `${id}.${extension}`), + `---\ntitle: ${id}\ndescription: A publishing integration fixture\npublishedAt: 2020-01-01\ntopics: [Verification]\naudience: developers\ndraft: false\nfeatured: true\nseries: Release checks\norder: ${order}\n---\n\n## A real heading\n\nA published article with [research](/research/).\n`, + ); + } + await writeFile( + join(contentRoot, 'future-check.md'), + '---\ntitle: Future fixture must stay private\ndescription: Future scheduled article\npublishedAt: 2999-01-01\ntopics: [Verification]\naudience: developers\ndraft: false\n---\nFuture content.\n', + ); + const astroPackage = JSON.parse( + await readFile(join(root, 'node_modules/astro/package.json'), 'utf8'), + ); + const cli = join(root, 'node_modules/astro', astroPackage.bin.astro); + execFileSync(process.execPath, [cli, 'build'], { + cwd: fixture, + env: { ...process.env, CONTENT_PREVIEW: 'true', ASTRO_TELEMETRY_DISABLED: '1' }, + stdio: 'pipe', + timeout: 45000, + }); + const output = join(fixture, 'dist'); + const first = load( + await readFile(join(output, 'writing/release-check-one/index.html'), 'utf8'), + ); + assert.equal(first('h1').text(), 'release-check-one'); + assert.equal(first('#a-real-heading').length, 1); + assert.ok(first('a[href="/writing/release-check-two/"]').length > 0); + assert.equal(first('meta[name="robots"]').length, 0); + assert.ok( + (await readFile(join(output, 'feed.xml'), 'utf8')).includes('/writing/release-check-two/'), + ); + assert.ok( + (await readFile(join(output, 'sitemap.xml'), 'utf8')).includes( + '/writing/release-check-one/', + ), + ); + assert.ok(!(await exists(join(output, 'writing/future-check/index.html')))); + assert.ok( + !(await exists(join(output, 'writing/passing-tests-is-not-correctness/index.html'))), + ); + assert.ok(!(await readFile(join(output, 'feed.xml'), 'utf8')).includes('Future fixture')); + } finally { + await rm(fixture, { recursive: true, force: true }); + } + }, +); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000000000..44355fb2da6eb --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,5 @@ +{ + "extends": "astro/tsconfigs/strict", + "include": [".astro/types.d.ts", "src/**/*", "astro.config.mjs"], + "exclude": ["dist", "_site", "vendor", "node_modules", "assets", "public"] +}