diff --git a/.env.development b/.env.development
index a692f21c7..e69de29bb 100644
--- a/.env.development
+++ b/.env.development
@@ -1 +0,0 @@
-SANDPACK_BARE_COMPONENTS=true
\ No newline at end of file
diff --git a/.env.production b/.env.production
index 445c9c4d0..e403f96b6 100644
--- a/.env.production
+++ b/.env.production
@@ -1,2 +1 @@
-NEXT_PUBLIC_GA_TRACKING_ID = 'UA-41298772-4'
-SANDPACK_BARE_COMPONENTS=true
\ No newline at end of file
+NEXT_PUBLIC_GA_TRACKING_ID = 'G-B1E83PJ3RT'
\ No newline at end of file
diff --git a/.eslintrc b/.eslintrc
index 147e54607..7bc6ab933 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -2,15 +2,36 @@
"root": true,
"extends": "next/core-web-vitals",
"parser": "@typescript-eslint/parser",
- "plugins": ["@typescript-eslint"],
+ "plugins": ["@typescript-eslint", "eslint-plugin-react-compiler", "local-rules"],
"rules": {
"no-unused-vars": "off",
- "@typescript-eslint/no-unused-vars": "warn"
+ "@typescript-eslint/no-unused-vars": ["error", {"varsIgnorePattern": "^_"}],
+ "react-hooks/exhaustive-deps": "error",
+ "react/no-unknown-property": ["error", {"ignore": ["meta"]}],
+ "react-compiler/react-compiler": "error",
+ "local-rules/lint-markdown-code-blocks": "error"
},
"env": {
"node": true,
"commonjs": true,
"browser": true,
"es6": true
- }
+ },
+ "overrides": [
+ {
+ "files": ["src/content/**/*.md"],
+ "parser": "./eslint-local-rules/parser",
+ "parserOptions": {
+ "sourceType": "module"
+ },
+ "rules": {
+ "no-unused-vars": "off",
+ "@typescript-eslint/no-unused-vars": "off",
+ "react-hooks/exhaustive-deps": "off",
+ "react/no-unknown-property": "off",
+ "react-compiler/react-compiler": "off",
+ "local-rules/lint-markdown-code-blocks": "error"
+ }
+ }
+ ]
}
diff --git a/.github/ISSUE_TEMPLATE/0-bug.yml b/.github/ISSUE_TEMPLATE/0-bug.yml
new file mode 100644
index 000000000..56d2e8540
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/0-bug.yml
@@ -0,0 +1,34 @@
+name: "π Report a bug"
+description: "Report a problem on the website."
+title: "[Bug]: "
+labels: ["bug: unconfirmed"]
+body:
+ - type: textarea
+ attributes:
+ label: Summary
+ description: |
+ A clear and concise summary of what the bug is.
+ placeholder: |
+ Example bug report:
+ When I click the "Submit" button on "Feedback", nothing happens.
+ validations:
+ required: true
+ - type: input
+ attributes:
+ label: Page
+ description: |
+ What page(s) did you encounter this bug on?
+ placeholder: |
+ https://react.dev/
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Details
+ description: |
+ Please provide any additional details about the bug.
+ placeholder: |
+ Example details:
+ The "Submit" button is unresponsive. I've tried refreshing the page and using a different browser, but the issue persists.
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/1-typo.yml b/.github/ISSUE_TEMPLATE/1-typo.yml
new file mode 100644
index 000000000..c86557a11
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/1-typo.yml
@@ -0,0 +1,34 @@
+name: "π€¦ Typo or mistake"
+description: "Report a typo or mistake in the docs."
+title: "[Typo]: "
+labels: ["type: typos"]
+body:
+ - type: textarea
+ attributes:
+ label: Summary
+ description: |
+ A clear and concise summary of what the mistake is.
+ placeholder: |
+ Example:
+ The code example on the "useReducer" page includes an unused variable `nextId`.
+ validations:
+ required: true
+ - type: input
+ attributes:
+ label: Page
+ description: |
+ What page is the typo on?
+ placeholder: |
+ https://react.dev/
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Details
+ description: |
+ Please provide a explanation for why this is a mistake.
+ placeholder: |
+ Example mistake:
+ In the "useReducer" section of the "API Reference" page, the code example under "Writing a reducer function" includes an unused variable `nextId` that should be removed.
+ validations:
+ required: false
diff --git a/.github/ISSUE_TEMPLATE/2-suggestion.yml b/.github/ISSUE_TEMPLATE/2-suggestion.yml
new file mode 100644
index 000000000..ac0b480fe
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/2-suggestion.yml
@@ -0,0 +1,34 @@
+name: "π‘ Suggestions"
+description: "Suggest a new page, section, or edit for an existing page."
+title: "[Suggestion]: "
+labels: ["type: documentation"]
+body:
+ - type: textarea
+ attributes:
+ label: Summary
+ description: |
+ A clear and concise summary of what we should add.
+ placeholder: |
+ Example:
+ Add a new page for how to use React with TypeScript.
+ validations:
+ required: true
+ - type: input
+ attributes:
+ label: Page
+ description: |
+ What page is this about?
+ placeholder: |
+ https://react.dev/
+ validations:
+ required: false
+ - type: textarea
+ attributes:
+ label: Details
+ description: |
+ Please provide a explanation for what you're suggesting.
+ placeholder: |
+ Example:
+ I think it would be helpful to have a page that explains how to use React with TypeScript. This could include a basic example of a component written in TypeScript, and a link to the TypeScript documentation.
+ validations:
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/3-framework.yml b/.github/ISSUE_TEMPLATE/3-framework.yml
new file mode 100644
index 000000000..a47295e1e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/3-framework.yml
@@ -0,0 +1,116 @@
+name: "π Suggest new framework"
+description: "I am a framework author applying to be included as a recommended framework."
+title: "[Framework]: "
+labels: ["type: framework"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ ## Apply to be included as a recommended React framework
+
+ _This form is for framework authors to apply to be included as a recommended [React framework](https://react.dev/learn/start-a-new-react-project). If you are not a framework author, please contact the authors before submitting._
+
+ Our goal when recommending a framework is to start developers with a React project that solves common problems like code splitting, data fetching, routing, and HTML generation without any extra work later. We believe this will allow users to get started quickly with React, and scale their app to production.
+
+ While we understand that many frameworks may want to be featured, this page is not a place to advertise every possible React framework or all frameworks that you can add React to. There are many great frameworks that offer support for React that are not listed in our guides. The frameworks we recommend have invested significantly in the React ecosystem, and collaborated with the React team to be compatible with our [full-stack React architecture vision](https://react.dev/learn/start-a-new-react-project#which-features-make-up-the-react-teams-full-stack-architecture-vision).
+
+ To be included, frameworks must meet the following criteria:
+
+ - **Free & open-source**: must be open source and free to use.
+ - **Well maintained**. must be actively maintained, providing bug fixes and improvements.
+ - **Active community**: must have a sufficiently large and active community to support users.
+ - **Clear onboarding**: must have clear install steps to install the React version of the framework.
+ - **Ecosystem compatibility**: must support using the full range of libraries and tools in the React ecosystem.
+ - **Self-hosting option**: must support an option to self-host applications without losing access to features.
+ - **Developer experience**. must allow developers to be productive by supporting features like Fast Refresh.
+ - **User experience**. must provide built-in support for common problems like routing and data-fetching.
+ - **Compatible with our future vision for React**. React evolves over time, and frameworks that do not align with Reactβs direction risk isolating their users from the main React ecosystem over time. To be included on this page we must feel confident that the framework is setting its users up for success with React over time.
+
+ Please note, we have reviewed most of the popular frameworks available today, so it is unlikely we have not considered your framework already. But if you think we missed something, please complete the application below.
+ - type: input
+ attributes:
+ label: Name
+ description: |
+ What is the name of your framework?
+ validations:
+ required: true
+ - type: input
+ attributes:
+ label: Homepage
+ description: |
+ What is the URL of your homepage?
+ validations:
+ required: true
+ - type: input
+ attributes:
+ label: Install instructions
+ description: |
+ What is the URL of your getting started guide?
+ validations:
+ required: true
+ - type: dropdown
+ attributes:
+ label: Is your framework open source?
+ description: |
+ We only recommend free and open source frameworks.
+ options:
+ - 'No'
+ - 'Yes'
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Well maintained
+ description: |
+ Please describe how your framework is actively maintained. Include recent releases, bug fixes, and improvements as examples.
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Active community
+ description: |
+ Please describe your community. Include the size of your community, and links to community resources.
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Clear onboarding
+ description: |
+ Please describe how a user can install your framework with React. Include links to any relevant documentation.
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Ecosystem compatibility
+ description: |
+ Please describe any limitations your framework has with the React ecosystem. Include any libraries or tools that are not compatible with your framework.
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Self-hosting option
+ description: |
+ Please describe how your framework supports self-hosting. Include any limitations to features when self-hosting. Also include whether you require a server to deploy your framework.
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Developer Experience
+ description: |
+ Please describe how your framework provides a great developer experience. Include any limitations to React features like React DevTools, Chrome DevTools, and Fast Refresh.
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: User Experience
+ description: |
+ Please describe how your framework helps developers create high quality user experiences by solving common use-cases. Include specifics for how your framework offers built-in support for code-splitting, routing, HTML generation, and data-fetching in a way that avoids client/server waterfalls by default. Include details on how you offer features such as SSG and SSR.
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Compatible with our future vision for React
+ description: |
+ Please describe how your framework aligns with our future vision for React. Include how your framework will evolve with React over time, and your plans to support future React features like React Server Components.
+ validations:
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 000000000..63e310e0b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,7 @@
+contact_links:
+ - name: π Bugs in React
+ url: https://github.com/facebook/react/issues/new/choose
+ about: This issue tracker is not for bugs in React. Please file React issues here.
+ - name: π€ Questions and Help
+ url: https://reactjs.org/community/support.html
+ about: This issue tracker is not for support questions. Please refer to the React community's help and discussion forums.
diff --git a/.github/workflows/analyze.yml b/.github/workflows/analyze.yml
index c447a2cdb..83e7f2e8a 100644
--- a/.github/workflows/analyze.yml
+++ b/.github/workflows/analyze.yml
@@ -7,22 +7,32 @@ on:
- main # change this if your default branch is named differently
workflow_dispatch:
+permissions: {}
+
jobs:
analyze:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
+ - uses: actions/checkout@v4
- name: Set up node
- uses: actions/setup-node@v1
+ uses: actions/setup-node@v4
+ with:
+ node-version: '20.x'
+ cache: yarn
+ cache-dependency-path: yarn.lock
+
+ - name: Restore cached node_modules
+ uses: actions/cache@v4
with:
- node-version: "14.x"
+ path: '**/node_modules'
+ key: node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- - name: Install dependencies
- uses: bahmutov/npm-install@v1.7.10
+ - name: Install deps
+ run: yarn install --frozen-lockfile
- name: Restore next build
- uses: actions/cache@v2
+ uses: actions/cache@v4
id: restore-build-cache
env:
cache-name: cache-next-build
@@ -38,16 +48,16 @@ jobs:
# Here's the first place where next-bundle-analysis' own script is used
# This step pulls the raw bundle stats for the current bundle
- name: Analyze bundle
- run: npx -p nextjs-bundle-analysis report
+ run: npx -p nextjs-bundle-analysis@0.5.0 report
- name: Upload bundle
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
path: .next/analyze/__bundle_analysis.json
name: bundle_analysis.json
- name: Download base branch bundle stats
- uses: dawidd6/action-download-artifact@v2
+ uses: dawidd6/action-download-artifact@268677152d06ba59fcec7a7f0b5d961b6ccd7e1e
if: success() && github.event.number
with:
workflow: analyze.yml
@@ -73,7 +83,7 @@ jobs:
run: ls -laR .next/analyze/base && npx -p nextjs-bundle-analysis compare
- name: Upload analysis comment
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: analysis_comment.txt
path: .next/analyze/__bundle_analysis_comment.txt
@@ -82,7 +92,7 @@ jobs:
run: echo ${{ github.event.number }} > ./pr_number
- name: Upload PR number
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v4
with:
name: pr_number
path: ./pr_number
diff --git a/.github/workflows/analyze_comment.yml b/.github/workflows/analyze_comment.yml
index bd73b6b4e..fcac37738 100644
--- a/.github/workflows/analyze_comment.yml
+++ b/.github/workflows/analyze_comment.yml
@@ -2,10 +2,15 @@ name: Analyze Bundle (Comment)
on:
workflow_run:
- workflows: ["Analyze Bundle"]
+ workflows: ['Analyze Bundle']
types:
- completed
+permissions:
+ contents: read
+ issues: write
+ pull-requests: write
+
jobs:
comment:
runs-on: ubuntu-latest
@@ -14,7 +19,7 @@ jobs:
github.event.workflow_run.conclusion == 'success' }}
steps:
- name: Download base branch bundle stats
- uses: dawidd6/action-download-artifact@v2
+ uses: dawidd6/action-download-artifact@268677152d06ba59fcec7a7f0b5d961b6ccd7e1e
with:
workflow: analyze.yml
run_id: ${{ github.event.workflow_run.id }}
@@ -22,7 +27,7 @@ jobs:
path: analysis_comment.txt
- name: Download PR number
- uses: dawidd6/action-download-artifact@v2
+ uses: dawidd6/action-download-artifact@268677152d06ba59fcec7a7f0b5d961b6ccd7e1e
with:
workflow: analyze.yml
run_id: ${{ github.event.workflow_run.id }}
@@ -47,26 +52,9 @@ jobs:
pr_number=$(cat pr_number/pr_number)
echo "pr-number=$pr_number" >> $GITHUB_OUTPUT
- - name: Find Comment
- uses: peter-evans/find-comment@v1
- if: success()
- id: fc
- with:
- issue-number: ${{ steps.get-comment-body.outputs.pr-number }}
- body-includes: ""
-
- - name: Create Comment
- uses: peter-evans/create-or-update-comment@v1.4.4
- if: success() && steps.fc.outputs.comment-id == 0
- with:
- issue-number: ${{ steps.get-comment-body.outputs.pr-number }}
- body: ${{ steps.get-comment-body.outputs.body }}
-
- - name: Update Comment
- uses: peter-evans/create-or-update-comment@v1.4.4
- if: success() && steps.fc.outputs.comment-id != 0
+ - name: Comment
+ uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728
with:
- issue-number: ${{ steps.get-comment-body.outputs.pr-number }}
- body: ${{ steps.get-comment-body.outputs.body }}
- comment-id: ${{ steps.fc.outputs.comment-id }}
- edit-mode: replace
+ header: next-bundle-analysis
+ number: ${{ steps.get-comment-body.outputs.pr-number }}
+ message: ${{ steps.get-comment-body.outputs.body }}
diff --git a/.github/workflows/discord_notify.yml b/.github/workflows/discord_notify.yml
new file mode 100644
index 000000000..2f5b2a497
--- /dev/null
+++ b/.github/workflows/discord_notify.yml
@@ -0,0 +1,32 @@
+name: Discord Notify
+
+on:
+ pull_request_target:
+ types: [opened, ready_for_review]
+
+permissions: {}
+
+jobs:
+ check_maintainer:
+ uses: facebook/react/.github/workflows/shared_check_maintainer.yml@main
+ permissions:
+ # Used by check_maintainer
+ contents: read
+ with:
+ actor: ${{ github.event.pull_request.user.login }}
+
+ notify:
+ if: ${{ needs.check_maintainer.outputs.is_core_team == 'true' }}
+ needs: check_maintainer
+ runs-on: ubuntu-latest
+ steps:
+ - name: Discord Webhook Action
+ uses: tsickert/discord-webhook@v6.0.0
+ with:
+ webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
+ embed-author-name: ${{ github.event.pull_request.user.login }}
+ embed-author-url: ${{ github.event.pull_request.user.html_url }}
+ embed-author-icon-url: ${{ github.event.pull_request.user.avatar_url }}
+ embed-title: '#${{ github.event.number }} (+${{github.event.pull_request.additions}} -${{github.event.pull_request.deletions}}): ${{ github.event.pull_request.title }}'
+ embed-description: ${{ github.event.pull_request.body }}
+ embed-url: ${{ github.event.pull_request.html_url }}
diff --git a/.github/workflows/label_core_team_prs.yml b/.github/workflows/label_core_team_prs.yml
new file mode 100644
index 000000000..f9b3328ee
--- /dev/null
+++ b/.github/workflows/label_core_team_prs.yml
@@ -0,0 +1,41 @@
+name: Label Core Team PRs
+
+on:
+ pull_request_target:
+
+permissions: {}
+
+env:
+ TZ: /usr/share/zoneinfo/America/Los_Angeles
+ # https://github.com/actions/cache/blob/main/tips-and-workarounds.md#cache-segment-restore-timeout
+ SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
+
+jobs:
+ check_maintainer:
+ uses: facebook/react/.github/workflows/shared_check_maintainer.yml@main
+ permissions:
+ # Used by check_maintainer
+ contents: read
+ with:
+ actor: ${{ github.event.pull_request.user.login }}
+
+ label:
+ if: ${{ needs.check_maintainer.outputs.is_core_team == 'true' }}
+ runs-on: ubuntu-latest
+ needs: check_maintainer
+ permissions:
+ # Used to add labels on issues
+ issues: write
+ # Used to add labels on PRs
+ pull-requests: write
+ steps:
+ - name: Label PR as React Core Team
+ uses: actions/github-script@v7
+ with:
+ script: |
+ github.rest.issues.addLabels({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: ${{ github.event.number }},
+ labels: ['React Core Team']
+ });
diff --git a/.github/workflows/site_lint.yml b/.github/workflows/site_lint.yml
index bf446393a..81a04601c 100644
--- a/.github/workflows/site_lint.yml
+++ b/.github/workflows/site_lint.yml
@@ -7,21 +7,31 @@ on:
pull_request:
types: [opened, synchronize, reopened]
+permissions: {}
+
jobs:
lint:
runs-on: ubuntu-latest
- name: Lint on node 12.x and ubuntu-latest
+ name: Lint on node 20.x and ubuntu-latest
steps:
- - uses: actions/checkout@v1
- - name: Use Node.js 12.x
- uses: actions/setup-node@v1
+ - uses: actions/checkout@v4
+ - name: Use Node.js 20.x
+ uses: actions/setup-node@v4
+ with:
+ node-version: 20.x
+ cache: yarn
+ cache-dependency-path: yarn.lock
+
+ - name: Restore cached node_modules
+ uses: actions/cache@v4
with:
- node-version: 12.x
+ path: '**/node_modules'
+ key: node_modules-${{ runner.arch }}-${{ runner.os }}-${{ hashFiles('yarn.lock') }}
- - name: Install deps and build (with cache)
- uses: bahmutov/npm-install@v1.7.10
+ - name: Install deps
+ run: yarn install --frozen-lockfile
- name: Lint codebase
run: yarn ci-check
diff --git a/.gitignore b/.gitignore
index d8bec488b..99f4615e5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
-/node_modules
+node_modules
/.pnp
.pnp.js
@@ -36,3 +36,6 @@ yarn-error.log*
# external fonts
public/fonts/**/Optimistic_*.woff2
+
+# rss
+public/rss.xml
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 0e861af35..4c7e5ec74 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -79,6 +79,7 @@ Ignore this rule if you're specifically describing an experimental proposal. Mak
- Use semicolons.
- No space between function names and parens (`method() {}` not `method () {}`).
- When in doubt, use the default style favored by [Prettier](https://prettier.io/playground/).
+- Always capitalize React concepts such as Hooks, Effects, and Transitions.
### Highlighting
diff --git a/README.md b/README.md
index 966131db5..182192cb5 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ This repo contains the source code and documentation powering [react.dev](https:
### Prerequisites
1. Git
-1. Node: any 12.x version starting with v12.0.0 or greater
+1. Node: any version starting with v16.8.0 or greater
1. Yarn: See [Yarn website for installation instructions](https://yarnpkg.com/lang/en/docs/install/)
1. A fork of the repo (for any contributions)
1. A clone of the [react.dev repo](https://github.com/reactjs/react.dev) on your local machine
diff --git a/colors.js b/colors.js
index acf8214ee..2b282c820 100644
--- a/colors.js
+++ b/colors.js
@@ -1,3 +1,10 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*/
@@ -11,7 +18,7 @@ module.exports = {
tertiary: '#5E687E', // gray-50
'tertiary-dark': '#99A1B3', // gray-30
link: '#087EA4', // blue-50
- 'link-dark': '#149ECA', // blue-40
+ 'link-dark': '#58C4DC', // blue-40
syntax: '#EBECF0', // gray-10
wash: '#FFFFFF',
'wash-dark': '#23272F', // gray-90
@@ -23,6 +30,8 @@ module.exports = {
'border-dark': '#343A46', // gray-80
'secondary-button': '#EBECF0', // gray-10
'secondary-button-dark': '#404756', // gray-70
+ brand: '#087EA4', // blue-40
+ 'brand-dark': '#58C4DC', // blue-40
// Gray
'gray-95': '#16181D',
diff --git a/eslint-local-rules/__tests__/fixtures/src/content/basic-error.md b/eslint-local-rules/__tests__/fixtures/src/content/basic-error.md
new file mode 100644
index 000000000..8e7670fdc
--- /dev/null
+++ b/eslint-local-rules/__tests__/fixtures/src/content/basic-error.md
@@ -0,0 +1,8 @@
+```jsx
+import {useState} from 'react';
+function Counter() {
+ const [count, setCount] = useState(0);
+ setCount(count + 1);
+ return
{count}
;
+}
+```
diff --git a/eslint-local-rules/__tests__/fixtures/src/content/duplicate-metadata.md b/eslint-local-rules/__tests__/fixtures/src/content/duplicate-metadata.md
new file mode 100644
index 000000000..67d6b62bb
--- /dev/null
+++ b/eslint-local-rules/__tests__/fixtures/src/content/duplicate-metadata.md
@@ -0,0 +1,8 @@
+```jsx title="Counter" {expectedErrors: {'react-compiler': [99]}} {expectedErrors: {'react-compiler': [2]}}
+import {useState} from 'react';
+function Counter() {
+ const [count, setCount] = useState(0);
+ setCount(count + 1);
+ return {count}
;
+}
+```
diff --git a/eslint-local-rules/__tests__/fixtures/src/content/malformed-metadata.md b/eslint-local-rules/__tests__/fixtures/src/content/malformed-metadata.md
new file mode 100644
index 000000000..fd542bf03
--- /dev/null
+++ b/eslint-local-rules/__tests__/fixtures/src/content/malformed-metadata.md
@@ -0,0 +1,8 @@
+```jsx {expectedErrors: {'react-compiler': 'invalid'}}
+import {useState} from 'react';
+function Counter() {
+ const [count, setCount] = useState(0);
+ setCount(count + 1);
+ return {count}
;
+}
+```
diff --git a/eslint-local-rules/__tests__/fixtures/src/content/mixed-language.md b/eslint-local-rules/__tests__/fixtures/src/content/mixed-language.md
new file mode 100644
index 000000000..313b0e30f
--- /dev/null
+++ b/eslint-local-rules/__tests__/fixtures/src/content/mixed-language.md
@@ -0,0 +1,7 @@
+```bash
+setCount()
+```
+
+```txt
+import {useState} from 'react';
+```
diff --git a/eslint-local-rules/__tests__/fixtures/src/content/stale-expected-error.md b/eslint-local-rules/__tests__/fixtures/src/content/stale-expected-error.md
new file mode 100644
index 000000000..46e330ac0
--- /dev/null
+++ b/eslint-local-rules/__tests__/fixtures/src/content/stale-expected-error.md
@@ -0,0 +1,5 @@
+```jsx {expectedErrors: {'react-compiler': [3]}}
+function Hello() {
+ return Hello
;
+}
+```
diff --git a/eslint-local-rules/__tests__/fixtures/src/content/suppressed-error.md b/eslint-local-rules/__tests__/fixtures/src/content/suppressed-error.md
new file mode 100644
index 000000000..ecefa8495
--- /dev/null
+++ b/eslint-local-rules/__tests__/fixtures/src/content/suppressed-error.md
@@ -0,0 +1,8 @@
+```jsx {expectedErrors: {'react-compiler': [4]}}
+import {useState} from 'react';
+function Counter() {
+ const [count, setCount] = useState(0);
+ setCount(count + 1);
+ return {count}
;
+}
+```
diff --git a/eslint-local-rules/__tests__/lint-markdown-code-blocks.test.js b/eslint-local-rules/__tests__/lint-markdown-code-blocks.test.js
new file mode 100644
index 000000000..250e0a1e5
--- /dev/null
+++ b/eslint-local-rules/__tests__/lint-markdown-code-blocks.test.js
@@ -0,0 +1,131 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+const assert = require('assert');
+const fs = require('fs');
+const path = require('path');
+const {ESLint} = require('eslint');
+const plugin = require('..');
+
+const FIXTURES_DIR = path.join(
+ __dirname,
+ 'fixtures',
+ 'src',
+ 'content'
+);
+const PARSER_PATH = path.join(__dirname, '..', 'parser.js');
+
+function createESLint({fix = false} = {}) {
+ return new ESLint({
+ useEslintrc: false,
+ fix,
+ plugins: {
+ 'local-rules': plugin,
+ },
+ overrideConfig: {
+ parser: PARSER_PATH,
+ plugins: ['local-rules'],
+ rules: {
+ 'local-rules/lint-markdown-code-blocks': 'error',
+ },
+ parserOptions: {
+ sourceType: 'module',
+ },
+ },
+ });
+}
+
+function readFixture(name) {
+ return fs.readFileSync(path.join(FIXTURES_DIR, name), 'utf8');
+}
+
+async function lintFixture(name, {fix = false} = {}) {
+ const eslint = createESLint({fix});
+ const filePath = path.join(FIXTURES_DIR, name);
+ const markdown = readFixture(name);
+ const [result] = await eslint.lintText(markdown, {filePath});
+ return result;
+}
+
+async function run() {
+ const basicResult = await lintFixture('basic-error.md');
+ assert.strictEqual(
+ basicResult.messages.length,
+ 1,
+ 'expected one diagnostic'
+ );
+ assert(
+ basicResult.messages[0].message.includes('Calling setState during render'),
+ 'expected message to mention setState during render'
+ );
+
+ const suppressedResult = await lintFixture('suppressed-error.md');
+ assert.strictEqual(
+ suppressedResult.messages.length,
+ 0,
+ 'expected suppression metadata to silence diagnostic'
+ );
+
+ const staleResult = await lintFixture('stale-expected-error.md');
+ assert.strictEqual(
+ staleResult.messages.length,
+ 1,
+ 'expected stale metadata error'
+ );
+ assert.strictEqual(
+ staleResult.messages[0].message,
+ 'React Compiler expected error on line 3 was not triggered'
+ );
+
+ const duplicateResult = await lintFixture('duplicate-metadata.md');
+ assert.strictEqual(
+ duplicateResult.messages.length,
+ 2,
+ 'expected duplicate metadata to surface compiler diagnostic and stale metadata notice'
+ );
+ const duplicateFixed = await lintFixture('duplicate-metadata.md', {
+ fix: true,
+ });
+ assert(
+ duplicateFixed.output.includes(
+ "{expectedErrors: {'react-compiler': [4]}}"
+ ),
+ 'expected duplicates to be rewritten to a single canonical block'
+ );
+ assert(
+ !duplicateFixed.output.includes('[99]'),
+ 'expected stale line numbers to be removed from metadata'
+ );
+
+ const mixedLanguageResult = await lintFixture('mixed-language.md');
+ assert.strictEqual(
+ mixedLanguageResult.messages.length,
+ 0,
+ 'expected non-js code fences to be ignored'
+ );
+
+ const malformedResult = await lintFixture('malformed-metadata.md');
+ assert.strictEqual(
+ malformedResult.messages.length,
+ 1,
+ 'expected malformed metadata to fall back to compiler diagnostics'
+ );
+ const malformedFixed = await lintFixture('malformed-metadata.md', {
+ fix: true,
+ });
+ assert(
+ malformedFixed.output.includes(
+ "{expectedErrors: {'react-compiler': [4]}}"
+ ),
+ 'expected malformed metadata to be replaced with canonical form'
+ );
+}
+
+run().catch(error => {
+ console.error(error);
+ process.exitCode = 1;
+});
diff --git a/eslint-local-rules/index.js b/eslint-local-rules/index.js
new file mode 100644
index 000000000..b1f747ccb
--- /dev/null
+++ b/eslint-local-rules/index.js
@@ -0,0 +1,14 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+const lintMarkdownCodeBlocks = require('./rules/lint-markdown-code-blocks');
+
+module.exports = {
+ rules: {
+ 'lint-markdown-code-blocks': lintMarkdownCodeBlocks,
+ },
+};
diff --git a/eslint-local-rules/package.json b/eslint-local-rules/package.json
new file mode 100644
index 000000000..9940fee20
--- /dev/null
+++ b/eslint-local-rules/package.json
@@ -0,0 +1,12 @@
+{
+ "name": "eslint-plugin-local-rules",
+ "version": "0.0.0",
+ "main": "index.js",
+ "private": "true",
+ "scripts": {
+ "test": "node __tests__/lint-markdown-code-blocks.test.js"
+ },
+ "devDependencies": {
+ "eslint-mdx": "^2"
+ }
+}
diff --git a/eslint-local-rules/parser.js b/eslint-local-rules/parser.js
new file mode 100644
index 000000000..043f2e520
--- /dev/null
+++ b/eslint-local-rules/parser.js
@@ -0,0 +1,8 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+module.exports = require('eslint-mdx');
diff --git a/eslint-local-rules/rules/diagnostics.js b/eslint-local-rules/rules/diagnostics.js
new file mode 100644
index 000000000..4e433164b
--- /dev/null
+++ b/eslint-local-rules/rules/diagnostics.js
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+function getRelativeLine(loc) {
+ return loc?.start?.line ?? loc?.line ?? 1;
+}
+
+function getRelativeColumn(loc) {
+ return loc?.start?.column ?? loc?.column ?? 0;
+}
+
+function getRelativeEndLine(loc, fallbackLine) {
+ if (loc?.end?.line != null) {
+ return loc.end.line;
+ }
+ if (loc?.line != null) {
+ return loc.line;
+ }
+ return fallbackLine;
+}
+
+function getRelativeEndColumn(loc, fallbackColumn) {
+ if (loc?.end?.column != null) {
+ return loc.end.column;
+ }
+ if (loc?.column != null) {
+ return loc.column;
+ }
+ return fallbackColumn;
+}
+
+/**
+ * @param {import('./markdown').MarkdownCodeBlock} block
+ * @param {Array<{detail: any, loc: any, message: string}>} diagnostics
+ * @returns {Array<{detail: any, message: string, relativeStartLine: number, markdownLoc: {start: {line: number, column: number}, end: {line: number, column: number}}}>}
+ */
+function normalizeDiagnostics(block, diagnostics) {
+ return diagnostics.map(({detail, loc, message}) => {
+ const relativeStartLine = Math.max(getRelativeLine(loc), 1);
+ const relativeStartColumn = Math.max(getRelativeColumn(loc), 0);
+ const relativeEndLine = Math.max(
+ getRelativeEndLine(loc, relativeStartLine),
+ relativeStartLine
+ );
+ const relativeEndColumn = Math.max(
+ getRelativeEndColumn(loc, relativeStartColumn),
+ relativeStartColumn
+ );
+
+ const markdownStartLine = block.codeStartLine + relativeStartLine - 1;
+ const markdownEndLine = block.codeStartLine + relativeEndLine - 1;
+
+ return {
+ detail,
+ message,
+ relativeStartLine,
+ markdownLoc: {
+ start: {
+ line: markdownStartLine,
+ column: relativeStartColumn,
+ },
+ end: {
+ line: markdownEndLine,
+ column: relativeEndColumn,
+ },
+ },
+ };
+ });
+}
+
+module.exports = {
+ normalizeDiagnostics,
+};
diff --git a/eslint-local-rules/rules/lint-markdown-code-blocks.js b/eslint-local-rules/rules/lint-markdown-code-blocks.js
new file mode 100644
index 000000000..5ec327947
--- /dev/null
+++ b/eslint-local-rules/rules/lint-markdown-code-blocks.js
@@ -0,0 +1,178 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+const {
+ buildFenceLine,
+ getCompilerExpectedLines,
+ getSortedUniqueNumbers,
+ hasCompilerEntry,
+ metadataEquals,
+ metadataHasExpectedErrorsToken,
+ removeCompilerExpectedLines,
+ setCompilerExpectedLines,
+} = require('./metadata');
+const {normalizeDiagnostics} = require('./diagnostics');
+const {parseMarkdownFile} = require('./markdown');
+const {runReactCompiler} = require('./react-compiler');
+
+module.exports = {
+ meta: {
+ type: 'problem',
+ docs: {
+ description: 'Run React Compiler on markdown code blocks',
+ category: 'Possible Errors',
+ },
+ fixable: 'code',
+ hasSuggestions: true,
+ schema: [],
+ },
+
+ create(context) {
+ return {
+ Program(node) {
+ const filename = context.getFilename();
+ if (!filename.endsWith('.md') || !filename.includes('src/content')) {
+ return;
+ }
+
+ const sourceCode = context.getSourceCode();
+ const {blocks} = parseMarkdownFile(sourceCode.text, filename);
+ // For each supported code block, run the compiler and reconcile metadata.
+ for (const block of blocks) {
+ const compilerResult = runReactCompiler(
+ block.code,
+ `${filename}#codeblock`
+ );
+
+ const expectedLines = getCompilerExpectedLines(block.metadata);
+ const expectedLineSet = new Set(expectedLines);
+ const diagnostics = normalizeDiagnostics(
+ block,
+ compilerResult.diagnostics
+ );
+
+ const errorLines = new Set();
+ const unexpectedDiagnostics = [];
+
+ for (const diagnostic of diagnostics) {
+ const line = diagnostic.relativeStartLine;
+ errorLines.add(line);
+ if (!expectedLineSet.has(line)) {
+ unexpectedDiagnostics.push(diagnostic);
+ }
+ }
+
+ const normalizedErrorLines = getSortedUniqueNumbers(
+ Array.from(errorLines)
+ );
+ const missingExpectedLines = expectedLines.filter(
+ (line) => !errorLines.has(line)
+ );
+
+ const desiredMetadata = normalizedErrorLines.length
+ ? setCompilerExpectedLines(block.metadata, normalizedErrorLines)
+ : removeCompilerExpectedLines(block.metadata);
+
+ // Compute canonical metadata and attach an autofix when it differs.
+ const metadataChanged = !metadataEquals(
+ block.metadata,
+ desiredMetadata
+ );
+ const replacementLine = buildFenceLine(block.lang, desiredMetadata);
+ const replacementDiffers = block.fence.rawText !== replacementLine;
+ const applyReplacementFix = replacementDiffers
+ ? (fixer) =>
+ fixer.replaceTextRange(block.fence.range, replacementLine)
+ : null;
+
+ const hasDuplicateMetadata =
+ block.metadata.hadDuplicateExpectedErrors;
+ const hasExpectedErrorsMetadata = metadataHasExpectedErrorsToken(
+ block.metadata
+ );
+
+ const shouldFixUnexpected =
+ Boolean(applyReplacementFix) &&
+ normalizedErrorLines.length > 0 &&
+ (metadataChanged ||
+ hasDuplicateMetadata ||
+ !hasExpectedErrorsMetadata);
+
+ let fixAlreadyAttached = false;
+
+ for (const diagnostic of unexpectedDiagnostics) {
+ const reportData = {
+ node,
+ loc: diagnostic.markdownLoc,
+ message: diagnostic.message,
+ };
+
+ if (
+ shouldFixUnexpected &&
+ applyReplacementFix &&
+ !fixAlreadyAttached
+ ) {
+ reportData.fix = applyReplacementFix;
+ reportData.suggest = [
+ {
+ desc: 'Add expectedErrors metadata to suppress these errors',
+ fix: applyReplacementFix,
+ },
+ ];
+ fixAlreadyAttached = true;
+ }
+
+ context.report(reportData);
+ }
+
+ // Assert that expectedErrors is actually needed
+ if (
+ Boolean(applyReplacementFix) &&
+ missingExpectedLines.length > 0 &&
+ hasCompilerEntry(block.metadata)
+ ) {
+ const plural = missingExpectedLines.length > 1;
+ const message = plural
+ ? `React Compiler expected errors on lines ${missingExpectedLines.join(
+ ', '
+ )} were not triggered`
+ : `React Compiler expected error on line ${missingExpectedLines[0]} was not triggered`;
+
+ const reportData = {
+ node,
+ loc: {
+ start: {
+ line: block.position.start.line,
+ column: 0,
+ },
+ end: {
+ line: block.position.start.line,
+ column: block.fence.rawText.length,
+ },
+ },
+ message,
+ };
+
+ if (!fixAlreadyAttached && applyReplacementFix) {
+ reportData.fix = applyReplacementFix;
+ fixAlreadyAttached = true;
+ } else if (applyReplacementFix) {
+ reportData.suggest = [
+ {
+ desc: 'Remove stale expectedErrors metadata',
+ fix: applyReplacementFix,
+ },
+ ];
+ }
+
+ context.report(reportData);
+ }
+ }
+ },
+ };
+ },
+};
diff --git a/eslint-local-rules/rules/markdown.js b/eslint-local-rules/rules/markdown.js
new file mode 100644
index 000000000..d888d1311
--- /dev/null
+++ b/eslint-local-rules/rules/markdown.js
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+const remark = require('remark');
+const {parseFenceMetadata} = require('./metadata');
+
+/**
+ * @typedef {Object} MarkdownCodeBlock
+ * @property {string} code
+ * @property {number} codeStartLine
+ * @property {{start: {line: number, column: number}, end: {line: number, column: number}}} position
+ * @property {{lineIndex: number, rawText: string, metaText: string, range: [number, number]}} fence
+ * @property {string} filePath
+ * @property {string} lang
+ * @property {import('./metadata').FenceMetadata} metadata
+ */
+
+const SUPPORTED_LANGUAGES = new Set([
+ 'js',
+ 'jsx',
+ 'javascript',
+ 'ts',
+ 'tsx',
+ 'typescript',
+]);
+
+function computeLineOffsets(lines) {
+ const offsets = [];
+ let currentOffset = 0;
+
+ for (const line of lines) {
+ offsets.push(currentOffset);
+ currentOffset += line.length + 1;
+ }
+
+ return offsets;
+}
+
+function parseMarkdownFile(content, filePath) {
+ const tree = remark().parse(content);
+ const lines = content.split('\n');
+ const lineOffsets = computeLineOffsets(lines);
+ const blocks = [];
+
+ function traverse(node) {
+ if (!node || typeof node !== 'object') {
+ return;
+ }
+
+ if (node.type === 'code') {
+ const rawLang = node.lang || '';
+ const normalizedLang = rawLang.toLowerCase();
+ if (!normalizedLang || !SUPPORTED_LANGUAGES.has(normalizedLang)) {
+ return;
+ }
+
+ const fenceLineIndex = (node.position?.start?.line ?? 1) - 1;
+ const fenceStartOffset = node.position?.start?.offset ?? 0;
+ const fenceLine = lines[fenceLineIndex] ?? '';
+ const fenceEndOffset = fenceStartOffset + fenceLine.length;
+
+ let metaText = '';
+ if (fenceLine) {
+ const prefixMatch = fenceLine.match(/^`{3,}\s*/);
+ const prefixLength = prefixMatch ? prefixMatch[0].length : 3;
+ metaText = fenceLine.slice(prefixLength + rawLang.length);
+ } else if (node.meta) {
+ metaText = ` ${node.meta}`;
+ }
+
+ const metadata = parseFenceMetadata(metaText);
+
+ blocks.push({
+ lang: rawLang || normalizedLang,
+ metadata,
+ filePath,
+ code: node.value || '',
+ codeStartLine: (node.position?.start?.line ?? 1) + 1,
+ position: {
+ start: {
+ line: fenceLineIndex + 1,
+ column: (node.position?.start?.column ?? 1) - 1,
+ },
+ end: {
+ line: fenceLineIndex + 1,
+ column: (node.position?.start?.column ?? 1) - 1 + fenceLine.length,
+ },
+ },
+ fence: {
+ lineIndex: fenceLineIndex,
+ rawText: fenceLine,
+ metaText,
+ range: [fenceStartOffset, fenceEndOffset],
+ },
+ });
+ return;
+ }
+
+ if ('children' in node && Array.isArray(node.children)) {
+ for (const child of node.children) {
+ traverse(child);
+ }
+ }
+ }
+
+ traverse(tree);
+
+ return {
+ content,
+ blocks,
+ lines,
+ lineOffsets,
+ };
+}
+
+module.exports = {
+ SUPPORTED_LANGUAGES,
+ computeLineOffsets,
+ parseMarkdownFile,
+};
diff --git a/eslint-local-rules/rules/metadata.js b/eslint-local-rules/rules/metadata.js
new file mode 100644
index 000000000..fb58a37c2
--- /dev/null
+++ b/eslint-local-rules/rules/metadata.js
@@ -0,0 +1,377 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+/**
+ * @typedef {{type: 'text', raw: string}} TextToken
+ * @typedef {{
+ * type: 'expectedErrors',
+ * entries: Record>,
+ * raw?: string,
+ * }} ExpectedErrorsToken
+ * @typedef {TextToken | ExpectedErrorsToken} MetadataToken
+ *
+ * @typedef {{
+ * leading: string,
+ * trailing: string,
+ * tokens: Array,
+ * parseError: boolean,
+ * hadDuplicateExpectedErrors: boolean,
+ * }} FenceMetadata
+ */
+
+const EXPECTED_ERRORS_BLOCK_REGEX = /\{\s*expectedErrors\s*:/;
+const REACT_COMPILER_KEY = 'react-compiler';
+
+function getSortedUniqueNumbers(values) {
+ return Array.from(new Set(values))
+ .filter((value) => typeof value === 'number' && !Number.isNaN(value))
+ .sort((a, b) => a - b);
+}
+
+function tokenizeMeta(body) {
+ if (!body) {
+ return [];
+ }
+
+ const tokens = [];
+ let current = '';
+ let depth = 0;
+
+ for (let i = 0; i < body.length; i++) {
+ const char = body[i];
+ if (char === '{') {
+ depth++;
+ } else if (char === '}') {
+ depth = Math.max(depth - 1, 0);
+ }
+
+ if (char === ' ' && depth === 0) {
+ if (current) {
+ tokens.push(current);
+ current = '';
+ }
+ continue;
+ }
+
+ current += char;
+ }
+
+ if (current) {
+ tokens.push(current);
+ }
+
+ return tokens;
+}
+
+function normalizeEntryValues(values) {
+ if (!Array.isArray(values)) {
+ return [];
+ }
+ return getSortedUniqueNumbers(values);
+}
+
+function parseExpectedErrorsEntries(rawEntries) {
+ const normalized = rawEntries
+ .replace(/([{,]\s*)([a-zA-Z_$][\w$]*)\s*:/g, '$1"$2":')
+ .replace(/'([^']*)'/g, '"$1"');
+
+ const parsed = JSON.parse(normalized);
+ const entries = {};
+
+ if (parsed && typeof parsed === 'object') {
+ for (const [key, value] of Object.entries(parsed)) {
+ entries[key] = normalizeEntryValues(Array.isArray(value) ? value.flat() : value);
+ }
+ }
+
+ return entries;
+}
+
+function parseExpectedErrorsToken(tokenText) {
+ const match = tokenText.match(/^\{\s*expectedErrors\s*:\s*(\{[\s\S]*\})\s*\}$/);
+ if (!match) {
+ return null;
+ }
+
+ const entriesSource = match[1];
+ let parseError = false;
+ let entries;
+
+ try {
+ entries = parseExpectedErrorsEntries(entriesSource);
+ } catch (error) {
+ parseError = true;
+ entries = {};
+ }
+
+ return {
+ token: {
+ type: 'expectedErrors',
+ entries,
+ raw: tokenText,
+ },
+ parseError,
+ };
+}
+
+function parseFenceMetadata(metaText) {
+ if (!metaText) {
+ return {
+ leading: '',
+ trailing: '',
+ tokens: [],
+ parseError: false,
+ hadDuplicateExpectedErrors: false,
+ };
+ }
+
+ const leading = metaText.match(/^\s*/)?.[0] ?? '';
+ const trailing = metaText.match(/\s*$/)?.[0] ?? '';
+ const bodyStart = leading.length;
+ const bodyEnd = metaText.length - trailing.length;
+ const body = metaText.slice(bodyStart, bodyEnd).trim();
+
+ if (!body) {
+ return {
+ leading,
+ trailing,
+ tokens: [],
+ parseError: false,
+ hadDuplicateExpectedErrors: false,
+ };
+ }
+
+ const tokens = [];
+ let parseError = false;
+ let sawExpectedErrors = false;
+ let hadDuplicateExpectedErrors = false;
+
+ for (const rawToken of tokenizeMeta(body)) {
+ const normalizedToken = rawToken.trim();
+ if (!normalizedToken) {
+ continue;
+ }
+
+ if (EXPECTED_ERRORS_BLOCK_REGEX.test(normalizedToken)) {
+ const parsed = parseExpectedErrorsToken(normalizedToken);
+ if (parsed) {
+ if (sawExpectedErrors) {
+ hadDuplicateExpectedErrors = true;
+ // Drop duplicates. We'll rebuild the canonical block on write.
+ continue;
+ }
+ tokens.push(parsed.token);
+ parseError = parseError || parsed.parseError;
+ sawExpectedErrors = true;
+ continue;
+ }
+ }
+
+ tokens.push({type: 'text', raw: normalizedToken});
+ }
+
+ return {
+ leading,
+ trailing,
+ tokens,
+ parseError,
+ hadDuplicateExpectedErrors,
+ };
+}
+
+function cloneMetadata(metadata) {
+ return {
+ leading: metadata.leading,
+ trailing: metadata.trailing,
+ parseError: metadata.parseError,
+ hadDuplicateExpectedErrors: metadata.hadDuplicateExpectedErrors,
+ tokens: metadata.tokens.map((token) => {
+ if (token.type === 'expectedErrors') {
+ const clonedEntries = {};
+ for (const [key, value] of Object.entries(token.entries)) {
+ clonedEntries[key] = [...value];
+ }
+ return {type: 'expectedErrors', entries: clonedEntries};
+ }
+ return {type: 'text', raw: token.raw};
+ }),
+ };
+}
+
+function findExpectedErrorsToken(metadata) {
+ return metadata.tokens.find((token) => token.type === 'expectedErrors') || null;
+}
+
+function getCompilerExpectedLines(metadata) {
+ const token = findExpectedErrorsToken(metadata);
+ if (!token) {
+ return [];
+ }
+ return getSortedUniqueNumbers(token.entries[REACT_COMPILER_KEY] || []);
+}
+
+function hasCompilerEntry(metadata) {
+ const token = findExpectedErrorsToken(metadata);
+ return Boolean(token && token.entries[REACT_COMPILER_KEY]?.length);
+}
+
+function metadataHasExpectedErrorsToken(metadata) {
+ return Boolean(findExpectedErrorsToken(metadata));
+}
+
+function stringifyExpectedErrorsToken(token) {
+ const entries = token.entries || {};
+ const keys = Object.keys(entries).filter((key) => entries[key].length > 0);
+ if (keys.length === 0) {
+ return '';
+ }
+
+ keys.sort();
+
+ const segments = keys.map((key) => {
+ const values = entries[key];
+ return `'${key}': [${values.join(', ')}]`;
+ });
+
+ return `{expectedErrors: {${segments.join(', ')}}}`;
+}
+
+function stringifyFenceMetadata(metadata) {
+ if (!metadata.tokens.length) {
+ return '';
+ }
+
+ const parts = metadata.tokens
+ .map((token) => {
+ if (token.type === 'expectedErrors') {
+ return stringifyExpectedErrorsToken(token);
+ }
+ return token.raw;
+ })
+ .filter(Boolean);
+
+ if (!parts.length) {
+ return '';
+ }
+
+ const leading = metadata.leading || ' ';
+ const trailing = metadata.trailing ? metadata.trailing.trimEnd() : '';
+ const body = parts.join(' ');
+ return `${leading}${body}${trailing}`;
+}
+
+function buildFenceLine(lang, metadata) {
+ const meta = stringifyFenceMetadata(metadata);
+ return meta ? `\`\`\`${lang}${meta}` : `\`\`\`${lang}`;
+}
+
+function metadataEquals(a, b) {
+ if (a.leading !== b.leading || a.trailing !== b.trailing) {
+ return false;
+ }
+
+ if (a.tokens.length !== b.tokens.length) {
+ return false;
+ }
+
+ for (let i = 0; i < a.tokens.length; i++) {
+ const left = a.tokens[i];
+ const right = b.tokens[i];
+ if (left.type !== right.type) {
+ return false;
+ }
+ if (left.type === 'text') {
+ if (left.raw !== right.raw) {
+ return false;
+ }
+ } else {
+ const leftKeys = Object.keys(left.entries).sort();
+ const rightKeys = Object.keys(right.entries).sort();
+ if (leftKeys.length !== rightKeys.length) {
+ return false;
+ }
+ for (let j = 0; j < leftKeys.length; j++) {
+ if (leftKeys[j] !== rightKeys[j]) {
+ return false;
+ }
+ const lValues = getSortedUniqueNumbers(left.entries[leftKeys[j]]);
+ const rValues = getSortedUniqueNumbers(right.entries[rightKeys[j]]);
+ if (lValues.length !== rValues.length) {
+ return false;
+ }
+ for (let k = 0; k < lValues.length; k++) {
+ if (lValues[k] !== rValues[k]) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+function normalizeMetadata(metadata) {
+ const normalized = cloneMetadata(metadata);
+ normalized.hadDuplicateExpectedErrors = false;
+ normalized.parseError = false;
+ if (!normalized.tokens.length) {
+ normalized.leading = '';
+ normalized.trailing = '';
+ }
+ return normalized;
+}
+
+function setCompilerExpectedLines(metadata, lines) {
+ const normalizedLines = getSortedUniqueNumbers(lines);
+ if (normalizedLines.length === 0) {
+ return removeCompilerExpectedLines(metadata);
+ }
+
+ const next = cloneMetadata(metadata);
+ let token = findExpectedErrorsToken(next);
+ if (!token) {
+ token = {type: 'expectedErrors', entries: {}};
+ next.tokens = [token, ...next.tokens];
+ }
+
+ token.entries[REACT_COMPILER_KEY] = normalizedLines;
+ return normalizeMetadata(next);
+}
+
+function removeCompilerExpectedLines(metadata) {
+ const next = cloneMetadata(metadata);
+ const token = findExpectedErrorsToken(next);
+ if (!token) {
+ return normalizeMetadata(next);
+ }
+
+ delete token.entries[REACT_COMPILER_KEY];
+
+ const hasEntries = Object.values(token.entries).some(
+ (value) => Array.isArray(value) && value.length > 0
+ );
+
+ if (!hasEntries) {
+ next.tokens = next.tokens.filter((item) => item !== token);
+ }
+
+ return normalizeMetadata(next);
+}
+
+module.exports = {
+ buildFenceLine,
+ getCompilerExpectedLines,
+ getSortedUniqueNumbers,
+ hasCompilerEntry,
+ metadataEquals,
+ metadataHasExpectedErrorsToken,
+ parseFenceMetadata,
+ removeCompilerExpectedLines,
+ setCompilerExpectedLines,
+ stringifyFenceMetadata,
+};
diff --git a/eslint-local-rules/rules/react-compiler.js b/eslint-local-rules/rules/react-compiler.js
new file mode 100644
index 000000000..26d3878ee
--- /dev/null
+++ b/eslint-local-rules/rules/react-compiler.js
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+const {transformFromAstSync} = require('@babel/core');
+const {parse: babelParse} = require('@babel/parser');
+const BabelPluginReactCompiler = require('babel-plugin-react-compiler').default;
+const {
+ parsePluginOptions,
+ validateEnvironmentConfig,
+} = require('babel-plugin-react-compiler');
+
+const COMPILER_OPTIONS = {
+ noEmit: true,
+ panicThreshold: 'none',
+ environment: validateEnvironmentConfig({
+ validateRefAccessDuringRender: true,
+ validateNoSetStateInRender: true,
+ validateNoSetStateInEffects: true,
+ validateNoJSXInTryStatements: true,
+ validateNoImpureFunctionsInRender: true,
+ validateStaticComponents: true,
+ validateNoFreezingKnownMutableFunctions: true,
+ validateNoVoidUseMemo: true,
+ validateNoCapitalizedCalls: [],
+ validateHooksUsage: true,
+ validateNoDerivedComputationsInEffects: true,
+ }),
+};
+
+function hasRelevantCode(code) {
+ const functionPattern = /^(export\s+)?(default\s+)?function\s+\w+/m;
+ const arrowPattern =
+ /^(export\s+)?(const|let|var)\s+\w+\s*=\s*(\([^)]*\)|\w+)\s*=>/m;
+ const hasImports = /^import\s+/m.test(code);
+
+ return functionPattern.test(code) || arrowPattern.test(code) || hasImports;
+}
+
+function runReactCompiler(code, filename) {
+ const result = {
+ sourceCode: code,
+ events: [],
+ };
+
+ if (!hasRelevantCode(code)) {
+ return {...result, diagnostics: []};
+ }
+
+ const options = parsePluginOptions({
+ ...COMPILER_OPTIONS,
+ });
+
+ options.logger = {
+ logEvent: (_, event) => {
+ if (event.kind === 'CompileError') {
+ const category = event.detail?.category;
+ if (category === 'Todo' || category === 'Invariant') {
+ return;
+ }
+ result.events.push(event);
+ }
+ },
+ };
+
+ try {
+ const ast = babelParse(code, {
+ sourceFilename: filename,
+ sourceType: 'module',
+ plugins: ['jsx', 'typescript'],
+ });
+
+ transformFromAstSync(ast, code, {
+ filename,
+ highlightCode: false,
+ retainLines: true,
+ plugins: [[BabelPluginReactCompiler, options]],
+ sourceType: 'module',
+ configFile: false,
+ babelrc: false,
+ });
+ } catch (error) {
+ return {...result, diagnostics: []};
+ }
+
+ const diagnostics = [];
+
+ for (const event of result.events) {
+ if (event.kind !== 'CompileError') {
+ continue;
+ }
+
+ const detail = event.detail;
+ if (!detail) {
+ continue;
+ }
+
+ const loc = typeof detail.primaryLocation === 'function'
+ ? detail.primaryLocation()
+ : null;
+
+ if (loc == null || typeof loc === 'symbol') {
+ continue;
+ }
+
+ const message = typeof detail.printErrorMessage === 'function'
+ ? detail.printErrorMessage(result.sourceCode, {eslint: true})
+ : detail.description || 'Unknown React Compiler error';
+
+ diagnostics.push({detail, loc, message});
+ }
+
+ return {...result, diagnostics};
+}
+
+module.exports = {
+ hasRelevantCode,
+ runReactCompiler,
+};
diff --git a/eslint-local-rules/yarn.lock b/eslint-local-rules/yarn.lock
new file mode 100644
index 000000000..5a7cf126d
--- /dev/null
+++ b/eslint-local-rules/yarn.lock
@@ -0,0 +1,1421 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+"@babel/code-frame@^7.16.0":
+ version "7.27.1"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be"
+ integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.27.1"
+ js-tokens "^4.0.0"
+ picocolors "^1.1.1"
+
+"@babel/helper-validator-identifier@^7.27.1":
+ version "7.27.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8"
+ integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==
+
+"@isaacs/cliui@^8.0.2":
+ version "8.0.2"
+ resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
+ integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==
+ dependencies:
+ string-width "^5.1.2"
+ string-width-cjs "npm:string-width@^4.2.0"
+ strip-ansi "^7.0.1"
+ strip-ansi-cjs "npm:strip-ansi@^6.0.1"
+ wrap-ansi "^8.1.0"
+ wrap-ansi-cjs "npm:wrap-ansi@^7.0.0"
+
+"@npmcli/config@^6.0.0":
+ version "6.4.1"
+ resolved "https://registry.yarnpkg.com/@npmcli/config/-/config-6.4.1.tgz#006409c739635db008e78bf58c92421cc147911d"
+ integrity sha512-uSz+elSGzjCMANWa5IlbGczLYPkNI/LeR+cHrgaTqTrTSh9RHhOFA4daD2eRUz6lMtOW+Fnsb+qv7V2Zz8ML0g==
+ dependencies:
+ "@npmcli/map-workspaces" "^3.0.2"
+ ci-info "^4.0.0"
+ ini "^4.1.0"
+ nopt "^7.0.0"
+ proc-log "^3.0.0"
+ read-package-json-fast "^3.0.2"
+ semver "^7.3.5"
+ walk-up-path "^3.0.1"
+
+"@npmcli/map-workspaces@^3.0.2":
+ version "3.0.6"
+ resolved "https://registry.yarnpkg.com/@npmcli/map-workspaces/-/map-workspaces-3.0.6.tgz#27dc06c20c35ef01e45a08909cab9cb3da08cea6"
+ integrity sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==
+ dependencies:
+ "@npmcli/name-from-folder" "^2.0.0"
+ glob "^10.2.2"
+ minimatch "^9.0.0"
+ read-package-json-fast "^3.0.0"
+
+"@npmcli/name-from-folder@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@npmcli/name-from-folder/-/name-from-folder-2.0.0.tgz#c44d3a7c6d5c184bb6036f4d5995eee298945815"
+ integrity sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==
+
+"@pkgjs/parseargs@^0.11.0":
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
+ integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
+
+"@pkgr/core@^0.1.0":
+ version "0.1.2"
+ resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.2.tgz#1cf95080bb7072fafaa3cb13b442fab4695c3893"
+ integrity sha512-fdDH1LSGfZdTH2sxdpVMw31BanV28K/Gry0cVFxaNP77neJSkd82mM8ErPNYs9e+0O7SdHBLTDzDgwUuy18RnQ==
+
+"@types/acorn@^4.0.0":
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/@types/acorn/-/acorn-4.0.6.tgz#d61ca5480300ac41a7d973dd5b84d0a591154a22"
+ integrity sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==
+ dependencies:
+ "@types/estree" "*"
+
+"@types/concat-stream@^2.0.0":
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/@types/concat-stream/-/concat-stream-2.0.3.tgz#1f5c2ad26525716c181191f7ed53408f78eb758e"
+ integrity sha512-3qe4oQAPNwVNwK4C9c8u+VJqv9kez+2MR4qJpoPFfXtgxxif1QbFusvXzK0/Wra2VX07smostI2VMmJNSpZjuQ==
+ dependencies:
+ "@types/node" "*"
+
+"@types/debug@^4.0.0":
+ version "4.1.12"
+ resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917"
+ integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==
+ dependencies:
+ "@types/ms" "*"
+
+"@types/estree-jsx@^1.0.0":
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.5.tgz#858a88ea20f34fe65111f005a689fa1ebf70dc18"
+ integrity sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==
+ dependencies:
+ "@types/estree" "*"
+
+"@types/estree@*", "@types/estree@^1.0.0":
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e"
+ integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
+
+"@types/hast@^2.0.0":
+ version "2.3.10"
+ resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.10.tgz#5c9d9e0b304bbb8879b857225c5ebab2d81d7643"
+ integrity sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==
+ dependencies:
+ "@types/unist" "^2"
+
+"@types/is-empty@^1.0.0":
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/@types/is-empty/-/is-empty-1.2.3.tgz#a2d55ea8a5ec57bf61e411ba2a9e5132fe4f0899"
+ integrity sha512-4J1l5d79hoIvsrKh5VUKVRA1aIdsOb10Hu5j3J2VfP/msDnfTdGPmNp2E1Wg+vs97Bktzo+MZePFFXSGoykYJw==
+
+"@types/mdast@^3.0.0":
+ version "3.0.15"
+ resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5"
+ integrity sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==
+ dependencies:
+ "@types/unist" "^2"
+
+"@types/ms@*":
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78"
+ integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==
+
+"@types/node@*":
+ version "24.5.1"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-24.5.1.tgz#dab6917c47113eb4502d27d06e89a407ec0eff95"
+ integrity sha512-/SQdmUP2xa+1rdx7VwB9yPq8PaKej8TD5cQ+XfKDPWWC+VDJU4rvVVagXqKUzhKjtFoNA8rXDJAkCxQPAe00+Q==
+ dependencies:
+ undici-types "~7.12.0"
+
+"@types/node@^18.0.0":
+ version "18.19.126"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.126.tgz#b1a9e0bac6338098f465ab242cbd6a8884d79b80"
+ integrity sha512-8AXQlBfrGmtYJEJUPs63F/uZQqVeFiN9o6NUjbDJYfxNxFnArlZufANPw4h6dGhYGKxcyw+TapXFvEsguzIQow==
+ dependencies:
+ undici-types "~5.26.4"
+
+"@types/supports-color@^8.0.0":
+ version "8.1.3"
+ resolved "https://registry.yarnpkg.com/@types/supports-color/-/supports-color-8.1.3.tgz#b769cdce1d1bb1a3fa794e35b62c62acdf93c139"
+ integrity sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg==
+
+"@types/unist@^2", "@types/unist@^2.0.0":
+ version "2.0.11"
+ resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.11.tgz#11af57b127e32487774841f7a4e54eab166d03c4"
+ integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==
+
+abbrev@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf"
+ integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==
+
+acorn-jsx@^5.0.0, acorn-jsx@^5.3.2:
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
+ integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
+
+acorn@^8.0.0, acorn@^8.10.0, acorn@^8.9.0:
+ version "8.15.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816"
+ integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
+
+ansi-regex@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+ integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+
+ansi-regex@^6.0.1:
+ version "6.2.2"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1"
+ integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==
+
+ansi-styles@^4.0.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
+ integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
+ dependencies:
+ color-convert "^2.0.1"
+
+ansi-styles@^6.1.0:
+ version "6.2.3"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.3.tgz#c044d5dcc521a076413472597a1acb1f103c4041"
+ integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==
+
+bail@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d"
+ integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==
+
+balanced-match@^1.0.0:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
+ integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
+
+brace-expansion@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7"
+ integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==
+ dependencies:
+ balanced-match "^1.0.0"
+
+buffer-from@^1.0.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
+ integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
+
+ccount@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5"
+ integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==
+
+character-entities-html4@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b"
+ integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==
+
+character-entities-legacy@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b"
+ integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==
+
+character-entities@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22"
+ integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==
+
+character-reference-invalid@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9"
+ integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==
+
+ci-info@^4.0.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.3.0.tgz#c39b1013f8fdbd28cd78e62318357d02da160cd7"
+ integrity sha512-l+2bNRMiQgcfILUi33labAZYIWlH1kWDp+ecNo5iisRKrbm0xcRyCww71/YU0Fkw0mAFpz9bJayXPjey6vkmaQ==
+
+color-convert@^2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
+ integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
+ dependencies:
+ color-name "~1.1.4"
+
+color-name@~1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
+ integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
+
+concat-stream@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1"
+ integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==
+ dependencies:
+ buffer-from "^1.0.0"
+ inherits "^2.0.3"
+ readable-stream "^3.0.2"
+ typedarray "^0.0.6"
+
+cross-spawn@^7.0.6:
+ version "7.0.6"
+ resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
+ integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
+ dependencies:
+ path-key "^3.1.0"
+ shebang-command "^2.0.0"
+ which "^2.0.1"
+
+debug@^4.0.0:
+ version "4.4.3"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
+ integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
+ dependencies:
+ ms "^2.1.3"
+
+decode-named-character-reference@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz#25c32ae6dd5e21889549d40f676030e9514cc0ed"
+ integrity sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==
+ dependencies:
+ character-entities "^2.0.0"
+
+dequal@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
+ integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
+
+diff@^5.0.0:
+ version "5.2.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531"
+ integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==
+
+eastasianwidth@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
+ integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
+
+emoji-regex@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
+ integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
+
+emoji-regex@^9.2.2:
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
+ integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
+
+error-ex@^1.3.2:
+ version "1.3.4"
+ resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.4.tgz#b3a8d8bb6f92eecc1629e3e27d3c8607a8a32414"
+ integrity sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==
+ dependencies:
+ is-arrayish "^0.2.1"
+
+eslint-mdx@^2:
+ version "2.3.4"
+ resolved "https://registry.yarnpkg.com/eslint-mdx/-/eslint-mdx-2.3.4.tgz#87a5d95d6fcb27bafd2b15092f16f5aa559e336b"
+ integrity sha512-u4NszEUyoGtR7Q0A4qs0OymsEQdCO6yqWlTzDa9vGWsK7aMotdnW0hqifHTkf6lEtA2vHk2xlkWHTCrhYLyRbw==
+ dependencies:
+ acorn "^8.10.0"
+ acorn-jsx "^5.3.2"
+ espree "^9.6.1"
+ estree-util-visit "^1.2.1"
+ remark-mdx "^2.3.0"
+ remark-parse "^10.0.2"
+ remark-stringify "^10.0.3"
+ synckit "^0.9.0"
+ tslib "^2.6.1"
+ unified "^10.1.2"
+ unified-engine "^10.1.0"
+ unist-util-visit "^4.1.2"
+ uvu "^0.5.6"
+ vfile "^5.3.7"
+
+eslint-visitor-keys@^3.4.1:
+ version "3.4.3"
+ resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
+ integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
+
+espree@^9.6.1:
+ version "9.6.1"
+ resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f"
+ integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==
+ dependencies:
+ acorn "^8.9.0"
+ acorn-jsx "^5.3.2"
+ eslint-visitor-keys "^3.4.1"
+
+estree-util-is-identifier-name@^2.0.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.1.0.tgz#fb70a432dcb19045e77b05c8e732f1364b4b49b2"
+ integrity sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ==
+
+estree-util-visit@^1.0.0, estree-util-visit@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/estree-util-visit/-/estree-util-visit-1.2.1.tgz#8bc2bc09f25b00827294703835aabee1cc9ec69d"
+ integrity sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw==
+ dependencies:
+ "@types/estree-jsx" "^1.0.0"
+ "@types/unist" "^2.0.0"
+
+extend@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
+ integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
+
+fault@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/fault/-/fault-2.0.1.tgz#d47ca9f37ca26e4bd38374a7c500b5a384755b6c"
+ integrity sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==
+ dependencies:
+ format "^0.2.0"
+
+foreground-child@^3.1.0:
+ version "3.3.1"
+ resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f"
+ integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==
+ dependencies:
+ cross-spawn "^7.0.6"
+ signal-exit "^4.0.1"
+
+format@^0.2.0:
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b"
+ integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==
+
+fs.realpath@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
+ integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
+
+glob@^10.2.2:
+ version "10.4.5"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956"
+ integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==
+ dependencies:
+ foreground-child "^3.1.0"
+ jackspeak "^3.1.2"
+ minimatch "^9.0.4"
+ minipass "^7.1.2"
+ package-json-from-dist "^1.0.0"
+ path-scurry "^1.11.1"
+
+glob@^8.0.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e"
+ integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
+ dependencies:
+ fs.realpath "^1.0.0"
+ inflight "^1.0.4"
+ inherits "2"
+ minimatch "^5.0.1"
+ once "^1.3.0"
+
+ignore@^5.0.0:
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5"
+ integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
+
+import-meta-resolve@^2.0.0:
+ version "2.2.2"
+ resolved "https://registry.yarnpkg.com/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz#75237301e72d1f0fbd74dbc6cca9324b164c2cc9"
+ integrity sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==
+
+inflight@^1.0.4:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
+ integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
+ dependencies:
+ once "^1.3.0"
+ wrappy "1"
+
+inherits@2, inherits@^2.0.3:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
+ integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+
+ini@^4.1.0:
+ version "4.1.3"
+ resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.3.tgz#4c359675a6071a46985eb39b14e4a2c0ec98a795"
+ integrity sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==
+
+is-alphabetical@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b"
+ integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==
+
+is-alphanumerical@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz#7c03fbe96e3e931113e57f964b0a368cc2dfd875"
+ integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==
+ dependencies:
+ is-alphabetical "^2.0.0"
+ is-decimal "^2.0.0"
+
+is-arrayish@^0.2.1:
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
+ integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
+
+is-buffer@^2.0.0:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
+ integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
+
+is-decimal@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-2.0.1.tgz#9469d2dc190d0214fd87d78b78caecc0cc14eef7"
+ integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==
+
+is-empty@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/is-empty/-/is-empty-1.2.0.tgz#de9bb5b278738a05a0b09a57e1fb4d4a341a9f6b"
+ integrity sha512-F2FnH/otLNJv0J6wc73A5Xo7oHLNnqplYqZhUu01tD54DIPvxIRSTSLkrUB/M0nHO4vo1O9PDfN4KoTxCzLh/w==
+
+is-fullwidth-code-point@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
+ integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
+
+is-hexadecimal@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz#86b5bf668fca307498d319dfc03289d781a90027"
+ integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==
+
+is-plain-obj@^4.0.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0"
+ integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==
+
+isexe@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
+ integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
+
+jackspeak@^3.1.2:
+ version "3.4.3"
+ resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a"
+ integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==
+ dependencies:
+ "@isaacs/cliui" "^8.0.2"
+ optionalDependencies:
+ "@pkgjs/parseargs" "^0.11.0"
+
+js-tokens@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
+ integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
+
+json-parse-even-better-errors@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
+ integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
+
+json-parse-even-better-errors@^3.0.0:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz#b43d35e89c0f3be6b5fbbe9dc6c82467b30c28da"
+ integrity sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==
+
+kleur@^4.0.3:
+ version "4.1.5"
+ resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780"
+ integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==
+
+lines-and-columns@^2.0.2:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz#d00318855905d2660d8c0822e3f5a4715855fc42"
+ integrity sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==
+
+load-plugin@^5.0.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/load-plugin/-/load-plugin-5.1.0.tgz#15600f5191c742b16e058cfc908c227c13db0104"
+ integrity sha512-Lg1CZa1CFj2CbNaxijTL6PCbzd4qGTlZov+iH2p5Xwy/ApcZJh+i6jMN2cYePouTfjJfrNu3nXFdEw8LvbjPFQ==
+ dependencies:
+ "@npmcli/config" "^6.0.0"
+ import-meta-resolve "^2.0.0"
+
+longest-streak@^3.0.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4"
+ integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==
+
+lru-cache@^10.2.0:
+ version "10.4.3"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119"
+ integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==
+
+mdast-util-from-markdown@^1.0.0, mdast-util-from-markdown@^1.1.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz#9421a5a247f10d31d2faed2a30df5ec89ceafcf0"
+ integrity sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==
+ dependencies:
+ "@types/mdast" "^3.0.0"
+ "@types/unist" "^2.0.0"
+ decode-named-character-reference "^1.0.0"
+ mdast-util-to-string "^3.1.0"
+ micromark "^3.0.0"
+ micromark-util-decode-numeric-character-reference "^1.0.0"
+ micromark-util-decode-string "^1.0.0"
+ micromark-util-normalize-identifier "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ unist-util-stringify-position "^3.0.0"
+ uvu "^0.5.0"
+
+mdast-util-mdx-expression@^1.0.0:
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.3.2.tgz#d027789e67524d541d6de543f36d51ae2586f220"
+ integrity sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==
+ dependencies:
+ "@types/estree-jsx" "^1.0.0"
+ "@types/hast" "^2.0.0"
+ "@types/mdast" "^3.0.0"
+ mdast-util-from-markdown "^1.0.0"
+ mdast-util-to-markdown "^1.0.0"
+
+mdast-util-mdx-jsx@^2.0.0:
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-2.1.4.tgz#7c1f07f10751a78963cfabee38017cbc8b7786d1"
+ integrity sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA==
+ dependencies:
+ "@types/estree-jsx" "^1.0.0"
+ "@types/hast" "^2.0.0"
+ "@types/mdast" "^3.0.0"
+ "@types/unist" "^2.0.0"
+ ccount "^2.0.0"
+ mdast-util-from-markdown "^1.1.0"
+ mdast-util-to-markdown "^1.3.0"
+ parse-entities "^4.0.0"
+ stringify-entities "^4.0.0"
+ unist-util-remove-position "^4.0.0"
+ unist-util-stringify-position "^3.0.0"
+ vfile-message "^3.0.0"
+
+mdast-util-mdx@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/mdast-util-mdx/-/mdast-util-mdx-2.0.1.tgz#49b6e70819b99bb615d7223c088d295e53bb810f"
+ integrity sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw==
+ dependencies:
+ mdast-util-from-markdown "^1.0.0"
+ mdast-util-mdx-expression "^1.0.0"
+ mdast-util-mdx-jsx "^2.0.0"
+ mdast-util-mdxjs-esm "^1.0.0"
+ mdast-util-to-markdown "^1.0.0"
+
+mdast-util-mdxjs-esm@^1.0.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-1.3.1.tgz#645d02cd607a227b49721d146fd81796b2e2d15b"
+ integrity sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w==
+ dependencies:
+ "@types/estree-jsx" "^1.0.0"
+ "@types/hast" "^2.0.0"
+ "@types/mdast" "^3.0.0"
+ mdast-util-from-markdown "^1.0.0"
+ mdast-util-to-markdown "^1.0.0"
+
+mdast-util-phrasing@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz#c7c21d0d435d7fb90956038f02e8702781f95463"
+ integrity sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==
+ dependencies:
+ "@types/mdast" "^3.0.0"
+ unist-util-is "^5.0.0"
+
+mdast-util-to-markdown@^1.0.0, mdast-util-to-markdown@^1.3.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz#c13343cb3fc98621911d33b5cd42e7d0731171c6"
+ integrity sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==
+ dependencies:
+ "@types/mdast" "^3.0.0"
+ "@types/unist" "^2.0.0"
+ longest-streak "^3.0.0"
+ mdast-util-phrasing "^3.0.0"
+ mdast-util-to-string "^3.0.0"
+ micromark-util-decode-string "^1.0.0"
+ unist-util-visit "^4.0.0"
+ zwitch "^2.0.0"
+
+mdast-util-to-string@^3.0.0, mdast-util-to-string@^3.1.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz#66f7bb6324756741c5f47a53557f0cbf16b6f789"
+ integrity sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==
+ dependencies:
+ "@types/mdast" "^3.0.0"
+
+micromark-core-commonmark@^1.0.0, micromark-core-commonmark@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz#1386628df59946b2d39fb2edfd10f3e8e0a75bb8"
+ integrity sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==
+ dependencies:
+ decode-named-character-reference "^1.0.0"
+ micromark-factory-destination "^1.0.0"
+ micromark-factory-label "^1.0.0"
+ micromark-factory-space "^1.0.0"
+ micromark-factory-title "^1.0.0"
+ micromark-factory-whitespace "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-chunked "^1.0.0"
+ micromark-util-classify-character "^1.0.0"
+ micromark-util-html-tag-name "^1.0.0"
+ micromark-util-normalize-identifier "^1.0.0"
+ micromark-util-resolve-all "^1.0.0"
+ micromark-util-subtokenize "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.1"
+ uvu "^0.5.0"
+
+micromark-extension-mdx-expression@^1.0.0:
+ version "1.0.8"
+ resolved "https://registry.yarnpkg.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.8.tgz#5bc1f5fd90388e8293b3ef4f7c6f06c24aff6314"
+ integrity sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==
+ dependencies:
+ "@types/estree" "^1.0.0"
+ micromark-factory-mdx-expression "^1.0.0"
+ micromark-factory-space "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-events-to-acorn "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ uvu "^0.5.0"
+
+micromark-extension-mdx-jsx@^1.0.0:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-1.0.5.tgz#e72d24b7754a30d20fb797ece11e2c4e2cae9e82"
+ integrity sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA==
+ dependencies:
+ "@types/acorn" "^4.0.0"
+ "@types/estree" "^1.0.0"
+ estree-util-is-identifier-name "^2.0.0"
+ micromark-factory-mdx-expression "^1.0.0"
+ micromark-factory-space "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ uvu "^0.5.0"
+ vfile-message "^3.0.0"
+
+micromark-extension-mdx-md@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/micromark-extension-mdx-md/-/micromark-extension-mdx-md-1.0.1.tgz#595d4b2f692b134080dca92c12272ab5b74c6d1a"
+ integrity sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA==
+ dependencies:
+ micromark-util-types "^1.0.0"
+
+micromark-extension-mdxjs-esm@^1.0.0:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-1.0.5.tgz#e4f8be9c14c324a80833d8d3a227419e2b25dec1"
+ integrity sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w==
+ dependencies:
+ "@types/estree" "^1.0.0"
+ micromark-core-commonmark "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-events-to-acorn "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ unist-util-position-from-estree "^1.1.0"
+ uvu "^0.5.0"
+ vfile-message "^3.0.0"
+
+micromark-extension-mdxjs@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs/-/micromark-extension-mdxjs-1.0.1.tgz#f78d4671678d16395efeda85170c520ee795ded8"
+ integrity sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q==
+ dependencies:
+ acorn "^8.0.0"
+ acorn-jsx "^5.0.0"
+ micromark-extension-mdx-expression "^1.0.0"
+ micromark-extension-mdx-jsx "^1.0.0"
+ micromark-extension-mdx-md "^1.0.0"
+ micromark-extension-mdxjs-esm "^1.0.0"
+ micromark-util-combine-extensions "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-factory-destination@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz#eb815957d83e6d44479b3df640f010edad667b9f"
+ integrity sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-factory-label@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz#cc95d5478269085cfa2a7282b3de26eb2e2dec68"
+ integrity sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ uvu "^0.5.0"
+
+micromark-factory-mdx-expression@^1.0.0:
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.9.tgz#57ba4571b69a867a1530f34741011c71c73a4976"
+ integrity sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==
+ dependencies:
+ "@types/estree" "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-events-to-acorn "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ unist-util-position-from-estree "^1.0.0"
+ uvu "^0.5.0"
+ vfile-message "^3.0.0"
+
+micromark-factory-space@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz#c8f40b0640a0150751d3345ed885a080b0d15faf"
+ integrity sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-factory-title@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz#dd0fe951d7a0ac71bdc5ee13e5d1465ad7f50ea1"
+ integrity sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==
+ dependencies:
+ micromark-factory-space "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-factory-whitespace@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz#798fb7489f4c8abafa7ca77eed6b5745853c9705"
+ integrity sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==
+ dependencies:
+ micromark-factory-space "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-util-character@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.2.0.tgz#4fedaa3646db249bc58caeb000eb3549a8ca5dcc"
+ integrity sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==
+ dependencies:
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-util-chunked@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz#37a24d33333c8c69a74ba12a14651fd9ea8a368b"
+ integrity sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==
+ dependencies:
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-classify-character@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz#6a7f8c8838e8a120c8e3c4f2ae97a2bff9190e9d"
+ integrity sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-util-combine-extensions@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz#192e2b3d6567660a85f735e54d8ea6e3952dbe84"
+ integrity sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==
+ dependencies:
+ micromark-util-chunked "^1.0.0"
+ micromark-util-types "^1.0.0"
+
+micromark-util-decode-numeric-character-reference@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz#b1e6e17009b1f20bc652a521309c5f22c85eb1c6"
+ integrity sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==
+ dependencies:
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-decode-string@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz#dc12b078cba7a3ff690d0203f95b5d5537f2809c"
+ integrity sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==
+ dependencies:
+ decode-named-character-reference "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-decode-numeric-character-reference "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-encode@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz#92e4f565fd4ccb19e0dcae1afab9a173bbeb19a5"
+ integrity sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==
+
+micromark-util-events-to-acorn@^1.0.0:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.3.tgz#a4ab157f57a380e646670e49ddee97a72b58b557"
+ integrity sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==
+ dependencies:
+ "@types/acorn" "^4.0.0"
+ "@types/estree" "^1.0.0"
+ "@types/unist" "^2.0.0"
+ estree-util-visit "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ uvu "^0.5.0"
+ vfile-message "^3.0.0"
+
+micromark-util-html-tag-name@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz#48fd7a25826f29d2f71479d3b4e83e94829b3588"
+ integrity sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==
+
+micromark-util-normalize-identifier@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz#7a73f824eb9f10d442b4d7f120fecb9b38ebf8b7"
+ integrity sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==
+ dependencies:
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-resolve-all@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz#4652a591ee8c8fa06714c9b54cd6c8e693671188"
+ integrity sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==
+ dependencies:
+ micromark-util-types "^1.0.0"
+
+micromark-util-sanitize-uri@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz#613f738e4400c6eedbc53590c67b197e30d7f90d"
+ integrity sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==
+ dependencies:
+ micromark-util-character "^1.0.0"
+ micromark-util-encode "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+
+micromark-util-subtokenize@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz#941c74f93a93eaf687b9054aeb94642b0e92edb1"
+ integrity sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==
+ dependencies:
+ micromark-util-chunked "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.0"
+ uvu "^0.5.0"
+
+micromark-util-symbol@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz#813cd17837bdb912d069a12ebe3a44b6f7063142"
+ integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==
+
+micromark-util-types@^1.0.0, micromark-util-types@^1.0.1:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.1.0.tgz#e6676a8cae0bb86a2171c498167971886cb7e283"
+ integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==
+
+micromark@^3.0.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.2.0.tgz#1af9fef3f995ea1ea4ac9c7e2f19c48fd5c006e9"
+ integrity sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==
+ dependencies:
+ "@types/debug" "^4.0.0"
+ debug "^4.0.0"
+ decode-named-character-reference "^1.0.0"
+ micromark-core-commonmark "^1.0.1"
+ micromark-factory-space "^1.0.0"
+ micromark-util-character "^1.0.0"
+ micromark-util-chunked "^1.0.0"
+ micromark-util-combine-extensions "^1.0.0"
+ micromark-util-decode-numeric-character-reference "^1.0.0"
+ micromark-util-encode "^1.0.0"
+ micromark-util-normalize-identifier "^1.0.0"
+ micromark-util-resolve-all "^1.0.0"
+ micromark-util-sanitize-uri "^1.0.0"
+ micromark-util-subtokenize "^1.0.0"
+ micromark-util-symbol "^1.0.0"
+ micromark-util-types "^1.0.1"
+ uvu "^0.5.0"
+
+minimatch@^5.0.1:
+ version "5.1.6"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
+ integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
+ dependencies:
+ brace-expansion "^2.0.1"
+
+minimatch@^9.0.0, minimatch@^9.0.4:
+ version "9.0.5"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5"
+ integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
+ dependencies:
+ brace-expansion "^2.0.1"
+
+"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707"
+ integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==
+
+mri@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
+ integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
+
+ms@^2.1.3:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
+nopt@^7.0.0:
+ version "7.2.1"
+ resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.1.tgz#1cac0eab9b8e97c9093338446eddd40b2c8ca1e7"
+ integrity sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==
+ dependencies:
+ abbrev "^2.0.0"
+
+npm-normalize-package-bin@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz#25447e32a9a7de1f51362c61a559233b89947832"
+ integrity sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==
+
+once@^1.3.0:
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
+ integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
+ dependencies:
+ wrappy "1"
+
+package-json-from-dist@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505"
+ integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==
+
+parse-entities@^4.0.0:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.2.tgz#61d46f5ed28e4ee62e9ddc43d6b010188443f159"
+ integrity sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ character-entities-legacy "^3.0.0"
+ character-reference-invalid "^2.0.0"
+ decode-named-character-reference "^1.0.0"
+ is-alphanumerical "^2.0.0"
+ is-decimal "^2.0.0"
+ is-hexadecimal "^2.0.0"
+
+parse-json@^6.0.0:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-6.0.2.tgz#6bf79c201351cc12d5d66eba48d5a097c13dc200"
+ integrity sha512-SA5aMiaIjXkAiBrW/yPgLgQAQg42f7K3ACO+2l/zOvtQBwX58DMUsFJXelW2fx3yMBmWOVkR6j1MGsdSbCA4UA==
+ dependencies:
+ "@babel/code-frame" "^7.16.0"
+ error-ex "^1.3.2"
+ json-parse-even-better-errors "^2.3.1"
+ lines-and-columns "^2.0.2"
+
+path-key@^3.1.0:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
+ integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
+
+path-scurry@^1.11.1:
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2"
+ integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==
+ dependencies:
+ lru-cache "^10.2.0"
+ minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
+
+picocolors@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
+ integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
+
+proc-log@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8"
+ integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==
+
+read-package-json-fast@^3.0.0, read-package-json-fast@^3.0.2:
+ version "3.0.2"
+ resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz#394908a9725dc7a5f14e70c8e7556dff1d2b1049"
+ integrity sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==
+ dependencies:
+ json-parse-even-better-errors "^3.0.0"
+ npm-normalize-package-bin "^3.0.0"
+
+readable-stream@^3.0.2:
+ version "3.6.2"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
+ integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
+ dependencies:
+ inherits "^2.0.3"
+ string_decoder "^1.1.1"
+ util-deprecate "^1.0.1"
+
+remark-mdx@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-2.3.0.tgz#efe678025a8c2726681bde8bf111af4a93943db4"
+ integrity sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g==
+ dependencies:
+ mdast-util-mdx "^2.0.0"
+ micromark-extension-mdxjs "^1.0.0"
+
+remark-parse@^10.0.2:
+ version "10.0.2"
+ resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-10.0.2.tgz#ca241fde8751c2158933f031a4e3efbaeb8bc262"
+ integrity sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==
+ dependencies:
+ "@types/mdast" "^3.0.0"
+ mdast-util-from-markdown "^1.0.0"
+ unified "^10.0.0"
+
+remark-stringify@^10.0.3:
+ version "10.0.3"
+ resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-10.0.3.tgz#83b43f2445c4ffbb35b606f967d121b2b6d69717"
+ integrity sha512-koyOzCMYoUHudypbj4XpnAKFbkddRMYZHwghnxd7ue5210WzGw6kOBwauJTRUMq16jsovXx8dYNvSSWP89kZ3A==
+ dependencies:
+ "@types/mdast" "^3.0.0"
+ mdast-util-to-markdown "^1.0.0"
+ unified "^10.0.0"
+
+sade@^1.7.3:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701"
+ integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==
+ dependencies:
+ mri "^1.1.0"
+
+safe-buffer@~5.2.0:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
+ integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
+
+semver@^7.3.5:
+ version "7.7.2"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58"
+ integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==
+
+shebang-command@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
+ integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
+ dependencies:
+ shebang-regex "^3.0.0"
+
+shebang-regex@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
+ integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
+
+signal-exit@^4.0.1:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
+ integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
+
+"string-width-cjs@npm:string-width@^4.2.0":
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+ integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+ dependencies:
+ emoji-regex "^8.0.0"
+ is-fullwidth-code-point "^3.0.0"
+ strip-ansi "^6.0.1"
+
+string-width@^4.1.0:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+ integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
+ dependencies:
+ emoji-regex "^8.0.0"
+ is-fullwidth-code-point "^3.0.0"
+ strip-ansi "^6.0.1"
+
+string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
+ integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
+ dependencies:
+ eastasianwidth "^0.2.0"
+ emoji-regex "^9.2.2"
+ strip-ansi "^7.0.1"
+
+string_decoder@^1.1.1:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
+ integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
+ dependencies:
+ safe-buffer "~5.2.0"
+
+stringify-entities@^4.0.0:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.4.tgz#b3b79ef5f277cc4ac73caeb0236c5ba939b3a4f3"
+ integrity sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==
+ dependencies:
+ character-entities-html4 "^2.0.0"
+ character-entities-legacy "^3.0.0"
+
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
+strip-ansi@^7.0.1:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.2.tgz#132875abde678c7ea8d691533f2e7e22bb744dba"
+ integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==
+ dependencies:
+ ansi-regex "^6.0.1"
+
+supports-color@^9.0.0:
+ version "9.4.0"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-9.4.0.tgz#17bfcf686288f531db3dea3215510621ccb55954"
+ integrity sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==
+
+synckit@^0.9.0:
+ version "0.9.3"
+ resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.9.3.tgz#1cfd60d9e61f931e07fb7f56f474b5eb31b826a7"
+ integrity sha512-JJoOEKTfL1urb1mDoEblhD9NhEbWmq9jHEMEnxoC4ujUaZ4itA8vKgwkFAyNClgxplLi9tsUKX+EduK0p/l7sg==
+ dependencies:
+ "@pkgr/core" "^0.1.0"
+ tslib "^2.6.2"
+
+to-vfile@^7.0.0:
+ version "7.2.4"
+ resolved "https://registry.yarnpkg.com/to-vfile/-/to-vfile-7.2.4.tgz#b97ecfcc15905ffe020bc975879053928b671378"
+ integrity sha512-2eQ+rJ2qGbyw3senPI0qjuM7aut8IYXK6AEoOWb+fJx/mQYzviTckm1wDjq91QYHAPBTYzmdJXxMFA6Mk14mdw==
+ dependencies:
+ is-buffer "^2.0.0"
+ vfile "^5.1.0"
+
+trough@^2.0.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/trough/-/trough-2.2.0.tgz#94a60bd6bd375c152c1df911a4b11d5b0256f50f"
+ integrity sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==
+
+tslib@^2.6.1, tslib@^2.6.2:
+ version "2.8.1"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
+ integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
+
+typedarray@^0.0.6:
+ version "0.0.6"
+ resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
+ integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==
+
+undici-types@~5.26.4:
+ version "5.26.5"
+ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
+ integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
+
+undici-types@~7.12.0:
+ version "7.12.0"
+ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.12.0.tgz#15c5c7475c2a3ba30659529f5cdb4674b622fafb"
+ integrity sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==
+
+unified-engine@^10.1.0:
+ version "10.1.0"
+ resolved "https://registry.yarnpkg.com/unified-engine/-/unified-engine-10.1.0.tgz#6899f00d1f53ee9af94f7abd0ec21242aae3f56c"
+ integrity sha512-5+JDIs4hqKfHnJcVCxTid1yBoI/++FfF/1PFdSMpaftZZZY+qg2JFruRbf7PaIwa9KgLotXQV3gSjtY0IdcFGQ==
+ dependencies:
+ "@types/concat-stream" "^2.0.0"
+ "@types/debug" "^4.0.0"
+ "@types/is-empty" "^1.0.0"
+ "@types/node" "^18.0.0"
+ "@types/unist" "^2.0.0"
+ concat-stream "^2.0.0"
+ debug "^4.0.0"
+ fault "^2.0.0"
+ glob "^8.0.0"
+ ignore "^5.0.0"
+ is-buffer "^2.0.0"
+ is-empty "^1.0.0"
+ is-plain-obj "^4.0.0"
+ load-plugin "^5.0.0"
+ parse-json "^6.0.0"
+ to-vfile "^7.0.0"
+ trough "^2.0.0"
+ unist-util-inspect "^7.0.0"
+ vfile-message "^3.0.0"
+ vfile-reporter "^7.0.0"
+ vfile-statistics "^2.0.0"
+ yaml "^2.0.0"
+
+unified@^10.0.0, unified@^10.1.2:
+ version "10.1.2"
+ resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df"
+ integrity sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ bail "^2.0.0"
+ extend "^3.0.0"
+ is-buffer "^2.0.0"
+ is-plain-obj "^4.0.0"
+ trough "^2.0.0"
+ vfile "^5.0.0"
+
+unist-util-inspect@^7.0.0:
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/unist-util-inspect/-/unist-util-inspect-7.0.2.tgz#858e4f02ee4053f7c6ada8bc81662901a0ee1893"
+ integrity sha512-Op0XnmHUl6C2zo/yJCwhXQSm/SmW22eDZdWP2qdf4WpGrgO1ZxFodq+5zFyeRGasFjJotAnLgfuD1jkcKqiH1Q==
+ dependencies:
+ "@types/unist" "^2.0.0"
+
+unist-util-is@^5.0.0:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.2.1.tgz#b74960e145c18dcb6226bc57933597f5486deae9"
+ integrity sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==
+ dependencies:
+ "@types/unist" "^2.0.0"
+
+unist-util-position-from-estree@^1.0.0, unist-util-position-from-estree@^1.1.0:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.2.tgz#8ac2480027229de76512079e377afbcabcfcce22"
+ integrity sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww==
+ dependencies:
+ "@types/unist" "^2.0.0"
+
+unist-util-remove-position@^4.0.0:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz#a89be6ea72e23b1a402350832b02a91f6a9afe51"
+ integrity sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ unist-util-visit "^4.0.0"
+
+unist-util-stringify-position@^3.0.0:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz#03ad3348210c2d930772d64b489580c13a7db39d"
+ integrity sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==
+ dependencies:
+ "@types/unist" "^2.0.0"
+
+unist-util-visit-parents@^5.1.1:
+ version "5.1.3"
+ resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz#b4520811b0ca34285633785045df7a8d6776cfeb"
+ integrity sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ unist-util-is "^5.0.0"
+
+unist-util-visit@^4.0.0, unist-util-visit@^4.1.2:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.2.tgz#125a42d1eb876283715a3cb5cceaa531828c72e2"
+ integrity sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ unist-util-is "^5.0.0"
+ unist-util-visit-parents "^5.1.1"
+
+util-deprecate@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+ integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
+
+uvu@^0.5.0, uvu@^0.5.6:
+ version "0.5.6"
+ resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df"
+ integrity sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==
+ dependencies:
+ dequal "^2.0.0"
+ diff "^5.0.0"
+ kleur "^4.0.3"
+ sade "^1.7.3"
+
+vfile-message@^3.0.0:
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.4.tgz#15a50816ae7d7c2d1fa87090a7f9f96612b59dea"
+ integrity sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ unist-util-stringify-position "^3.0.0"
+
+vfile-reporter@^7.0.0:
+ version "7.0.5"
+ resolved "https://registry.yarnpkg.com/vfile-reporter/-/vfile-reporter-7.0.5.tgz#a0cbf3922c08ad428d6db1161ec64a53b5725785"
+ integrity sha512-NdWWXkv6gcd7AZMvDomlQbK3MqFWL1RlGzMn++/O2TI+68+nqxCPTvLugdOtfSzXmjh+xUyhp07HhlrbJjT+mw==
+ dependencies:
+ "@types/supports-color" "^8.0.0"
+ string-width "^5.0.0"
+ supports-color "^9.0.0"
+ unist-util-stringify-position "^3.0.0"
+ vfile "^5.0.0"
+ vfile-message "^3.0.0"
+ vfile-sort "^3.0.0"
+ vfile-statistics "^2.0.0"
+
+vfile-sort@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/vfile-sort/-/vfile-sort-3.0.1.tgz#4b06ec63e2946749b0bb514e736554cd75e441a2"
+ integrity sha512-1os1733XY6y0D5x0ugqSeaVJm9lYgj0j5qdcZQFyxlZOSy1jYarL77lLyb5gK4Wqr1d5OxmuyflSO3zKyFnTFw==
+ dependencies:
+ vfile "^5.0.0"
+ vfile-message "^3.0.0"
+
+vfile-statistics@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/vfile-statistics/-/vfile-statistics-2.0.1.tgz#2e1adae1cd3a45c1ed4f2a24bd103c3d71e4bce3"
+ integrity sha512-W6dkECZmP32EG/l+dp2jCLdYzmnDBIw6jwiLZSER81oR5AHRcVqL+k3Z+pfH1R73le6ayDkJRMk0sutj1bMVeg==
+ dependencies:
+ vfile "^5.0.0"
+ vfile-message "^3.0.0"
+
+vfile@^5.0.0, vfile@^5.1.0, vfile@^5.3.7:
+ version "5.3.7"
+ resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.3.7.tgz#de0677e6683e3380fafc46544cfe603118826ab7"
+ integrity sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==
+ dependencies:
+ "@types/unist" "^2.0.0"
+ is-buffer "^2.0.0"
+ unist-util-stringify-position "^3.0.0"
+ vfile-message "^3.0.0"
+
+walk-up-path@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/walk-up-path/-/walk-up-path-3.0.1.tgz#c8d78d5375b4966c717eb17ada73dbd41490e886"
+ integrity sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==
+
+which@^2.0.1:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
+ integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
+ dependencies:
+ isexe "^2.0.0"
+
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
+ integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+ dependencies:
+ ansi-styles "^4.0.0"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+
+wrap-ansi@^8.1.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
+ integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==
+ dependencies:
+ ansi-styles "^6.1.0"
+ string-width "^5.0.1"
+ strip-ansi "^7.0.1"
+
+wrappy@1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+ integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
+
+yaml@^2.0.0:
+ version "2.8.1"
+ resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.8.1.tgz#1870aa02b631f7e8328b93f8bc574fac5d6c4d79"
+ integrity sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==
+
+zwitch@^2.0.0:
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7"
+ integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==
diff --git a/next-env.d.ts b/next-env.d.ts
index 4f11a03dc..52e831b43 100644
--- a/next-env.d.ts
+++ b/next-env.d.ts
@@ -2,4 +2,4 @@
///
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/basic-features/typescript for more information.
+// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
diff --git a/next.config.js b/next.config.js
index 2ea3e916e..5a5755307 100644
--- a/next.config.js
+++ b/next.config.js
@@ -1,3 +1,10 @@
+/**
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*/
@@ -9,14 +16,10 @@ const nextConfig = {
pageExtensions: ['jsx', 'js', 'ts', 'tsx', 'mdx', 'md'],
reactStrictMode: true,
experimental: {
- plugins: true,
scrollRestoration: true,
- legacyBrowsers: false,
- browsersListForSwc: true,
- },
- env: {
- SANDPACK_BARE_COMPONENTS: process.env.SANDPACK_BARE_COMPONENTS,
+ reactCompiler: true,
},
+ env: {},
webpack: (config, {dev, isServer, ...options}) => {
if (process.env.ANALYZE) {
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');
@@ -35,10 +38,6 @@ const nextConfig = {
const {IgnorePlugin, NormalModuleReplacementPlugin} = require('webpack');
config.plugins.push(
- new NormalModuleReplacementPlugin(
- /^@stitches\/core$/,
- require.resolve('./src/utils/emptyShim.js')
- ),
new NormalModuleReplacementPlugin(
/^raf$/,
require.resolve('./src/utils/rafShim.js')
diff --git a/package.json b/package.json
index f4f9a8026..0efe373e2 100644
--- a/package.json
+++ b/package.json
@@ -7,37 +7,40 @@
"analyze": "ANALYZE=true next build",
"dev": "next-remote-watch ./src/content",
"build": "next build && node --experimental-modules ./scripts/downloadFonts.mjs",
- "lint": "next lint",
- "lint:fix": "next lint --fix",
+ "lint": "next lint && eslint \"src/content/**/*.md\"",
+ "lint:fix": "next lint --fix && eslint \"src/content/**/*.md\" --fix",
"format:source": "prettier --config .prettierrc --write \"{plugins,src}/**/*.{js,ts,jsx,tsx,css}\"",
"nit:source": "prettier --config .prettierrc --list-different \"{plugins,src}/**/*.{js,ts,jsx,tsx,css}\"",
"prettier": "yarn format:source",
"prettier:diff": "yarn nit:source",
"lint-heading-ids": "node scripts/headingIdLinter.js",
"fix-headings": "node scripts/headingIdLinter.js --fix",
- "ci-check": "npm-run-all prettier:diff --parallel lint tsc lint-heading-ids",
+ "ci-check": "npm-run-all prettier:diff --parallel lint tsc lint-heading-ids rss deadlinks",
"tsc": "tsc --noEmit",
"start": "next start",
- "postinstall": "patch-package && (is-ci || husky install .husky)",
- "check-all": "npm-run-all prettier lint:fix tsc"
+ "postinstall": "yarn --cwd eslint-local-rules install && is-ci || husky install .husky",
+ "check-all": "npm-run-all prettier lint:fix tsc rss",
+ "rss": "node scripts/generateRss.js",
+ "deadlinks": "node scripts/deadLinkChecker.js",
+ "copyright": "node scripts/copyright.js",
+ "test:eslint-local-rules": "yarn --cwd eslint-local-rules test"
},
"dependencies": {
- "@codesandbox/sandpack-react": "1.15.5",
- "@docsearch/css": "3.0.0-alpha.41",
- "@docsearch/react": "3.0.0-alpha.41",
+ "@codesandbox/sandpack-react": "2.13.5",
+ "@docsearch/css": "^3.8.3",
+ "@docsearch/react": "^3.8.3",
"@headlessui/react": "^1.7.0",
+ "@radix-ui/react-context-menu": "^2.1.5",
"body-scroll-lock": "^3.1.3",
"classnames": "^2.2.6",
- "date-fns": "^2.16.1",
"debounce": "^1.2.1",
- "ga-lite": "^2.1.4",
"github-slugger": "^1.3.0",
- "next": "12.3.2-canary.7",
+ "next": "15.1.0",
"next-remote-watch": "^1.0.0",
"parse-numeric-range": "^1.2.0",
- "react": "0.0.0-experimental-cb5084d1c-20220924",
- "react-collapsed": "npm:@gaearon/react-collapsed@3.1.0-forked.1",
- "react-dom": "0.0.0-experimental-cb5084d1c-20220924",
+ "react": "^19.0.0",
+ "react-collapsed": "4.0.4",
+ "react-dom": "^19.0.0",
"remark-frontmatter": "^4.0.1",
"remark-gfm": "^3.0.1"
},
@@ -53,20 +56,24 @@
"@types/mdx-js__react": "^1.5.2",
"@types/node": "^14.6.4",
"@types/parse-numeric-range": "^0.0.1",
- "@types/react": "^18.0.9",
- "@types/react-dom": "^18.0.5",
+ "@types/react": "^19.0.0",
+ "@types/react-dom": "^19.0.0",
"@typescript-eslint/eslint-plugin": "^5.36.2",
"@typescript-eslint/parser": "^5.36.2",
"asyncro": "^3.0.0",
"autoprefixer": "^10.4.2",
"babel-eslint": "10.x",
+ "babel-plugin-react-compiler": "^19.1.0-rc.3",
+ "chalk": "4.1.2",
"eslint": "7.x",
"eslint-config-next": "12.0.3",
"eslint-config-react-app": "^5.2.1",
"eslint-plugin-flowtype": "4.x",
"eslint-plugin-import": "2.x",
"eslint-plugin-jsx-a11y": "6.x",
+ "eslint-plugin-local-rules": "link:eslint-local-rules",
"eslint-plugin-react": "7.x",
+ "eslint-plugin-react-compiler": "^19.0.0-beta-e552027-20250112",
"eslint-plugin-react-hooks": "^0.0.0-experimental-fabef7a6b-20221215",
"fs-extra": "^9.0.1",
"globby": "^11.0.1",
@@ -77,7 +84,6 @@
"mdast-util-to-string": "^1.1.0",
"metro-cache": "0.72.2",
"npm-run-all": "^4.1.5",
- "patch-package": "^6.2.2",
"postcss": "^8.4.5",
"postcss-flexbugs-fixes": "4.2.1",
"postcss-preset-env": "^6.7.0",
@@ -92,13 +98,13 @@
"retext": "^7.0.1",
"retext-smartypants": "^4.0.0",
"rss": "^1.2.2",
- "tailwindcss": "^3.0.22",
- "typescript": "^4.0.2",
+ "tailwindcss": "^3.4.1",
+ "typescript": "^5.7.2",
"unist-util-visit": "^2.0.3",
"webpack-bundle-analyzer": "^4.5.0"
},
"engines": {
- "node": ">=12.x"
+ "node": ">=16.8.0"
},
"nextBundleAnalysis": {
"budget": null,
@@ -108,5 +114,6 @@
"lint-staged": {
"*.{js,ts,jsx,tsx,css}": "yarn prettier",
"src/**/*.md": "yarn fix-headings"
- }
+ },
+ "packageManager": "yarn@1.22.22"
}
diff --git a/patches/@codemirror+lang-javascript+0.19.6.patch b/patches/@codemirror+lang-javascript+0.19.6.patch
deleted file mode 100644
index 3436b8e37..000000000
--- a/patches/@codemirror+lang-javascript+0.19.6.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-diff --git a/node_modules/@codemirror/lang-javascript/dist/index.cjs b/node_modules/@codemirror/lang-javascript/dist/index.cjs
-index 4475e4f..e1255c9 100644
---- a/node_modules/@codemirror/lang-javascript/dist/index.cjs
-+++ b/node_modules/@codemirror/lang-javascript/dist/index.cjs
-@@ -135,7 +135,9 @@ const javascriptLanguage = language.LRLanguage.define({
- JSXText: highlight.tags.content,
- "JSXStartTag JSXStartCloseTag JSXSelfCloseEndTag JSXEndTag": highlight.tags.angleBracket,
- "JSXIdentifier JSXNameSpacedName": highlight.tags.tagName,
-- "JSXAttribute/JSXIdentifier JSXAttribute/JSXNameSpacedName": highlight.tags.attributeName
-+ "JSXAttribute/JSXIdentifier JSXAttribute/JSXNameSpacedName": highlight.tags.attributeName,
-+ "JSXAttribute/JSXLowerIdentifier JSXAttribute/JSXNameSpacedName": highlight.tags.attributeName,
-+ "JSXBuiltin/JSXIdentifier": highlight.tags.standard(highlight.tags.tagName)
- })
- ]
- }),
-diff --git a/node_modules/@codemirror/lang-javascript/dist/index.js b/node_modules/@codemirror/lang-javascript/dist/index.js
-index d089f6b..db09ea6 100644
---- a/node_modules/@codemirror/lang-javascript/dist/index.js
-+++ b/node_modules/@codemirror/lang-javascript/dist/index.js
-@@ -131,7 +131,9 @@ const javascriptLanguage = /*@__PURE__*/LRLanguage.define({
- JSXText: tags.content,
- "JSXStartTag JSXStartCloseTag JSXSelfCloseEndTag JSXEndTag": tags.angleBracket,
- "JSXIdentifier JSXNameSpacedName": tags.tagName,
-- "JSXAttribute/JSXIdentifier JSXAttribute/JSXNameSpacedName": tags.attributeName
-+ "JSXAttribute/JSXIdentifier JSXAttribute/JSXNameSpacedName": tags.attributeName,
-+ "JSXAttribute/JSXLowerIdentifier JSXAttribute/JSXNameSpacedName": tags.attributeName,
-+ "JSXBuiltin/JSXIdentifier": tags.standard(tags.tagName),
- })
- ]
- }),
diff --git a/patches/@codesandbox+sandpack-react+1.15.5.patch b/patches/@codesandbox+sandpack-react+1.15.5.patch
deleted file mode 100644
index b68a5303d..000000000
--- a/patches/@codesandbox+sandpack-react+1.15.5.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-diff --git a/node_modules/@codesandbox/sandpack-react/dist/cjs/index.js b/node_modules/@codesandbox/sandpack-react/dist/cjs/index.js
-index 6b8518e..ada84f5 100644
---- a/node_modules/@codesandbox/sandpack-react/dist/cjs/index.js
-+++ b/node_modules/@codesandbox/sandpack-react/dist/cjs/index.js
-@@ -92,7 +92,7 @@ h1 {
-
-
-
--