diff --git a/.github/skills/write-changelog/SKILL.md b/.github/skills/write-changelog/SKILL.md new file mode 100644 index 0000000000..86b597da2d --- /dev/null +++ b/.github/skills/write-changelog/SKILL.md @@ -0,0 +1,74 @@ +--- +name: write-changelog +description: 'Write a CHANGELOG.md entry for a new extension release. Use when: writing changelog, updating changelog, adding release notes, preparing a release, documenting milestone changes. Requires a milestone name and extension version number.' +argument-hint: 'Provide the extension version (e.g. 0.134.0) and the GitHub milestone name (e.g. 1.112.0)' +--- + +# Write Changelog Entry + +Generate a new entry in `CHANGELOG.md` for an extension release by gathering closed issues and merged PRs from a GitHub milestone. + +## Inputs + +The user must provide: +1. **Extension version number** - the version for the changelog heading (e.g. `0.134.0`) +2. **GitHub milestone name** - the milestone to query (e.g. `1.112.0`) + +## Procedure + +### 1. Gather Milestone Items + +Search for all closed items in the milestone scoped to `microsoft/vscode-pull-request-github`: + +- **Issues (bugs/features):** Search for closed issues with `milestone:"" repo:microsoft/vscode-pull-request-github is:closed` +- **Merged PRs:** Search for merged PRs with `milestone:"" repo:microsoft/vscode-pull-request-github is:pr is:merged` + +### 2. Classify Items + +Sort every item into one of these buckets: + +| Bucket | Criteria | +|--------|----------| +| **Changes** | Feature requests, enhancements, new settings, new commands, infrastructure improvements (e.g. dependency upgrades, build system changes) | +| **Fixes** | Items labeled `bug`, or PRs that fix a specific issue | +| **Thank You** | Merged PRs authored by external contributors (user type is not `Bot`, and user is not a GitHub staff / `site_admin`) | +| **Skip** | Version-bump PRs (title is just a version like "0.132.0"), test plan items, items from other repos | + +### 3. Write the Entry + +Insert the new section **at the top** of `CHANGELOG.md`, directly after the `# Changelog` heading and before the previous release section. + +Follow this format exactly: + +```markdown +## + +### Changes + +- Description of change one. +- Description of change two with setting `"settingName"`. + +### Fixes + +- Short description of bug. https://github.com/microsoft/vscode-pull-request-github/issues/ +- Another bug fix. https://github.com/microsoft/vscode-pull-request-github/issues/ + +**_Thank You_** + +* [@username (Display Name)](https://github.com/username): Short description of contribution [PR #1234](https://github.com/microsoft/vscode-pull-request-github/pull/1234) +``` + +### Format Rules + +- **Changes:** Write a concise, user-facing description. Do NOT link to issues. Use backticks for setting names and commands. Each entry is a single `- ` bullet. +- **Fixes:** Use the issue title (cleaned up for readability) followed by a space and the full issue URL. Each entry is a single `- ` bullet. If a fix came from a PR without a linked issue, describe it without a URL. +- **Thank You:** Use `* ` bullets (not `- `). Format: `[@login (Name)](profile-url): Description [PR #number](pr-url)`. Only include for external community contributors. +- **Sections:** Omit any section (`### Changes`, `### Fixes`, `**_Thank You_**`) if there are no items for it. +- **No blank lines** between bullets within a section. +- **One blank line** between sections. + +### 4. Validate + +- Confirm the new section is positioned correctly (after `# Changelog`, before the previous version). +- Verify all issue/PR links are correct and point to `microsoft/vscode-pull-request-github`. +- Ensure no duplicate entries. diff --git a/.github/workflows/copilot-setup-steps.yml b/.github/workflows/copilot-setup-steps.yml index c9f9ff8872..74dc8fb9a7 100644 --- a/.github/workflows/copilot-setup-steps.yml +++ b/.github/workflows/copilot-setup-steps.yml @@ -29,10 +29,10 @@ jobs: uses: actions/setup-node@v4 with: node-version: "20" - cache: "yarn" + cache: "npm" - name: Install dependencies - run: yarn install --frozen-lockfile + run: npm ci env: # Skip Playwright browser downloads to avoid installation failures PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1 @@ -48,7 +48,7 @@ jobs: continue-on-error: true - name: Update VS Code type definitions - run: yarn update-dts + run: npm run update-dts - name: Basic build verification run: | diff --git a/.gitignore b/.gitignore index 4d5727ad18..3520467a42 100644 --- a/.gitignore +++ b/.gitignore @@ -339,7 +339,6 @@ media .vscode-test-web .DS_Store *.vsix -package-lock.json src/@types/vscode.d.ts src/@types/vscode.proposed.d.ts diff --git a/.vscodeignore b/.vscodeignore index d37228c7e4..e64d84d935 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -22,15 +22,15 @@ webviews/** .gitignore-revs .prettierignore .prettierrc -.yarnrc +package-lock.json azure-pipeline.* **/tsconfig*.json *.tsbuildinfo **/webpack.config*.js -yarn.lock +npm-debug.log **/*.map **/*.svg -!**/git-pull-request_webview.svg +!**/*_webview.svg **/*.ts *.vsix **/*.bak diff --git a/.yarnrc b/.yarnrc deleted file mode 100644 index 123ac74a0a..0000000000 --- a/.yarnrc +++ /dev/null @@ -1 +0,0 @@ -ignore-engines true diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ffccb7787..cc4759927b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,90 @@ # Changelog +## 0.140.0 + +### Changes + +- New "Checkout Pull Request in Worktree" option added to the Pull Requests view context menu and the PR description view. + +### Fixes + +- `hasBranch` called with repository name (`pr.base.name`) instead of branch name (`pr.base.ref`) in `reviewManager.ts`. https://github.com/microsoft/vscode-pull-request-github/issues/8668 + +**_Thank You_** + +* [@Will-hxw](https://github.com/Will-hxw): Use `pr.base.ref` instead of `pr.base.name` in `hasBranch` call [PR #8698](https://github.com/microsoft/vscode-pull-request-github/pull/8698) + +## 0.138.0 + +### Fixes + +- Extension does not show all PR checks. https://github.com/microsoft/vscode-pull-request-github/issues/8640 +- File-scoped comment fails with "Error: File has been deleted". https://github.com/microsoft/vscode-pull-request-github/issues/8641 +- PR made without the UI is not linked to the existing branch. https://github.com/microsoft/vscode-pull-request-github/issues/8643 + +## 0.136.0 + +### Changes + +- Add tool to create pull requests. +- Add tool to resolve review comments. +- Offer to delete worktrees from the clean up command. +- Include line numbers in "Apply suggestion using AI" context for code review comments. + +### Fixes + +- Resolving comments doesn't update state on server. https://github.com/microsoft/vscode-pull-request-github/issues/8649 +- PR description filled differently than on github.com. https://github.com/microsoft/vscode-pull-request-github/issues/8630 +- Can't checkout PR locally when already on the same branch. https://github.com/microsoft/vscode-pull-request-github/issues/8624 +- Parent folder checkbox not auto-checked when all children are marked as viewed. https://github.com/microsoft/vscode-pull-request-github/issues/8584 +- Escape file names in processed links. + +## 0.134.0 + +### Changes + +- Branch names in the create PR view are now cached for faster target branch loading. +- GitHub permalink links in PR and issue overview webviews now open the corresponding local file when the file exists in the workspace. + +### Fixes + +- Selecting a target branch when creating a PR is sometimes broken. https://github.com/microsoft/vscode-pull-request-github/issues/8627 +- "Apply suggestion using AI" for code comment reviews results in a redundant disclaimer suffix. https://github.com/microsoft/vscode-pull-request-github/issues/8605 + +**_Thank You_** + +* [@Daniel-Aaron-Bloom](https://github.com/Daniel-Aaron-Bloom): Link to local file for permalinks in webview [PR #8583](https://github.com/microsoft/vscode-pull-request-github/pull/8583) + +## 0.132.2 + +### Fixes + +- Button missing rounded corners on one side. https://github.com/microsoft/vscode-pull-request-github/issues/8609 + +## 0.132.1 + +### Fixes + +- Can't add multiline GitHub PR Comment because Inline Chat button covers Comment button. https://github.com/microsoft/vscode-pull-request-github/issues/8504 +- Deleting a worktree after merging a PR mixes the main branch with the worktree. https://github.com/microsoft/vscode-pull-request-github/issues/8519 +- Missing issue webview icon. + +## 0.132.0 + +### Changes + +- When `"githubPullRequests.pullRequestDescription"` is set to `"branchName"`, the branch name is now "title-ized" (dashes and underscores replaced with spaces, words capitalized) to match the behavior on github.com. +- Pull requests in the sidebar views can now show icons representing their status (open, closed, merged, draft) with the setting `"githubPullRequests.pullRequestAvatarDisplay"`. + +### Fixes + +- Update with merge commit feature not working. https://github.com/microsoft/vscode-pull-request-github/issues/8553 +- Avatar doesn't show in comment widget with GitHub Enterprise. https://github.com/microsoft/vscode-pull-request-github/issues/8550 +- Can't easily open PR to the right. https://github.com/microsoft/vscode-pull-request-github/issues/8537 +- Stale worktree repo entry persists in PR sidebar after worktree removal. https://github.com/microsoft/vscode-pull-request-github/issues/8525 +- Wrong list of files when creating PR. https://github.com/microsoft/vscode-pull-request-github/issues/8457 +- Element with id All Open (URL) is already registered. https://github.com/microsoft/vscode-pull-request-github/issues/8073 + ## 0.130.0 ### Changes diff --git a/azure-pipeline.nightly.yml b/azure-pipeline.nightly.yml index 28d5448034..68099f3613 100644 --- a/azure-pipeline.nightly.yml +++ b/azure-pipeline.nightly.yml @@ -34,11 +34,11 @@ extends: nodeVersion: "20.x" buildSteps: - - script: yarn install --frozen-lockfile --check-files + - script: npm ci displayName: Install dependencies retryCountOnTaskFailure: 3 - - script: yarn run bundle + - script: npm run bundle displayName: Compile - script: > @@ -51,11 +51,11 @@ extends: displayName: Override package.json testSteps: - - script: yarn install --frozen-lockfile --check-files + - script: npm ci displayName: Install dependencies retryCountOnTaskFailure: 3 - - script: yarn run bundle + - script: npm run bundle displayName: Compile - bash: | @@ -63,23 +63,23 @@ extends: echo ">>> Started xvfb" displayName: Start xvfb - - script: yarn run test + - script: npm run test displayName: Run test suite env: DISPLAY: ':99.0' TEST_JUNIT_XML_PATH: $(Agent.HomeDirectory)/test-results.xml - # - script: yarn run browsertest --browserType=chromium + # - script: npm run browsertest --browserType=chromium # displayName: Run test suite (chromium) # env: # TEST_JUNIT_XML_PATH: $(Agent.HomeDirectory)/browser-chromium-test-results.xml - # - script: yarn run browsertest --browserType=firefox + # - script: npm run browsertest --browserType=firefox # displayName: Run test suite (firefox) # env: # TEST_JUNIT_XML_PATH: $(Agent.HomeDirectory)/browser-firefox-test-results.xml - # - script: yarn run browsertest --browserType=webkit + # - script: npm run browsertest --browserType=webkit # displayName: Run test suite (webkit) # env: # TEST_JUNIT_XML_PATH: $(Agent.HomeDirectory)/browser-webkit-test-results.xml diff --git a/azure-pipeline.pr.yml b/azure-pipeline.pr.yml index 6a4422580d..df40e8d2b9 100644 --- a/azure-pipeline.pr.yml +++ b/azure-pipeline.pr.yml @@ -6,7 +6,7 @@ jobs: steps: - template: scripts/ci/common-setup.yml - - script: yarn run compile + - script: npm run compile displayName: Compile - script: npm run hygiene @@ -15,25 +15,25 @@ jobs: - script: npm run lint displayName: Run lint - - script: yarn run check:commands + - script: npm run check:commands displayName: Verify command registrations - - script: yarn run test + - script: npm run test displayName: Run test suite env: TEST_JUNIT_XML_PATH: $(Agent.HomeDirectory)/test-results.xml - # - script: yarn run browsertest --browserType=chromium + # - script: npm run browsertest --browserType=chromium # displayName: Run test suite (chromium) # env: # TEST_JUNIT_XML_PATH: $(Agent.HomeDirectory)/browser-chromium-test-results.xml - # - script: yarn run browsertest --browserType=firefox + # - script: npm run browsertest --browserType=firefox # displayName: Run test suite (firefox) # env: # TEST_JUNIT_XML_PATH: $(Agent.HomeDirectory)/browser-firefox-test-results.xml - # - script: yarn run browsertest --browserType=webkit + # - script: npm run browsertest --browserType=webkit # displayName: Run test suite (webkit) # env: # TEST_JUNIT_XML_PATH: $(Agent.HomeDirectory)/browser-webkit-test-results.xml diff --git a/azure-pipeline.release.yml b/azure-pipeline.release.yml index 1f8bb2c0d6..94c8158f19 100644 --- a/azure-pipeline.release.yml +++ b/azure-pipeline.release.yml @@ -31,19 +31,19 @@ extends: nodeVersion: "20.x" buildSteps: - - script: yarn install --frozen-lockfile --check-files + - script: npm ci displayName: Install dependencies retryCountOnTaskFailure: 3 - - script: yarn run bundle + - script: npm run bundle displayName: Compile testSteps: - - script: yarn install --frozen-lockfile --check-files + - script: npm ci displayName: Install dependencies retryCountOnTaskFailure: 3 - - script: yarn run bundle + - script: npm run bundle displayName: Compile - bash: | @@ -51,23 +51,23 @@ extends: echo ">>> Started xvfb" displayName: Start xvfb - - script: yarn run test + - script: npm run test displayName: Run test suite env: DISPLAY: ':99.0' TEST_JUNIT_XML_PATH: $(Agent.HomeDirectory)/test-results.xml - # - script: yarn run browsertest --browserType=chromium + # - script: npm run browsertest --browserType=chromium # displayName: Run test suite (chromium) # env: # TEST_JUNIT_XML_PATH: $(Agent.HomeDirectory)/browser-chromium-test-results.xml - # - script: yarn run browsertest --browserType=firefox + # - script: npm run browsertest --browserType=firefox # displayName: Run test suite (firefox) # env: # TEST_JUNIT_XML_PATH: $(Agent.HomeDirectory)/browser-firefox-test-results.xml - # - script: yarn run browsertest --browserType=webkit + # - script: npm run browsertest --browserType=webkit # displayName: Run test suite (webkit) # env: # TEST_JUNIT_XML_PATH: $(Agent.HomeDirectory)/browser-webkit-test-results.xml diff --git a/build/filters.js b/build/filters.js index 1425e36c2f..b64bd3adf2 100644 --- a/build/filters.js +++ b/build/filters.js @@ -47,6 +47,7 @@ module.exports.indentationFilter = [ // except multiple specific files '!**/package.json', + '!**/package-lock.json', '!**/yarn.lock', '!**/yarn-error.log', '!**/fixtures/**/*' @@ -70,6 +71,7 @@ module.exports.copyrightFilter = [ '!**/*.yml', '!**/*.md', '!package.nls.json', + '!**/package-lock.json', '!**/*.svg', '!src/integrations/gitlens/gitlens.d.ts', '!**/fixtures/**' diff --git a/common/views.ts b/common/views.ts index 5682e9b011..9e2f35fdf2 100644 --- a/common/views.ts +++ b/common/views.ts @@ -180,4 +180,11 @@ export interface OpenCommitChangesArgs { commitSha: string; } +export interface OpenLocalFileArgs { + file: string; + startLine: number; + endLine: number; + href: string; +} + // #endregion \ No newline at end of file diff --git a/documentation/releasing.md b/documentation/releasing.md index e76d24aace..9be934ecb4 100644 --- a/documentation/releasing.md +++ b/documentation/releasing.md @@ -3,6 +3,7 @@ 1. Edit version in [package.json](https://github.com/Microsoft/vscode-pull-request-github/blob/main/package.json) - Update version of the extension - this is usually the minor version. **Until the marketplace supports semantic versioning, the minor version should always be an event number. Odd numbers are reserved for the pre-release version of the extension.** + - Run `npm install` to update `package-lock.json` - (If necessary) Update vscode engine version 2. Update [CHANGELOG.md](https://github.com/Microsoft/vscode-pull-request-github/blob/main/CHANGELOG.md) diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000..0ca9cc2e9b --- /dev/null +++ b/package-lock.json @@ -0,0 +1,12705 @@ +{ + "name": "vscode-pull-request-github", + "version": "0.140.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "vscode-pull-request-github", + "version": "0.140.0", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "@joaomoreno/unique-names-generator": "^5.2.0", + "@octokit/rest": "22.0.0", + "@octokit/types": "14.1.0", + "@vscode/codicons": "^0.0.36", + "@vscode/extension-telemetry": "0.7.5", + "@vscode/prompt-tsx": "^0.3.0-alpha.12", + "apollo-boost": "^0.4.9", + "apollo-link-context": "1.0.20", + "cockatiel": "^3.1.1", + "cross-fetch": "3.1.5", + "dayjs": "1.10.4", + "debounce": "^1.2.1", + "events": "3.2.0", + "fast-deep-equal": "^3.1.3", + "js-yaml": "^4.1.1", + "jsonc-parser": "^3.3.1", + "lru-cache": "6.0.0", + "markdown-it": "^14.1.1", + "marked": "^4.0.10", + "react": "^16.12.0", + "react-dom": "^16.12.0", + "ssh-config": "4.1.1", + "stream-http": "^3.2.0", + "temporal-polyfill": "^0.3.0", + "tunnel": "0.0.6", + "url-search-params-polyfill": "^8.1.1", + "uuid": "14.0.0", + "vscode-tas-client": "^0.1.84", + "vsls": "^0.3.967" + }, + "devDependencies": { + "@eslint/js": "^9.36.0", + "@shikijs/monaco": "^3.7.0", + "@types/chai": "^4.1.4", + "@types/glob": "7.1.3", + "@types/js-yaml": "^4.0.9", + "@types/lru-cache": "^5.1.0", + "@types/marked": "^0.7.2", + "@types/mocha": "^10.0.10", + "@types/node": "22", + "@types/react": "^16.8.4", + "@types/react-dom": "^16.8.2", + "@types/sinon": "7.0.11", + "@types/temp": "0.8.34", + "@types/vscode": "1.103.0", + "@types/webpack-env": "^1.16.0", + "@typescript-eslint/eslint-plugin": "^8.44.0", + "@typescript-eslint/parser": "^8.44.0", + "@vscode/dts": "^0.4.1", + "@vscode/test-cli": "^0.0.11", + "@vscode/test-electron": "^2.5.2", + "@vscode/test-web": "^0.0.71", + "assert": "^2.0.0", + "buffer": "^6.0.3", + "constants-browserify": "^1.0.0", + "crypto-browserify": "3.12.0", + "css-loader": "7.1.2", + "esbuild-loader": "4.4.2", + "eslint": "^9.36.0", + "eslint-import-resolver-typescript": "^4.4.4", + "eslint-plugin-import": "2.31.0", + "eslint-plugin-rulesdir": "^0.2.2", + "event-stream": "^4.0.1", + "fork-ts-checker-webpack-plugin": "9.1.0", + "glob": "7.1.6", + "globals": "^16.4.0", + "graphql": "15.5.0", + "graphql-tag": "2.11.0", + "gulp-filter": "^7.0.0", + "husky": "^8.0.1", + "jsdom": "28.1.0", + "jsdom-global": "3.0.2", + "json5": "2.2.2", + "merge-options": "3.0.4", + "minimist": "^1.2.6", + "mkdirp": "1.0.4", + "mocha": "^11.7.5", + "mocha-junit-reporter": "1.23.0", + "mocha-multi-reporters": "1.1.7", + "os-browserify": "^0.3.0", + "p-all": "^1.0.0", + "path-browserify": "1.0.1", + "process": "^0.11.10", + "react-testing-library": "7.0.1", + "sinon": "9.0.0", + "source-map-support": "0.5.19", + "stream-browserify": "^3.0.0", + "style-loader": "4.0.0", + "svg-inline-loader": "^0.8.2", + "temp": "0.9.4", + "terser-webpack-plugin": "5.3.17", + "timers-browserify": "^2.0.12", + "ts-loader": "9.5.2", + "ts-node": "^10.9.2", + "tty": "1.0.1", + "typescript": "^5.9.2", + "typescript-eslint": "^8.44.0", + "typescript-formatter": "^7.2.2", + "vinyl-fs": "^3.0.3", + "webpack": "5.104.1", + "webpack-cli": "4.2.0" + }, + "engines": { + "node": ">=20", + "vscode": "^1.110.0" + } + }, + "node_modules/@acemir/cssom": { + "version": "0.9.31", + "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz", + "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@asamuzakjp/css-color": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-5.0.1.tgz", + "integrity": "sha512-2SZFvqMyvboVV1d15lMf7XiI3m7SDqXUuKaTymJYLN6dSGadqp+fVojqJlVoMlbZnlTmu3S0TLwLTJpvBMO1Aw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^3.1.1", + "@csstools/css-color-parser": "^4.0.2", + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0", + "lru-cache": "^11.2.6" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.8.1.tgz", + "integrity": "sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.6" + } + }, + "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@azure/abort-controller": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", + "integrity": "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@azure/abort-controller/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@azure/core-auth": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@azure/core-auth/-/core-auth-1.10.1.tgz", + "integrity": "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-util": "^1.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-auth/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@azure/core-rest-pipeline": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.23.0.tgz", + "integrity": "sha512-Evs1INHo+jUjwHi1T6SG6Ua/LHOQBCLuKEEE6efIpt4ZOoNonaT1kP32GoOcdNDbfqsD2445CPri3MubBy5DEQ==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "@typespec/ts-http-runtime": "^0.3.4", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-rest-pipeline/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@azure/core-tracing": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@azure/core-tracing/-/core-tracing-1.3.1.tgz", + "integrity": "sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-tracing/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@azure/core-util": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/@azure/core-util/-/core-util-1.13.1.tgz", + "integrity": "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A==", + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/core-util/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@azure/logger": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@azure/logger/-/logger-1.3.0.tgz", + "integrity": "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==", + "license": "MIT", + "dependencies": { + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@azure/logger/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz", + "integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@bramus/specificity": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@bramus/specificity/-/specificity-2.4.2.tgz", + "integrity": "sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "css-tree": "^3.0.0" + }, + "bin": { + "specificity": "bin/cli.js" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.8.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "0.3.9" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.0.3", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "node_modules/@csstools/color-helpers": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-6.0.2.tgz", + "integrity": "sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@csstools/css-calc": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-3.1.1.tgz", + "integrity": "sha512-HJ26Z/vmsZQqs/o3a6bgKslXGFAungXGbinULZO3eMsOyNJHeBBZfup5FiZInOghgoM4Hwnmw+OgbJCNg1wwUQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-color-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-4.0.2.tgz", + "integrity": "sha512-0GEfbBLmTFf0dJlpsNU7zwxRIH0/BGEMuXLTCvFYxuL1tNhqzTbtnFICyJLTNK4a+RechKP75e7w42ClXSnJQw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^6.0.2", + "@csstools/css-calc": "^3.1.1" + }, + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^4.0.0", + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-parser-algorithms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-4.0.0.tgz", + "integrity": "sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^4.0.0" + } + }, + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.1.0.tgz", + "integrity": "sha512-H4tuz2nhWgNKLt1inYpoVCfbJbMwX/lQKp3g69rrrIMIYlFD9+zTykOKhNR8uGrAmbS/kT9n6hTFkmDkxLgeTA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0" + }, + "node_modules/@csstools/css-tokenizer": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-4.0.0.tgz", + "integrity": "sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=20.19.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/core/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.6", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/debug": { + "version": "4.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.3.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.15.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/eslintrc": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@eslint/eslintrc/node_modules/debug": { + "version": "4.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@eslint/js": { + "version": "9.36.0", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "node_modules/@eslint/object-schema": { + "version": "2.1.6", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/plugin-kit": { + "version": "0.3.5", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.15.2", + "levn": "^0.4.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@exodus/bytes": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.15.0.tgz", + "integrity": "sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true + } + } + }, + "node_modules/@humanfs/core": { + "version": "0.19.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanfs/node": { + "version": "0.16.7", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, + "engines": { + "node": ">=18.18.0" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "dev": true, + "license": "ISC", + "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" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "24.9.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^1.1.1", + "@types/yargs": "^13.0.0" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/@joaomoreno/unique-names-generator": { + "version": "5.2.0", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", + "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.25", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@koa/cors": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/@koa/router": { + "version": "13.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.1", + "http-errors": "^2.0.0", + "koa-compose": "^4.1.0", + "path-to-regexp": "^6.3.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/@koa/router/node_modules/http-errors": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@koa/router/node_modules/path-to-regexp": { + "version": "6.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@koa/router/node_modules/statuses": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/@microsoft/1ds-core-js": { + "version": "3.2.9", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-core-js": "2.8.10", + "@microsoft/applicationinsights-shims": "^2.0.2", + "@microsoft/dynamicproto-js": "^1.1.7" + } + }, + "node_modules/@microsoft/1ds-post-js": { + "version": "3.2.9", + "license": "MIT", + "dependencies": { + "@microsoft/1ds-core-js": "3.2.9", + "@microsoft/applicationinsights-shims": "^2.0.2", + "@microsoft/dynamicproto-js": "^1.1.7" + } + }, + "node_modules/@microsoft/applicationinsights-channel-js": { + "version": "2.8.10", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-common": "2.8.10", + "@microsoft/applicationinsights-core-js": "2.8.10", + "@microsoft/applicationinsights-shims": "2.0.2", + "@microsoft/dynamicproto-js": "^1.1.7" + }, + "peerDependencies": { + "tslib": "*" + } + }, + "node_modules/@microsoft/applicationinsights-common": { + "version": "2.8.10", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-core-js": "2.8.10", + "@microsoft/applicationinsights-shims": "2.0.2", + "@microsoft/dynamicproto-js": "^1.1.7" + }, + "peerDependencies": { + "tslib": "*" + } + }, + "node_modules/@microsoft/applicationinsights-core-js": { + "version": "2.8.10", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-shims": "2.0.2", + "@microsoft/dynamicproto-js": "^1.1.7" + }, + "peerDependencies": { + "tslib": "*" + } + }, + "node_modules/@microsoft/applicationinsights-shims": { + "version": "2.0.2", + "license": "MIT" + }, + "node_modules/@microsoft/applicationinsights-web-basic": { + "version": "2.8.10", + "license": "MIT", + "dependencies": { + "@microsoft/applicationinsights-channel-js": "2.8.10", + "@microsoft/applicationinsights-common": "2.8.10", + "@microsoft/applicationinsights-core-js": "2.8.10", + "@microsoft/applicationinsights-shims": "2.0.2", + "@microsoft/dynamicproto-js": "^1.1.7" + }, + "peerDependencies": { + "tslib": "*" + } + }, + "node_modules/@microsoft/applicationinsights-web-snippet": { + "version": "1.0.1", + "license": "MIT" + }, + "node_modules/@microsoft/dynamicproto-js": { + "version": "1.1.7", + "license": "MIT" + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.4", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.4", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@octokit/auth-token": { + "version": "6.0.0", + "license": "MIT", + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/core": { + "version": "7.0.3", + "license": "MIT", + "dependencies": { + "@octokit/auth-token": "^6.0.0", + "@octokit/graphql": "^9.0.1", + "@octokit/request": "^10.0.2", + "@octokit/request-error": "^7.0.0", + "@octokit/types": "^14.0.0", + "before-after-hook": "^4.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/endpoint": { + "version": "11.0.0", + "license": "MIT", + "dependencies": { + "@octokit/types": "^14.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/graphql": { + "version": "9.0.1", + "license": "MIT", + "dependencies": { + "@octokit/request": "^10.0.2", + "@octokit/types": "^14.0.0", + "universal-user-agent": "^7.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/openapi-types": { + "version": "25.1.0", + "license": "MIT" + }, + "node_modules/@octokit/plugin-paginate-rest": { + "version": "13.1.1", + "license": "MIT", + "dependencies": { + "@octokit/types": "^14.1.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-request-log": { + "version": "6.0.0", + "license": "MIT", + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/plugin-rest-endpoint-methods": { + "version": "16.0.0", + "license": "MIT", + "dependencies": { + "@octokit/types": "^14.1.0" + }, + "engines": { + "node": ">= 20" + }, + "peerDependencies": { + "@octokit/core": ">=6" + } + }, + "node_modules/@octokit/request": { + "version": "10.0.3", + "license": "MIT", + "dependencies": { + "@octokit/endpoint": "^11.0.0", + "@octokit/request-error": "^7.0.0", + "@octokit/types": "^14.0.0", + "fast-content-type-parse": "^3.0.0", + "universal-user-agent": "^7.0.2" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/request-error": { + "version": "7.0.0", + "license": "MIT", + "dependencies": { + "@octokit/types": "^14.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/rest": { + "version": "22.0.0", + "license": "MIT", + "dependencies": { + "@octokit/core": "^7.0.2", + "@octokit/plugin-paginate-rest": "^13.0.1", + "@octokit/plugin-request-log": "^6.0.0", + "@octokit/plugin-rest-endpoint-methods": "^16.0.0" + }, + "engines": { + "node": ">= 20" + } + }, + "node_modules/@octokit/types": { + "version": "14.1.0", + "license": "MIT", + "dependencies": { + "@octokit/openapi-types": "^25.1.0" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.4.0", + "license": "Apache-2.0", + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "1.9.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "1.9.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "1.9.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.9.1", + "@opentelemetry/semantic-conventions": "1.9.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "1.9.1", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "1.9.1", + "@opentelemetry/resources": "1.9.1", + "@opentelemetry/semantic-conventions": "1.9.1" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.5.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.9.1", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@playwright/browser-chromium": { + "version": "1.54.1", + "dev": true, + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.54.1" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@sheerun/mutationobserver-shim": { + "version": "0.3.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@shikijs/core": { + "version": "3.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/types": "3.7.0", + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4", + "hast-util-to-html": "^9.0.5" + } + }, + "node_modules/@shikijs/monaco": { + "version": "3.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/core": "3.7.0", + "@shikijs/types": "3.7.0", + "@shikijs/vscode-textmate": "^10.0.2" + } + }, + "node_modules/@shikijs/types": { + "version": "3.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@shikijs/vscode-textmate": "^10.0.2", + "@types/hast": "^3.0.4" + } + }, + "node_modules/@shikijs/vscode-textmate": { + "version": "10.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.2", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "6.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@sinonjs/formatio": { + "version": "5.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^5.0.2" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "5.3.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.1", + "dev": true, + "license": "(Unlicense OR Apache-2.0)" + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@tybys/wasm-util/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, + "node_modules/@types/chai": { + "version": "4.2.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/glob": { + "version": "7.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/istanbul-lib-coverage": "*", + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/lru-cache": { + "version": "5.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/marked": { + "version": "0.7.4", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mocha": { + "version": "10.0.10", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.10.tgz", + "integrity": "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "22.18.6", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/prop-types": { + "version": "15.7.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/react": { + "version": "16.14.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "16.9.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/react": "^16" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/sinon": { + "version": "7.0.11", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/temp": { + "version": "0.8.34", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/unist": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/vscode": { + "version": "1.103.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/webpack-env": { + "version": "1.16.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yargs": { + "version": "13.0.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "20.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/zen-observable": { + "version": "0.8.2", + "license": "MIT" + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "8.44.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/regexpp": "^4.10.0", + "@typescript-eslint/scope-manager": "8.44.1", + "@typescript-eslint/type-utils": "8.44.1", + "@typescript-eslint/utils": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", + "graphemer": "^1.4.0", + "ignore": "^7.0.0", + "natural-compare": "^1.4.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^8.44.1", + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { + "version": "7.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "8.44.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/scope-manager": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/project-service": { + "version": "8.44.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/tsconfig-utils": "^8.44.1", + "@typescript-eslint/types": "^8.44.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "8.44.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/tsconfig-utils": { + "version": "8.44.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "8.44.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1", + "@typescript-eslint/utils": "8.44.1", + "debug": "^4.3.4", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/types": { + "version": "8.44.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "8.44.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/project-service": "8.44.1", + "@typescript-eslint/tsconfig-utils": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/visitor-keys": "8.44.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.1.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "8.44.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.7.0", + "@typescript-eslint/scope-manager": "8.44.1", + "@typescript-eslint/types": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "8.44.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/types": "8.44.1", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typespec/ts-http-runtime": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.4.tgz", + "integrity": "sha512-CI0NhTrz4EBaa0U+HaaUZrJhPoso8sG7ZFya8uQoBA57fjzrjRSv87ekCjLZOFExN+gXE/z0xuN2QfH4H2HrLQ==", + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@typespec/ts-http-runtime/node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "dev": true, + "license": "ISC" + }, + "node_modules/@unrs/resolver-binding-android-arm-eabi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz", + "integrity": "sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-android-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz", + "integrity": "sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-arm64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz", + "integrity": "sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-darwin-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz", + "integrity": "sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@unrs/resolver-binding-freebsd-x64": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz", + "integrity": "sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz", + "integrity": "sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz", + "integrity": "sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz", + "integrity": "sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-arm64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz", + "integrity": "sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz", + "integrity": "sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz", + "integrity": "sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz", + "integrity": "sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz", + "integrity": "sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-gnu": { + "version": "1.11.1", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-x64-musl": { + "version": "1.11.1", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-wasm32-wasi": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz", + "integrity": "sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz", + "integrity": "sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz", + "integrity": "sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@unrs/resolver-binding-win32-x64-msvc": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz", + "integrity": "sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@vscode/codicons": { + "version": "0.0.36", + "license": "CC-BY-4.0" + }, + "node_modules/@vscode/dts": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "https-proxy-agent": "^7.0.0", + "minimist": "^1.2.8", + "prompts": "^2.4.2" + }, + "bin": { + "dts": "index.js" + } + }, + "node_modules/@vscode/dts/node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@vscode/extension-telemetry": { + "version": "0.7.5", + "license": "MIT", + "dependencies": { + "@microsoft/1ds-core-js": "^3.2.8", + "@microsoft/1ds-post-js": "^3.2.8", + "@microsoft/applicationinsights-web-basic": "^2.8.9", + "applicationinsights": "2.4.1" + }, + "engines": { + "vscode": "^1.75.0" + } + }, + "node_modules/@vscode/prompt-tsx": { + "version": "0.3.0-alpha.12", + "license": "MIT" + }, + "node_modules/@vscode/test-cli": { + "version": "0.0.11", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mocha": "^10.0.2", + "c8": "^9.1.0", + "chokidar": "^3.5.3", + "enhanced-resolve": "^5.15.0", + "glob": "^10.3.10", + "minimatch": "^9.0.3", + "mocha": "^11.1.0", + "supports-color": "^9.4.0", + "yargs": "^17.7.2" + }, + "bin": { + "vscode-test": "out/bin.mjs" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@vscode/test-cli/node_modules/brace-expansion": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@vscode/test-cli/node_modules/chokidar": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/@vscode/test-cli/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "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" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vscode/test-cli/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vscode/test-cli/node_modules/supports-color": { + "version": "9.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@vscode/test-electron": { + "version": "2.5.2", + "dev": true, + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.5", + "jszip": "^3.10.1", + "ora": "^8.1.0", + "semver": "^7.6.2" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@vscode/test-web": { + "version": "0.0.71", + "dev": true, + "license": "MIT", + "dependencies": { + "@koa/cors": "^5.0.0", + "@koa/router": "^13.1.0", + "@playwright/browser-chromium": "^1.53.1", + "gunzip-maybe": "^1.4.2", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "koa": "^3.0.0", + "koa-morgan": "^1.0.1", + "koa-mount": "^4.2.0", + "koa-static": "^5.0.0", + "minimist": "^1.2.8", + "playwright": "^1.53.1", + "tar-fs": "^3.1.0", + "tinyglobby": "0.2.14", + "vscode-uri": "^3.1.0" + }, + "bin": { + "vscode-test-web": "out/server/index.js" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@vscode/test-web/node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/info": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "envinfo": "^7.7.3" + }, + "peerDependencies": { + "webpack-cli": "4.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "peerDependencies": { + "webpack-cli": "4.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@wry/context": { + "version": "0.4.4", + "license": "MIT", + "dependencies": { + "@types/node": ">=6", + "tslib": "^1.9.3" + } + }, + "node_modules/@wry/equality": { + "version": "0.1.11", + "license": "MIT", + "dependencies": { + "tslib": "^1.9.3" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/accepts": { + "version": "1.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "8.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.11.0" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansi-wrap": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/apollo-boost": { + "version": "0.4.9", + "license": "MIT", + "dependencies": { + "apollo-cache": "^1.3.5", + "apollo-cache-inmemory": "^1.6.6", + "apollo-client": "^2.6.10", + "apollo-link": "^1.0.6", + "apollo-link-error": "^1.0.3", + "apollo-link-http": "^1.3.1", + "graphql-tag": "^2.4.2", + "ts-invariant": "^0.4.0", + "tslib": "^1.10.0" + }, + "peerDependencies": { + "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + } + }, + "node_modules/apollo-cache": { + "version": "1.3.5", + "license": "MIT", + "dependencies": { + "apollo-utilities": "^1.3.4", + "tslib": "^1.10.0" + }, + "peerDependencies": { + "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + } + }, + "node_modules/apollo-cache-inmemory": { + "version": "1.6.6", + "license": "MIT", + "dependencies": { + "apollo-cache": "^1.3.5", + "apollo-utilities": "^1.3.4", + "optimism": "^0.10.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.10.0" + }, + "peerDependencies": { + "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + } + }, + "node_modules/apollo-client": { + "version": "2.6.10", + "license": "MIT", + "dependencies": { + "@types/zen-observable": "^0.8.0", + "apollo-cache": "1.3.5", + "apollo-link": "^1.0.0", + "apollo-utilities": "1.3.4", + "symbol-observable": "^1.0.2", + "ts-invariant": "^0.4.0", + "tslib": "^1.10.0", + "zen-observable": "^0.8.0" + }, + "peerDependencies": { + "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + } + }, + "node_modules/apollo-link": { + "version": "1.2.14", + "license": "MIT", + "dependencies": { + "apollo-utilities": "^1.3.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3", + "zen-observable-ts": "^0.8.21" + }, + "peerDependencies": { + "graphql": "^0.11.3 || ^0.12.3 || ^0.13.0 || ^14.0.0 || ^15.0.0" + } + }, + "node_modules/apollo-link-context": { + "version": "1.0.20", + "license": "MIT", + "dependencies": { + "apollo-link": "^1.2.14", + "tslib": "^1.9.3" + } + }, + "node_modules/apollo-link-error": { + "version": "1.1.13", + "license": "MIT", + "dependencies": { + "apollo-link": "^1.2.14", + "apollo-link-http-common": "^0.2.16", + "tslib": "^1.9.3" + } + }, + "node_modules/apollo-link-http": { + "version": "1.5.17", + "license": "MIT", + "dependencies": { + "apollo-link": "^1.2.14", + "apollo-link-http-common": "^0.2.16", + "tslib": "^1.9.3" + }, + "peerDependencies": { + "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + } + }, + "node_modules/apollo-link-http-common": { + "version": "0.2.16", + "license": "MIT", + "dependencies": { + "apollo-link": "^1.2.14", + "ts-invariant": "^0.4.0", + "tslib": "^1.9.3" + }, + "peerDependencies": { + "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + } + }, + "node_modules/apollo-utilities": { + "version": "1.3.4", + "license": "MIT", + "dependencies": { + "@wry/equality": "^0.1.2", + "fast-json-stable-stringify": "^2.0.0", + "ts-invariant": "^0.4.0", + "tslib": "^1.10.0" + }, + "peerDependencies": { + "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + } + }, + "node_modules/append-buffer": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/applicationinsights": { + "version": "2.4.1", + "license": "MIT", + "dependencies": { + "@azure/core-auth": "^1.4.0", + "@azure/core-rest-pipeline": "^1.10.0", + "@microsoft/applicationinsights-web-snippet": "^1.0.1", + "@opentelemetry/api": "^1.0.4", + "@opentelemetry/core": "^1.0.1", + "@opentelemetry/sdk-trace-base": "^1.0.1", + "@opentelemetry/semantic-conventions": "^1.0.1", + "cls-hooked": "^4.2.2", + "continuation-local-storage": "^3.2.1", + "diagnostic-channel": "1.1.0", + "diagnostic-channel-publishers": "1.0.5" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "applicationinsights-native-metrics": "*" + }, + "peerDependenciesMeta": { + "applicationinsights-native-metrics": { + "optional": true + } + } + }, + "node_modules/arg": { + "version": "4.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "license": "Python-2.0" + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-back": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "is-array-buffer": "^3.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-differ": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array-includes": { + "version": "3.1.9", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.0", + "es-object-atoms": "^1.1.1", + "get-intrinsic": "^1.3.0", + "is-string": "^1.1.1", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.6", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-shim-unscopables": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "is-array-buffer": "^3.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/assert": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "es6-object-assign": "^1.1.0", + "is-nan": "^1.2.1", + "object-is": "^1.0.1", + "util": "^0.12.0" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/async-function": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/async-hook-jl": { + "version": "1.7.6", + "license": "MIT", + "dependencies": { + "stack-chain": "^1.3.7" + }, + "engines": { + "node": "^4.7 || >=6.9 || >=7.3" + } + }, + "node_modules/async-listener": { + "version": "0.6.10", + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^5.3.0", + "shimmer": "^1.1.0" + }, + "engines": { + "node": "<=0.11.8 || >0.11.10" + } + }, + "node_modules/async-listener/node_modules/semver": { + "version": "5.7.2", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/b4a": { + "version": "1.6.7", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/bare-events": { + "version": "2.6.0", + "dev": true, + "license": "Apache-2.0", + "optional": true + }, + "node_modules/bare-fs": { + "version": "4.1.6", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-events": "^2.5.4", + "bare-path": "^3.0.0", + "bare-stream": "^2.6.4" + }, + "engines": { + "bare": ">=1.16.0" + }, + "peerDependencies": { + "bare-buffer": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + } + } + }, + "node_modules/bare-os": { + "version": "3.6.1", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "bare": ">=1.14.0" + } + }, + "node_modules/bare-path": { + "version": "3.0.0", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-os": "^3.0.1" + } + }, + "node_modules/bare-stream": { + "version": "2.6.5", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "streamx": "^2.21.0" + }, + "peerDependencies": { + "bare-buffer": "*", + "bare-events": "*" + }, + "peerDependenciesMeta": { + "bare-buffer": { + "optional": true + }, + "bare-events": { + "optional": true + } + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/baseline-browser-mapping": { + "version": "2.9.19", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, + "node_modules/basic-auth": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/basic-auth/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/before-after-hook": { + "version": "4.0.0", + "license": "Apache-2.0" + }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bn.js": { + "version": "4.12.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.3.tgz", + "integrity": "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.13.tgz", + "integrity": "sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "dev": true, + "license": "ISC" + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.1.tgz", + "integrity": "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^5.2.1", + "randombytes": "^2.1.0", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/browserify-rsa/node_modules/bn.js": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.3.tgz", + "integrity": "sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==", + "dev": true, + "license": "MIT" + }, + "node_modules/browserify-sign": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.5.tgz", + "integrity": "sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==", + "dev": true, + "license": "ISC", + "dependencies": { + "bn.js": "^5.2.2", + "browserify-rsa": "^4.1.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.6.1", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.9", + "readable-stream": "^2.3.8", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/browserify-sign/node_modules/bn.js": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.3.tgz", + "integrity": "sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==", + "dev": true, + "license": "MIT" + }, + "node_modules/browserify-zlib": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "pako": "~0.2.0" + } + }, + "node_modules/browserify-zlib/node_modules/pako": { + "version": "0.2.9", + "dev": true, + "license": "MIT" + }, + "node_modules/browserslist": { + "version": "4.28.1", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "6.0.3", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/buffer-equal": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "license": "MIT" + }, + "node_modules/c8": { + "version": "9.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@istanbuljs/schema": "^0.1.3", + "find-up": "^5.0.0", + "foreground-child": "^3.1.1", + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-report": "^3.0.1", + "istanbul-reports": "^3.1.6", + "test-exclude": "^6.0.0", + "v8-to-istanbul": "^9.0.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1" + }, + "bin": { + "c8": "bin/c8.js" + }, + "engines": { + "node": ">=14.14.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.0", + "es-define-property": "^1.0.0", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bind-apply-helpers/node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "6.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001769", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/ccount": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/charenc": { + "version": "0.0.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chokidar/node_modules/readdirp": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cipher-base": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/clone": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-buffer": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/clone-stats": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/cloneable-readable": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "node_modules/cls-hooked": { + "version": "4.2.2", + "license": "BSD-2-Clause", + "dependencies": { + "async-hook-jl": "^1.7.6", + "emitter-listener": "^1.0.1", + "semver": "^5.4.1" + }, + "engines": { + "node": "^4.7 || >=6.9 || >=7.3 || >=8.2.1" + } + }, + "node_modules/cls-hooked/node_modules/semver": { + "version": "5.7.2", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/cockatiel": { + "version": "3.1.1", + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "1.2.2", + "dev": true, + "license": "MIT" + }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/command-line-usage": { + "version": "6.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^4.0.1", + "chalk": "^2.4.2", + "table-layout": "^1.0.1", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/command-line-usage/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/command-line-usage/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/command-line-usage/node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/command-line-usage/node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/command-line-usage/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/commander": { + "version": "2.20.3", + "dev": true, + "license": "MIT" + }, + "node_modules/commandpost": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/continuation-local-storage": { + "version": "3.2.1", + "license": "BSD-2-Clause", + "dependencies": { + "async-listener": "^0.6.0", + "emitter-listener": "^1.1.1" + } + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/convert-source-map/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/cookies": { + "version": "0.9.1", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "keygrip": "~1.1.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cosmiconfig/node_modules/import-fresh": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-hash": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/cross-fetch": { + "version": "3.1.5", + "license": "MIT", + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": "*" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "dev": true, + "license": "MIT", + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/css-loader": { + "version": "7.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-tree": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.2.1.tgz", + "integrity": "sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.27.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssstyle": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-6.2.0.tgz", + "integrity": "sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^5.0.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.28", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.6" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cssstyle/node_modules/lru-cache": { + "version": "11.2.6", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.6.tgz", + "integrity": "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/csstype": { + "version": "3.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/data-urls": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-7.0.0.tgz", + "integrity": "sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==", + "dev": true, + "license": "MIT", + "dependencies": { + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/data-view-buffer": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/data-view-byte-length": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/inspect-js" + } + }, + "node_modules/data-view-byte-offset": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/dayjs": { + "version": "1.10.4", + "license": "MIT" + }, + "node_modules/debounce": { + "version": "1.2.1", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.4.1", + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/decamelize": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-equal": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-data-property": { + "version": "1.1.4", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/depd": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/dequal": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/devlop": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/diagnostic-channel": { + "version": "1.1.0", + "license": "MIT", + "dependencies": { + "semver": "^5.3.0" + } + }, + "node_modules/diagnostic-channel-publishers": { + "version": "1.0.5", + "license": "MIT", + "peerDependencies": { + "diagnostic-channel": "*" + } + }, + "node_modules/diagnostic-channel/node_modules/semver": { + "version": "5.7.2", + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/doctrine": { + "version": "2.1.0", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dom-testing-library": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.4.3", + "@sheerun/mutationobserver-shim": "^0.3.2", + "pretty-format": "^24.7.0", + "wait-for-expect": "^1.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/duplexer": { + "version": "0.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/duplexify": { + "version": "3.7.1", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/duplexify/node_modules/end-of-stream": { + "version": "1.4.5", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/editorconfig": { + "version": "0.15.3", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^2.19.0", + "lru-cache": "^4.1.5", + "semver": "^5.6.0", + "sigmund": "^1.0.1" + }, + "bin": { + "editorconfig": "bin/editorconfig" + } + }, + "node_modules/editorconfig/node_modules/lru-cache": { + "version": "4.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/editorconfig/node_modules/semver": { + "version": "5.7.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/editorconfig/node_modules/yallist": { + "version": "2.1.2", + "dev": true, + "license": "ISC" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.286", + "dev": true, + "license": "ISC" + }, + "node_modules/elliptic": { + "version": "6.6.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/emitter-listener": { + "version": "1.1.2", + "license": "BSD-2-Clause", + "dependencies": { + "shimmer": "^1.2.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.19.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.3.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/enquirer": { + "version": "2.3.6", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/envinfo": { + "version": "7.7.4", + "dev": true, + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.24.0", + "dev": true, + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.2", + "arraybuffer.prototype.slice": "^1.0.4", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "data-view-buffer": "^1.0.2", + "data-view-byte-length": "^1.0.2", + "data-view-byte-offset": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "es-set-tostringtag": "^2.1.0", + "es-to-primitive": "^1.3.0", + "function.prototype.name": "^1.1.8", + "get-intrinsic": "^1.3.0", + "get-proto": "^1.0.1", + "get-symbol-description": "^1.1.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "internal-slot": "^1.1.0", + "is-array-buffer": "^3.0.5", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.2", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.2.1", + "is-set": "^2.0.3", + "is-shared-array-buffer": "^1.0.4", + "is-string": "^1.1.1", + "is-typed-array": "^1.1.15", + "is-weakref": "^1.1.1", + "math-intrinsics": "^1.1.0", + "object-inspect": "^1.13.4", + "object-keys": "^1.1.1", + "object.assign": "^4.1.7", + "own-keys": "^1.0.1", + "regexp.prototype.flags": "^1.5.4", + "safe-array-concat": "^1.1.3", + "safe-push-apply": "^1.0.0", + "safe-regex-test": "^1.1.0", + "set-proto": "^1.0.0", + "stop-iteration-iterator": "^1.1.0", + "string.prototype.trim": "^1.2.10", + "string.prototype.trimend": "^1.0.9", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.3", + "typed-array-byte-length": "^1.0.3", + "typed-array-byte-offset": "^1.0.4", + "typed-array-length": "^1.0.7", + "unbox-primitive": "^1.1.0", + "which-typed-array": "^1.1.19" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract/node_modules/has-symbols": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract/node_modules/object.assign": { + "version": "4.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0", + "has-symbols": "^1.1.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7", + "is-date-object": "^1.0.5", + "is-symbol": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive/node_modules/has-symbols": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-to-primitive/node_modules/is-symbol": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-object-assign": { + "version": "1.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, + "node_modules/esbuild-loader": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/esbuild-loader/-/esbuild-loader-4.4.2.tgz", + "integrity": "sha512-8LdoT9sC7fzfvhxhsIAiWhzLJr9yT3ggmckXxsgvM07wgrRxhuT98XhLn3E7VczU5W5AFsPKv9DdWcZIubbWkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.1", + "get-tsconfig": "^4.10.1", + "loader-utils": "^2.0.4", + "webpack-sources": "^1.4.3" + }, + "funding": { + "url": "https://github.com/privatenumber/esbuild-loader?sponsor=1" + }, + "peerDependencies": { + "webpack": "^4.40.0 || ^5.0.0" + } + }, + "node_modules/esbuild-loader/node_modules/loader-utils": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "dev": true, + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/eslint": { + "version": "9.36.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.0", + "@eslint/config-helpers": "^0.3.1", + "@eslint/core": "^0.15.2", + "@eslint/eslintrc": "^3.3.1", + "@eslint/js": "9.36.0", + "@eslint/plugin-kit": "^0.3.5", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "@types/json-schema": "^7.0.15", + "ajv": "^6.12.4", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.2", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "node_modules/eslint-import-context": { + "version": "0.1.9", + "dev": true, + "license": "MIT", + "dependencies": { + "get-tsconfig": "^4.10.1", + "stable-hash-x": "^0.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-context" + }, + "peerDependencies": { + "unrs-resolver": "^1.0.0" + }, + "peerDependenciesMeta": { + "unrs-resolver": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "4.4.4", + "dev": true, + "license": "ISC", + "dependencies": { + "debug": "^4.4.1", + "eslint-import-context": "^0.1.8", + "get-tsconfig": "^4.10.1", + "is-bun-module": "^2.0.0", + "stable-hash-x": "^0.2.0", + "tinyglobby": "^0.2.14", + "unrs-resolver": "^1.7.11" + }, + "engines": { + "node": "^16.17.0 || >=18.6.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-resolver-typescript" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*", + "eslint-plugin-import-x": "*" + }, + "peerDependenciesMeta": { + "eslint-plugin-import": { + "optional": true + }, + "eslint-plugin-import-x": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-typescript/node_modules/fdir": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/eslint-import-resolver-typescript/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/eslint-import-resolver-typescript/node_modules/tinyglobby": { + "version": "0.2.15", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.12.1", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.31.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@rtsao/scc": "^1.1.0", + "array-includes": "^3.1.8", + "array.prototype.findlastindex": "^1.2.5", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.12.0", + "hasown": "^2.0.2", + "is-core-module": "^2.15.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.8", + "object.groupby": "^1.0.3", + "object.values": "^1.2.0", + "semver": "^6.3.1", + "string.prototype.trimend": "^1.0.8", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-rulesdir": { + "version": "0.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-scope/node_modules/estraverse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/debug": { + "version": "4.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/eslint/node_modules/eslint-scope": { + "version": "8.4.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/glob-parent": { + "version": "6.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/espree": { + "version": "10.4.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.6.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.2.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/event-stream": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "^0.1.1", + "from": "^0.1.7", + "map-stream": "0.0.7", + "pause-stream": "^0.0.11", + "split": "^1.0.1", + "stream-combiner": "^0.2.2", + "through": "^2.3.8" + } + }, + "node_modules/events": { + "version": "3.2.0", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/execa": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "human-signals": "^1.1.1", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.0", + "onetime": "^5.1.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/signal-exit": { + "version": "3.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/extend": { + "version": "3.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fast-content-type-parse": { + "version": "3.0.0", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "MIT" + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "license": "MIT" + }, + "node_modules/fast-fifo": { + "version": "1.3.2", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.11.0", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/file-entry-cache": { + "version": "8.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flat-cache": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/flatted": { + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", + "dev": true, + "license": "ISC" + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "node_modules/for-each": { + "version": "0.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/fork-ts-checker-webpack-plugin": { + "version": "9.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.16.7", + "chalk": "^4.1.2", + "chokidar": "^4.0.1", + "cosmiconfig": "^8.2.0", + "deepmerge": "^4.2.2", + "fs-extra": "^10.0.0", + "memfs": "^3.4.1", + "minimatch": "^3.0.4", + "node-abort-controller": "^3.0.1", + "schema-utils": "^3.1.1", + "semver": "^7.3.5", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "typescript": ">3.6.0", + "webpack": "^5.11.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/from": { + "version": "0.1.7", + "dev": true, + "license": "MIT" + }, + "node_modules/fs-extra": { + "version": "10.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/fs-mkdirp-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/fs-monkey": { + "version": "1.1.0", + "dev": true, + "license": "Unlicense" + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.8", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "functions-have-names": "^1.2.3", + "hasown": "^2.0.2", + "is-callable": "^1.2.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic/node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic/node_modules/has-symbols": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.11.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, + "node_modules/glob": { + "version": "7.1.6", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/glob-stream": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/glob-stream/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-stream/node_modules/glob-parent": { + "version": "3.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/glob-stream/node_modules/is-glob": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/globals": { + "version": "16.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.2.1", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "dev": true, + "license": "ISC" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/graphql": { + "version": "15.5.0", + "license": "MIT", + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/graphql-tag": { + "version": "2.11.0", + "license": "MIT", + "peerDependencies": { + "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0" + } + }, + "node_modules/gulp-filter": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "multimatch": "^5.0.0", + "plugin-error": "^1.0.1", + "streamfilter": "^3.0.0", + "to-absolute-glob": "^2.0.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + }, + "peerDependencies": { + "gulp": ">=4" + }, + "peerDependenciesMeta": { + "gulp": { + "optional": true + } + } + }, + "node_modules/gunzip-maybe": { + "version": "1.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "browserify-zlib": "^0.1.4", + "is-deflate": "^1.0.0", + "is-gzip": "^1.0.0", + "peek-stream": "^1.1.0", + "pumpify": "^1.3.3", + "through2": "^2.0.3" + }, + "bin": { + "gunzip-maybe": "bin.js" + } + }, + "node_modules/has-bigints": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag/node_modules/has-symbols": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.2.tgz", + "integrity": "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^2.3.8", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hasown/node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hast-util-to-html": { + "version": "9.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^3.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "stringify-entities": "^4.0.0", + "zwitch": "^2.0.4" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/he": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/http-assert": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-equal": "~1.0.1", + "http-errors": "~1.8.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors": { + "version": "1.8.1", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/depd": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/human-signals": { + "version": "1.1.1", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/husky": { + "version": "8.0.1", + "dev": true, + "license": "MIT", + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "5.2.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-arguments": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-async-function": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "async-function": "^1.0.0", + "call-bound": "^1.0.3", + "get-proto": "^1.0.1", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-bigints": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-boolean-object": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/is-bun-module": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.7.1" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-deflate": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/is-extendable": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-finalizationregistry": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-generator-function": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-proto": "^1.0.0", + "has-tostringtag": "^1.0.2", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-gzip": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-interactive": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-map": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-nan": { + "version": "1.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-negated-glob": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-number-object": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-potential-custom-element-name": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-relative": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-set": { + "version": "2.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-string": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.15", + "dev": true, + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "dev": true, + "license": "MIT" + }, + "node_modules/is-valid-glob": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-weakmap": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakset": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "get-intrinsic": "^1.2.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/isexe": { + "version": "2.0.0", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.2.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.1", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-28.1.0.tgz", + "integrity": "sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.31", + "@asamuzakjp/dom-selector": "^6.8.1", + "@bramus/specificity": "^2.4.2", + "@exodus/bytes": "^1.11.0", + "cssstyle": "^6.0.1", + "data-urls": "^7.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "undici": "^7.21.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.1", + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^16.0.0", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom-global": { + "version": "3.0.2", + "dev": true, + "license": "MIT", + "peerDependencies": { + "jsdom": ">=10.0.0" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.2", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "6.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jszip": { + "version": "3.10.1", + "dev": true, + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, + "node_modules/just-extend": { + "version": "4.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/keygrip": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tsscmp": "1.0.6" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/keyv": { + "version": "4.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/koa": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "^1.3.8", + "content-disposition": "~1.0.1", + "content-type": "^1.0.5", + "cookies": "~0.9.1", + "delegates": "^1.0.0", + "destroy": "^1.2.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "fresh": "~0.5.2", + "http-assert": "^1.5.0", + "http-errors": "^2.0.0", + "koa-compose": "^4.1.0", + "mime-types": "^3.0.1", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/koa-compose": { + "version": "4.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/koa-morgan": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "morgan": "^1.6.1" + } + }, + "node_modules/koa-mount": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.0.1", + "koa-compose": "^4.1.0" + }, + "engines": { + "node": ">= 7.6.0" + } + }, + "node_modules/koa-send": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "http-errors": "^1.7.3", + "resolve-path": "^1.4.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/koa-static": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.1.0", + "koa-send": "^5.0.0" + }, + "engines": { + "node": ">= 7.6.0" + } + }, + "node_modules/koa-static/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/koa/node_modules/http-errors": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/koa/node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/koa/node_modules/mime-db": { + "version": "1.54.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa/node_modules/mime-types": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/koa/node_modules/statuses": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/lazystream": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lead": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "flush-write-stream": "^1.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/levn/node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/levn/node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "dev": true, + "license": "MIT" + }, + "node_modules/linkify-it": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/loader-utils": { + "version": "1.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/loader-utils/node_modules/json5": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", + "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "dev": true, + "license": "ISC" + }, + "node_modules/map-stream": { + "version": "0.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/markdown-it": { + "version": "14.1.1", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/marked": { + "version": "4.0.10", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/md5": { + "version": "2.3.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "charenc": "0.0.2", + "crypt": "0.0.2", + "is-buffer": "~1.1.6" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.27.1.tgz", + "integrity": "sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/mdurl": { + "version": "2.0.0", + "license": "MIT" + }, + "node_modules/media-typer": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/memfs": { + "version": "3.6.0", + "dev": true, + "license": "Unlicense", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/merge-options": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "dev": true, + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.7", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/mkdirp": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha": { + "version": "11.7.5", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-11.7.5.tgz", + "integrity": "sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==", + "dev": true, + "license": "MIT", + "dependencies": { + "browser-stdout": "^1.3.1", + "chokidar": "^4.0.1", + "debug": "^4.3.5", + "diff": "^7.0.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^10.4.5", + "he": "^1.2.0", + "is-path-inside": "^3.0.3", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^9.0.5", + "ms": "^2.1.3", + "picocolors": "^1.1.1", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^9.2.0", + "yargs": "^17.7.2", + "yargs-parser": "^21.1.1", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/mocha-junit-reporter": { + "version": "1.23.0", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^2.2.0", + "md5": "^2.1.0", + "mkdirp": "~0.5.1", + "strip-ansi": "^4.0.0", + "xml": "^1.0.0" + }, + "peerDependencies": { + "mocha": ">=2.2.5" + } + }, + "node_modules/mocha-junit-reporter/node_modules/ansi-regex": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/mocha-junit-reporter/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/mocha-junit-reporter/node_modules/mkdirp": { + "version": "0.5.5", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha-junit-reporter/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/mocha-junit-reporter/node_modules/strip-ansi": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mocha-multi-reporters": { + "version": "1.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^3.1.0", + "lodash": "^4.16.4" + } + }, + "node_modules/mocha-multi-reporters/node_modules/debug": { + "version": "3.2.7", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.3.tgz", + "integrity": "sha512-MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", + "dev": true, + "license": "ISC", + "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" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", + "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.2" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/morgan": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz", + "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.1.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/morgan/node_modules/debug": { + "version": "2.6.9", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/morgan/node_modules/ms": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/morgan/node_modules/on-finished": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "license": "MIT" + }, + "node_modules/multimatch": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/multimatch/node_modules/@types/minimatch": { + "version": "3.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/napi-postinstall": { + "version": "0.3.4", + "dev": true, + "license": "MIT", + "bin": { + "napi-postinstall": "lib/cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/napi-postinstall" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "dev": true, + "license": "MIT" + }, + "node_modules/nise": { + "version": "4.1.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/node-abort-controller": { + "version": "3.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/node-fetch": { + "version": "2.6.7", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "license": "MIT" + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "license": "BSD-2-Clause" + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/node-releases": { + "version": "2.0.27", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/now-and-later": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "once": "^1.3.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-is": { + "version": "1.1.5", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/optimism": { + "version": "0.10.3", + "license": "MIT", + "dependencies": { + "@wry/context": "^0.4.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "dev": true, + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/optionator/node_modules/prelude-ls": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/optionator/node_modules/type-check": { + "version": "0.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "8.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "cli-cursor": "^5.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.2", + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "5.4.1", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/emoji-regex": { + "version": "10.4.0", + "dev": true, + "license": "MIT" + }, + "node_modules/ora/node_modules/is-unicode-supported": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/log-symbols": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/string-width": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/ordered-read-streams": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^2.0.1" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/own-keys": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.6", + "object-keys": "^1.1.1", + "safe-push-apply": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-all": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-map": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pako": { + "version": "1.0.11", + "dev": true, + "license": "(MIT AND Zlib)" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-asn1": { + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.9.tgz", + "integrity": "sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "asn1.js": "^4.10.1", + "browserify-aes": "^1.2.0", + "evp_bytestokey": "^1.0.3", + "pbkdf2": "^3.1.5", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", + "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-browserify": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "node_modules/path-exists": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "dev": true, + "license": "ISC" + }, + "node_modules/path-to-regexp": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-to-regexp/node_modules/isarray": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/pause-stream": { + "version": "0.0.11", + "dev": true, + "license": [ + "MIT", + "Apache2" + ], + "dependencies": { + "through": "~2.3" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.5.tgz", + "integrity": "sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "ripemd160": "^2.0.3", + "safe-buffer": "^5.2.1", + "sha.js": "^2.4.12", + "to-buffer": "^1.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/peek-stream": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "duplexify": "^3.5.0", + "through2": "^2.0.3" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", + "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/playwright": { + "version": "1.56.1", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.56.1" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.54.1", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/playwright/node_modules/playwright-core": { + "version": "1.56.1", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/plugin-error": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-colors": "^1.0.1", + "arr-diff": "^4.0.0", + "arr-union": "^3.1.0", + "extend-shallow": "^3.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/plugin-error/node_modules/ansi-colors": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-wrap": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/possible-typed-array-names": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.5.12", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.12.tgz", + "integrity": "sha512-W62t/Se6rA0Az3DfCL0AqJwXuKwBeYg6nOaIgzP+xZ7N5BFCI7DYi1qs6ygUYT6rvfi6t9k65UMLJC+PHZpDAA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss/node_modules/nanoid": { + "version": "3.3.11", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/pretty-format": { + "version": "24.9.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^24.9.0", + "ansi-regex": "^4.0.0", + "ansi-styles": "^3.2.0", + "react-is": "^16.8.4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pretty-format/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pretty-format/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/pretty-format/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "node_modules/process": { + "version": "0.11.10", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/prompts": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.7.2", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "node_modules/property-information": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/pseudomap": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/pump": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/pumpify/node_modules/pump": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/punycode.js": { + "version": "2.3.1", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.2", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/react": { + "version": "16.14.0", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "16.14.0", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.19.1" + }, + "peerDependencies": { + "react": "^16.14.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "license": "MIT" + }, + "node_modules/react-testing-library": { + "version": "7.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.4.3", + "dom-testing-library": "^4.1.0" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/isarray": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "dev": true, + "license": "MIT" + }, + "node_modules/readable-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/readdirp": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/reduce-flatten": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/reflect.getprototypeof": { + "version": "1.0.10", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.9", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.7", + "get-proto": "^1.0.1", + "which-builtin-type": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/remove-bom-buffer": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remove-bom-stream": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/replace-ext": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-options": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "value-or-function": "^3.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/resolve-path": { + "version": "1.4.0", + "dev": true, + "license": "MIT", + "dependencies": { + "http-errors": "~1.6.2", + "path-is-absolute": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/resolve-path/node_modules/depd": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/resolve-path/node_modules/http-errors": { + "version": "1.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/resolve-path/node_modules/inherits": { + "version": "2.0.3", + "dev": true, + "license": "ISC" + }, + "node_modules/resolve-path/node_modules/setprototypeof": { + "version": "1.1.0", + "dev": true, + "license": "ISC" + }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor/node_modules/onetime": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rimraf": { + "version": "2.6.3", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/ripemd160": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.3.tgz", + "integrity": "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==", + "dev": true, + "license": "MIT", + "dependencies": { + "hash-base": "^3.1.2", + "inherits": "^2.0.4" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-array-concat": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "get-intrinsic": "^1.2.6", + "has-symbols": "^1.1.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-array-concat/node_modules/has-symbols": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-push-apply": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "dev": true, + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" + } + }, + "node_modules/scheduler": { + "version": "0.19.1", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "node_modules/schema-utils": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "7.7.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-7.0.5.tgz", + "integrity": "sha512-F4LcB0UqUl1zErq+1nYEEzSHJnIwb3AF2XWB94b+afhrekOUijwooAYqFyRbjYkm2PAKBabx6oYv/xDxNi8IBw==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/set-function-length": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-length/node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/set-function-name": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-proto": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "dev": true, + "license": "ISC" + }, + "node_modules/sha.js": { + "version": "2.4.12", + "dev": true, + "license": "(MIT AND BSD-3-Clause)", + "dependencies": { + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" + }, + "bin": { + "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shimmer": { + "version": "1.2.1", + "license": "BSD-2-Clause" + }, + "node_modules/side-channel": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sigmund": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-html-tokenizer": { + "version": "0.1.1", + "dev": true, + "license": "MIT" + }, + "node_modules/sinon": { + "version": "9.0.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/formatio": "^5.0.0", + "@sinonjs/samsam": "^5.0.1", + "diff": "^4.0.2", + "nise": "^4.0.1", + "supports-color": "^7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/source-list-map": { + "version": "2.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.19", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/split": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ssh-config": { + "version": "4.1.1", + "license": "MIT" + }, + "node_modules/stable-hash-x": { + "version": "0.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/stack-chain": { + "version": "1.3.7", + "license": "MIT" + }, + "node_modules/statuses": { + "version": "1.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stdin-discarder": { + "version": "0.2.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stop-iteration-iterator": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "internal-slot": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/stream-browserify": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "node_modules/stream-browserify/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/stream-combiner": { + "version": "0.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "duplexer": "~0.1.1", + "through": "~2.3.4" + } + }, + "node_modules/stream-http": { + "version": "3.2.0", + "license": "MIT", + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, + "node_modules/stream-http/node_modules/readable-stream": { + "version": "3.6.0", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/streamfilter": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "^3.0.6" + }, + "engines": { + "node": ">=8.12.0" + } + }, + "node_modules/streamfilter/node_modules/readable-stream": { + "version": "3.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/streamx": { + "version": "2.22.1", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-fifo": "^1.3.2", + "text-decoder": "^1.1.0" + }, + "optionalDependencies": { + "bare-events": "^2.2.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.10", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-data-property": "^1.1.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.5", + "es-object-atoms": "^1.0.0", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.9", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.2", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-loader": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.27.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-inline-loader": { + "version": "0.8.2", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^1.1.0", + "object-assign": "^4.0.1", + "simple-html-tokenizer": "^0.1.1" + } + }, + "node_modules/symbol-observable": { + "version": "1.2.0", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/symbol-tree": { + "version": "3.2.4", + "dev": true, + "license": "MIT" + }, + "node_modules/table-layout": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "array-back": "^4.0.1", + "deep-extend": "~0.6.0", + "typical": "^5.2.0", + "wordwrapjs": "^4.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/tapable": { + "version": "2.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/tar-fs": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.2.tgz", + "integrity": "sha512-QGxxTxxyleAdyM3kpFs14ymbYmNFrfY+pHj7Z8FgtbZ7w2//VAgLMac7sT6nRpIHjppXO2AwwEOg0bPFVRcmXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "pump": "^3.0.0", + "tar-stream": "^3.1.5" + }, + "optionalDependencies": { + "bare-fs": "^4.0.1", + "bare-path": "^3.0.0" + } + }, + "node_modules/tar-stream": { + "version": "3.1.7", + "dev": true, + "license": "MIT", + "dependencies": { + "b4a": "^1.6.4", + "fast-fifo": "^1.2.0", + "streamx": "^2.15.0" + } + }, + "node_modules/tas-client": { + "version": "0.2.33", + "license": "MIT" + }, + "node_modules/temp": { + "version": "0.9.4", + "dev": true, + "license": "MIT", + "dependencies": { + "mkdirp": "^0.5.1", + "rimraf": "~2.6.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/temp/node_modules/mkdirp": { + "version": "0.5.5", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/temporal-polyfill": { + "version": "0.3.0", + "license": "MIT", + "dependencies": { + "temporal-spec": "0.3.0" + } + }, + "node_modules/temporal-spec": { + "version": "0.3.0", + "license": "ISC" + }, + "node_modules/terser": { + "version": "5.46.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.1.tgz", + "integrity": "sha512-vzCjQO/rgUuK9sf8VJZvjqiqiHFaZLnOiimmUuOKODxWL8mm/xua7viT7aqX7dgPY60otQjUotzFMmCB4VdmqQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.15.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.17", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.17.tgz", + "integrity": "sha512-YR7PtUp6GMU91BgSJmlaX/rS2lGDbAF7D+Wtq7hRO+MiljNmodYvqslzCFiYVAgW+Qoaaia/QUIP4lGXufjdZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/terser-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/terser-webpack-plugin/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/terser-webpack-plugin/node_modules/schema-utils": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/terser/node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/text-decoder": { + "version": "1.2.3", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "b4a": "^1.6.4" + } + }, + "node_modules/through": { + "version": "2.3.8", + "dev": true, + "license": "MIT" + }, + "node_modules/through2": { + "version": "2.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2-filter": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "dev": true, + "license": "MIT", + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.6", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", + "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tldts": { + "version": "7.0.25", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.25.tgz", + "integrity": "sha512-keinCnPbwXEUG3ilrWQZU+CqcTTzHq9m2HhoUP2l7Xmi8l1LuijAXLpAJ5zRW+ifKTNscs4NdCkfkDCBYm352w==", + "dev": true, + "license": "MIT", + "dependencies": { + "tldts-core": "^7.0.25" + }, + "bin": { + "tldts": "bin/cli.js" + } + }, + "node_modules/tldts-core": { + "version": "7.0.25", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.25.tgz", + "integrity": "sha512-ZjCZK0rppSBu7rjHYDYsEaMOIbbT+nWF57hKkv4IUmZWBNrBWBOjIElc0mKRgLM8bm7x/BBlof6t2gi/Oq/Asw==", + "dev": true, + "license": "MIT" + }, + "node_modules/to-absolute-glob": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-buffer": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "isarray": "^2.0.5", + "safe-buffer": "^5.2.1", + "typed-array-buffer": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-through": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tough-cookie": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", + "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/trim-lines": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/ts-api-utils": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, + "node_modules/ts-invariant": { + "version": "0.4.4", + "license": "MIT", + "dependencies": { + "tslib": "^1.9.3" + } + }, + "node_modules/ts-loader": { + "version": "9.5.2", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.4", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/ts-node": { + "version": "10.9.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@cspotcode/source-map-support": "^0.8.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.1", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/node_modules/diff": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz", + "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/tslib": { + "version": "1.14.1", + "license": "0BSD" + }, + "node_modules/tsscmp": { + "version": "1.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.x" + } + }, + "node_modules/tty": { + "version": "1.0.1", + "dev": true, + "license": "ISC" + }, + "node_modules/tunnel": { + "version": "0.0.6", + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/type-is": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-db": { + "version": "1.54.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/type-is/node_modules/mime-types": { + "version": "3.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-array-buffer": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "for-each": "^0.3.3", + "gopd": "^1.2.0", + "has-proto": "^1.2.0", + "is-typed-array": "^1.1.15", + "reflect.getprototypeof": "^1.0.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.7", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0", + "reflect.getprototypeof": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typescript": { + "version": "5.9.2", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/typescript-eslint": { + "version": "8.44.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@typescript-eslint/eslint-plugin": "8.44.1", + "@typescript-eslint/parser": "8.44.1", + "@typescript-eslint/typescript-estree": "8.44.1", + "@typescript-eslint/utils": "8.44.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <6.0.0" + } + }, + "node_modules/typescript-formatter": { + "version": "7.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "commandpost": "^1.0.0", + "editorconfig": "^0.15.0" + }, + "bin": { + "tsfmt": "bin/tsfmt" + }, + "engines": { + "node": ">= 4.2.0" + }, + "peerDependencies": { + "typescript": "^2.1.6 || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev" + } + }, + "node_modules/typical": { + "version": "5.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/uc.micro": { + "version": "2.1.0", + "license": "MIT" + }, + "node_modules/unbox-primitive": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "has-bigints": "^1.0.2", + "has-symbols": "^1.1.0", + "which-boxed-primitive": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unbox-primitive/node_modules/has-symbols": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unc-path-regex": { + "version": "0.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/undici": { + "version": "7.24.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.24.4.tgz", + "integrity": "sha512-BM/JzwwaRXxrLdElV2Uo6cTLEjhSb3WXboncJamZ15NgUURmvlXvxa6xkwIOILIjPNo9i8ku136ZvWV0Uly8+w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "license": "MIT" + }, + "node_modules/unique-stream": { + "version": "2.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/universal-user-agent": { + "version": "7.0.3", + "license": "ISC" + }, + "node_modules/universalify": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/unrs-resolver": { + "version": "1.11.1", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "napi-postinstall": "^0.3.0" + }, + "funding": { + "url": "https://opencollective.com/unrs-resolver" + }, + "optionalDependencies": { + "@unrs/resolver-binding-android-arm-eabi": "1.11.1", + "@unrs/resolver-binding-android-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-arm64": "1.11.1", + "@unrs/resolver-binding-darwin-x64": "1.11.1", + "@unrs/resolver-binding-freebsd-x64": "1.11.1", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.11.1", + "@unrs/resolver-binding-linux-arm64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-arm64-musl": "1.11.1", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-riscv64-musl": "1.11.1", + "@unrs/resolver-binding-linux-s390x-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-gnu": "1.11.1", + "@unrs/resolver-binding-linux-x64-musl": "1.11.1", + "@unrs/resolver-binding-wasm32-wasi": "1.11.1", + "@unrs/resolver-binding-win32-arm64-msvc": "1.11.1", + "@unrs/resolver-binding-win32-ia32-msvc": "1.11.1", + "@unrs/resolver-binding-win32-x64-msvc": "1.11.1" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/url-search-params-polyfill": { + "version": "8.1.1", + "license": "MIT" + }, + "node_modules/util": { + "version": "0.12.4", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "license": "MIT" + }, + "node_modules/uuid": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz", + "integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist-node/bin/uuid" + } + }, + "node_modules/v8-compile-cache": { + "version": "2.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-compile-cache-lib": { + "version": "3.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul": { + "version": "9.3.0", + "dev": true, + "license": "ISC", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.12", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/v8-to-istanbul/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/v8-to-istanbul/node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.6", + "dev": true, + "license": "MIT" + }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "2.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/value-or-function": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vfile": { + "version": "6.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vinyl": { + "version": "2.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-fs": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-sourcemap": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-sourcemap/node_modules/normalize-path": { + "version": "2.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vscode-tas-client": { + "version": "0.1.84", + "license": "MIT", + "dependencies": { + "tas-client": "0.2.33" + }, + "engines": { + "vscode": "^1.85.0" + } + }, + "node_modules/vscode-uri": { + "version": "3.1.0", + "dev": true, + "license": "MIT" + }, + "node_modules/vsls": { + "version": "0.3.1291", + "license": "SEE LICENSE IN LICENSE.txt" + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/wait-for-expect": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "node_modules/watchpack": { + "version": "2.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" + } + }, + "node_modules/webpack": { + "version": "5.104.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.28.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.4", + "es-module-lexer": "^2.0.0", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.3.1", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", + "terser-webpack-plugin": "^5.3.16", + "watchpack": "^2.4.4", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "4.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@webpack-cli/info": "^1.1.0", + "@webpack-cli/serve": "^1.1.0", + "colorette": "^1.2.1", + "command-line-usage": "^6.1.0", + "commander": "^6.2.0", + "enquirer": "^2.3.6", + "execa": "^4.1.0", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "leven": "^3.1.0", + "rechoir": "^0.7.0", + "v8-compile-cache": "^2.2.0", + "webpack-merge": "^4.2.2" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generate-loader": { + "optional": true + }, + "@webpack-cli/generate-plugin": { + "optional": true + }, + "@webpack-cli/init": { + "optional": true + }, + "@webpack-cli/migrate": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-merge": { + "version": "4.2.2", + "dev": true, + "license": "MIT", + "dependencies": { + "lodash": "^4.17.15" + } + }, + "node_modules/webpack-sources": { + "version": "1.4.3", + "dev": true, + "license": "MIT", + "dependencies": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + } + }, + "node_modules/webpack/node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack/node_modules/ajv-keywords": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack/node_modules/events": { + "version": "3.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "1.0.0", + "dev": true, + "license": "MIT" + }, + "node_modules/webpack/node_modules/schema-utils": { + "version": "4.3.3", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack/node_modules/terser-webpack-plugin": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.4.0.tgz", + "integrity": "sha512-Bn5vxm48flOIfkdl5CaD2+1CiUVbonWQ3KQPyP7/EuIl9Gbzq/gQFOzaMFUEgVjB1396tcK0SG8XcNJ/2kDH8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/webpack-sources": { + "version": "3.3.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, + "node_modules/whatwg-url": { + "version": "16.0.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-16.0.1.tgz", + "integrity": "sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.11.0", + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-bigint": "^1.1.0", + "is-boolean-object": "^1.2.1", + "is-number-object": "^1.1.1", + "is-string": "^1.1.1", + "is-symbol": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-boxed-primitive/node_modules/has-symbols": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-boxed-primitive/node_modules/is-symbol": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "has-symbols": "^1.1.0", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-builtin-type": { + "version": "1.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "function.prototype.name": "^1.1.6", + "has-tostringtag": "^1.0.2", + "is-async-function": "^2.0.0", + "is-date-object": "^1.1.0", + "is-finalizationregistry": "^1.1.0", + "is-generator-function": "^1.0.10", + "is-regex": "^1.2.1", + "is-weakref": "^1.0.2", + "isarray": "^2.0.5", + "which-boxed-primitive": "^1.1.0", + "which-collection": "^1.0.2", + "which-typed-array": "^1.1.16" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-collection": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "is-map": "^2.0.3", + "is-set": "^2.0.3", + "is-weakmap": "^2.0.2", + "is-weakset": "^2.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.19", + "dev": true, + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrapjs": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "reduce-flatten": "^2.0.0", + "typical": "^5.2.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/workerpool": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-9.3.4.tgz", + "integrity": "sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "node_modules/xml": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" + }, + "node_modules/xtend": { + "version": "4.0.2", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "4.0.0", + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zen-observable": { + "version": "0.8.15", + "license": "MIT" + }, + "node_modules/zen-observable-ts": { + "version": "0.8.21", + "license": "MIT", + "dependencies": { + "tslib": "^1.9.3", + "zen-observable": "^0.8.0" + } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + } + } +} diff --git a/package.json b/package.json index c353d5e65a..0515181d94 100644 --- a/package.json +++ b/package.json @@ -41,9 +41,10 @@ "treeItemMarkdownLabel", "treeViewMarkdownMessage" ], - "version": "0.130.0", + "version": "0.140.0", "publisher": "GitHub", "engines": { + "node": ">=20", "vscode": "^1.110.0" }, "categories": [ @@ -309,6 +310,11 @@ "default": true, "description": "%githubPullRequests.defaultDeletionMethod.selectRemote.description%" }, + "githubPullRequests.defaultDeletionMethod.selectWorktree": { + "type": "boolean", + "default": false, + "description": "%githubPullRequests.defaultDeletionMethod.selectWorktree.description%" + }, "githubPullRequests.deleteBranchAfterMerge": { "type": "boolean", "default": false, @@ -797,11 +803,15 @@ "type": "string", "enum": [ "author", - "assignee" + "assignee", + "state", + "generic" ], "enumDescriptions": [ "%githubIssues.issueAvatarDisplay.author%", - "%githubIssues.issueAvatarDisplay.assignee%" + "%githubIssues.issueAvatarDisplay.assignee%", + "%githubIssues.issueAvatarDisplay.state%", + "%githubIssues.issueAvatarDisplay.generic%" ], "default": "author", "description": "%githubIssues.issueAvatarDisplay.description%" @@ -837,6 +847,21 @@ "default": false, "description": "%githubPullRequests.showPullRequestNumberInTree.description%" }, + "githubPullRequests.pullRequestAvatarDisplay": { + "type": "string", + "enum": [ + "author", + "state", + "generic" + ], + "enumDescriptions": [ + "%githubPullRequests.pullRequestAvatarDisplay.author%", + "%githubPullRequests.pullRequestAvatarDisplay.state%", + "%githubPullRequests.pullRequestAvatarDisplay.generic%" + ], + "default": "author", + "description": "%githubPullRequests.pullRequestAvatarDisplay.description%" + }, "githubIssues.alwaysPromptForNewIssueRepo": { "type": "boolean", "default": false, @@ -988,6 +1013,18 @@ "category": "%command.pull.request.category%", "icon": "$(cloud)" }, + { + "command": "pr.pickInWorktree", + "title": "%command.pr.pickInWorktreeFromDescription.title%", + "category": "%command.pull.request.category%", + "icon": "$(folder-library)" + }, + { + "command": "pr.pickInWorktreeFromDescription", + "title": "%command.pr.pickInWorktree.title%", + "category": "%command.pull.request.category%", + "icon": "$(folder-library)" + }, { "command": "pr.exit", "title": "%command.pr.exit.title%", @@ -2059,6 +2096,14 @@ "command": "pr.pickOnCodespaces", "when": "false" }, + { + "command": "pr.pickInWorktree", + "when": "false" + }, + { + "command": "pr.pickInWorktreeFromDescription", + "when": "false" + }, { "command": "pr.exit", "when": "github:inReviewMode" @@ -2857,6 +2902,11 @@ "when": "view == pr:github && viewItem =~ /pullrequest(:local)?:nonactive/ && (!isWeb || remoteName != codespaces && virtualWorkspace != vscode-vfs)", "group": "1_pullrequest@3" }, + { + "command": "pr.pickInWorktree", + "when": "view == pr:github && viewItem =~ /pullrequest(:local)?:nonactive/ && !isWeb", + "group": "1_pullrequest@4" + }, { "command": "pr.openChanges", "when": "view =~ /(pr|prStatus):github/ && viewItem =~ /(pullrequest|description)/", @@ -3616,13 +3666,18 @@ "when": "webviewId == PullRequestOverview && github:checkoutMenu" }, { - "command": "pr.checkoutOnVscodeDevFromDescription", + "command": "pr.pickInWorktreeFromDescription", "group": "checkout@1", + "when": "webviewId == PullRequestOverview && github:checkoutMenu && !isWeb" + }, + { + "command": "pr.checkoutOnVscodeDevFromDescription", + "group": "checkout@2", "when": "webviewId == PullRequestOverview && github:checkoutMenu" }, { "command": "pr.checkoutOnCodespacesFromDescription", - "group": "checkout@2", + "group": "checkout@3", "when": "webviewId == PullRequestOverview && github:checkoutMenu" }, { @@ -3770,6 +3825,12 @@ }, { "path": "./src/lm/skills/show-github-search-result/SKILL.md" + }, + { + "path": "./src/lm/skills/address-pr-comments/SKILL.md" + }, + { + "path": "./src/lm/skills/create-pull-request/SKILL.md" } ], "languageModelTools": [ @@ -3928,18 +3989,27 @@ "when": "config.githubPullRequests.experimental.chat" }, { - "name": "github-pull-request_activePullRequest", + "name": "github-pull-request_currentActivePullRequest", "tags": [ "github", "pull request" ], "toolReferenceName": "activePullRequest", - "displayName": "%languageModelTools.github-pull-request_activePullRequest.displayName%", + "displayName": "%languageModelTools.github-pull-request_currentActivePullRequest.displayName%", "modelDescription": "Get comprehensive information about the active GitHub pull request (PR). The active PR is the one that is currently checked out. This includes the PR title, full description, list of changed files, review comments, and PR state. For PRs created by Copilot, it also includes the session logs which indicate the development process and decisions made by the coding agent. Does NOT include status checks/CI results; use the pullRequestStatusChecks tool instead. When asked about the active or current pull request, do this first! Use this tool for any request related to \"current changes,\" \"pull request details,\" \"what changed,\" or similar queries even if the user does not explicitly mention \"pull request.\" When asked to use this tool, ALWAYS use it.", "icon": "$(git-pull-request)", "canBeReferencedInPrompt": true, - "userDescription": "%languageModelTools.github-pull-request_activePullRequest.description%", - "when": "config.githubPullRequests.experimental.chat" + "userDescription": "%languageModelTools.github-pull-request_currentActivePullRequest.description%", + "when": "config.githubPullRequests.experimental.chat", + "inputSchema": { + "type": "object", + "properties": { + "refresh": { + "type": "boolean", + "description": "Whether to fetch fresh data from GitHub or return cached data. Set to true to ensure the most up-to-date information, especially after recent changes. Set to false to improve performance when up-to-date information is not critical." + } + } + } }, { "name": "github-pull-request_pullRequestStatusChecks", @@ -3988,23 +4058,111 @@ "when": "config.githubPullRequests.experimental.chat" }, { - "name": "github-pull-request_openPullRequest", + "name": "github-pull-request_pullRequestInViewport", "tags": [ "github", "pull request" ], "toolReferenceName": "openPullRequest", - "displayName": "%languageModelTools.github-pull-request_openPullRequest.displayName%", + "displayName": "%languageModelTools.github-pull-request_pullRequestInViewport.displayName%", "modelDescription": "Get comprehensive information about the GitHub pull request (PR) which is currently visible, but not necessarily checked out. This is the pull request that the user is currently viewing. This includes the PR title, full description, list of changed files, review comments, and PR state. For PRs created by Copilot, it also includes the session logs which indicate the development process and decisions made by the coding agent. Does NOT include status checks/CI results; use the pullRequestStatusChecks tool instead. When asked about the currently open pull request, do this first! Use this tool for any request related to \"pull request details,\" \"what changed,\" or similar queries even if the user does not explicitly mention \"pull request.\" When asked to use this tool, ALWAYS use it.", "icon": "$(git-pull-request)", "canBeReferencedInPrompt": true, - "userDescription": "%languageModelTools.github-pull-request_openPullRequest.description%", + "userDescription": "%languageModelTools.github-pull-request_pullRequestInViewport.description%", "when": "config.githubPullRequests.experimental.chat" + }, + { + "name": "github-pull-request_create_pull_request", + "tags": [ + "github", + "pull request" + ], + "toolReferenceName": "create_pull_request", + "displayName": "%languageModelTools.github-pull-request_create_pull_request.displayName%", + "userDescription": "%languageModelTools.github-pull-request_create_pull_request.description%", + "modelDescription": "Create a new GitHub pull request. Requires a title and head branch. The base branch and repo default to the repository defaults. Returns the created pull request number, URL, and details.", + "icon": "$(git-pull-request-new)", + "canBeReferencedInPrompt": true, + "inputSchema": { + "type": "object", + "properties": { + "repo": { + "type": "object", + "description": "The repository to create the pull request in.", + "properties": { + "owner": { + "type": "string", + "description": "The owner of the repository." + }, + "name": { + "type": "string", + "description": "The name of the repository." + } + } + }, + "title": { + "type": "string", + "description": "The title of the pull request." + }, + "body": { + "type": "string", + "description": "The body/description of the pull request." + }, + "head": { + "type": "string", + "description": "The name of the branch where your changes are implemented (branch name only, without owner prefix)." + }, + "headOwner": { + "type": "string", + "description": "The owner of the head branch repository. Defaults to the origin/push remote repository owner." + }, + "base": { + "type": "string", + "description": "The name of the branch you want the changes pulled into. Defaults to the repository's default branch." + }, + "draft": { + "type": "boolean", + "description": "Indicates whether the pull request is a draft." + } + }, + "required": [ + "title", + "head" + ] + }, + "when": "config.githubPullRequests.experimental.chat" + }, + { + "name": "github-pull-request_resolveReviewThread", + "tags": [ + "github", + "pull request", + "review" + ], + "toolReferenceName": "resolveReviewThread", + "displayName": "%languageModelTools.github-pull-request_resolveReviewThread.displayName%", + "modelDescription": "Resolve a review thread on the active GitHub pull request. Use the threadId from the reviewThreads array returned by the activePullRequest tool. Only resolves threads where canResolve is true and isResolved is false.", + "icon": "$(pass)", + "canBeReferencedInPrompt": true, + "userDescription": "%languageModelTools.github-pull-request_resolveReviewThread.description%", + "when": "config.githubPullRequests.experimental.chat", + "inputSchema": { + "type": "object", + "properties": { + "threadId": { + "type": "string", + "description": "The GraphQL node ID of the review thread to resolve. Obtain this from the id field in the reviewThreads array of the activePullRequest tool output." + } + }, + "required": [ + "threadId" + ] + } } ] }, "scripts": { - "postinstall": "yarn update-dts", + "postinstall": "npm run update-dts", "bundle": "webpack --mode production --env esbuild", "bundle:node": "webpack --mode production --config-name extension:node --config-name webviews", "bundle:web": "webpack --mode production --config-name extension:webworker --config-name webviews", @@ -4015,11 +4173,11 @@ "compile:node": "webpack --mode development --config-name extension:node --config-name webviews", "compile:web": "webpack --mode development --config-name extension:webworker --config-name webviews", "lint": "eslint --fix --cache . --ext .ts,.tsx", - "package": "npx vsce package --yarn", - "test": "yarn run test:preprocess && node ./out/src/test/runTests.js", - "test:preprocess": "yarn run compile:test && yarn run test:preprocess-gql && yarn run test:preprocess-svg && yarn run test:preprocess-fixtures", + "package": "npx vsce package", + "test": "npm run test:preprocess && node ./out/src/test/runTests.js", + "test:preprocess": "npm run compile:test && npm run test:preprocess-gql && npm run test:preprocess-svg && npm run test:preprocess-fixtures", "browsertest:preprocess": "tsc ./src/test/browser/runTests.ts --outDir ./dist/browser/test --rootDir ./src/test/browser --target es6 --module commonjs", - "browsertest": "yarn run browsertest:preprocess && node ./dist/browser/test/runTests.js", + "browsertest": "npm run browsertest:preprocess && node ./dist/browser/test/runTests.js", "test:preprocess-gql": "node scripts/preprocess-gql --in src/github/queries.gql --out out/src/github/queries.gql && node scripts/preprocess-gql --in src/github/queriesExtra.gql --out out/src/github/queriesExtra.gql && node scripts/preprocess-gql --in src/github/queriesShared.gql --out out/src/github/queriesShared.gql && node scripts/preprocess-gql --in src/github/queriesLimited.gql --out out/src/github/queriesLimited.gql", "test:preprocess-svg": "node scripts/preprocess-svg --in ../resources/ --out out/resources", "test:preprocess-fixtures": "node scripts/preprocess-fixtures --in src --out out", @@ -4039,7 +4197,7 @@ "@types/js-yaml": "^4.0.9", "@types/lru-cache": "^5.1.0", "@types/marked": "^0.7.2", - "@types/mocha": "^8.2.2", + "@types/mocha": "^10.0.10", "@types/node": "22", "@types/react": "^16.8.4", "@types/react-dom": "^16.8.2", @@ -4058,7 +4216,7 @@ "constants-browserify": "^1.0.0", "crypto-browserify": "3.12.0", "css-loader": "7.1.2", - "esbuild-loader": "4.2.2", + "esbuild-loader": "4.4.2", "eslint": "^9.36.0", "eslint-import-resolver-typescript": "^4.4.4", "eslint-plugin-import": "2.31.0", @@ -4071,13 +4229,13 @@ "graphql-tag": "2.11.0", "gulp-filter": "^7.0.0", "husky": "^8.0.1", - "jsdom": "19.0.0", + "jsdom": "28.1.0", "jsdom-global": "3.0.2", "json5": "2.2.2", "merge-options": "3.0.4", "minimist": "^1.2.6", "mkdirp": "1.0.4", - "mocha": "^9.0.1", + "mocha": "^11.7.5", "mocha-junit-reporter": "1.23.0", "mocha-multi-reporters": "1.1.7", "os-browserify": "^0.3.0", @@ -4091,7 +4249,7 @@ "style-loader": "4.0.0", "svg-inline-loader": "^0.8.2", "temp": "0.9.4", - "terser-webpack-plugin": "5.1.1", + "terser-webpack-plugin": "5.3.17", "timers-browserify": "^2.0.12", "ts-loader": "9.5.2", "ts-node": "^10.9.2", @@ -4130,10 +4288,17 @@ "temporal-polyfill": "^0.3.0", "tunnel": "0.0.6", "url-search-params-polyfill": "^8.1.1", - "uuid": "8.3.2", + "uuid": "14.0.0", "vscode-tas-client": "^0.1.84", "vsls": "^0.3.967" }, + "overrides": { + "mocha": { + "diff": "7.0.0", + "serialize-javascript": "7.0.5" + }, + "elliptic": "6.6.1" + }, "resolutions": { "string_decoder": "^1.3.0" }, diff --git a/package.nls.json b/package.nls.json index 0808791b64..bd16502abe 100644 --- a/package.nls.json +++ b/package.nls.json @@ -44,6 +44,7 @@ "githubPullRequests.fileAutoReveal.description": "Automatically reveal open files in the pull request changes tree.", "githubPullRequests.defaultDeletionMethod.selectLocalBranch.description": "When true, the option to delete the local branch will be selected by default when deleting a branch from a pull request.", "githubPullRequests.defaultDeletionMethod.selectRemote.description": "When true, the option to delete the remote will be selected by default when deleting a branch from a pull request.", + "githubPullRequests.defaultDeletionMethod.selectWorktree.description": "When true, the option to remove the associated worktree will be selected by default when deleting a branch from a pull request.", "githubPullRequests.deleteBranchAfterMerge.description": "Automatically delete the branch after merging a pull request. This setting only applies when the pull request is merged through this extension. When using merge queues, this will only delete the local branch.", "githubPullRequests.terminalLinksHandler.description": "Default handler for terminal links.", "githubPullRequests.terminalLinksHandler.github": "Create the pull request on GitHub.", @@ -182,6 +183,12 @@ "githubPullRequests.showPullRequestNumberInTree.description": "Shows the pull request number in the tree view.", "githubPullRequests.labelCreated.description": "Group of labels that you want to add to the pull request automatically. Labels that don't exist in the repository won't be added.", "githubPullRequests.labelCreated.label.description": "Each string element is the value of label that you want to add.", + "githubPullRequests.pullRequestAvatarDisplay.description": "Which icon to use in the pull request tree view", + "githubPullRequests.pullRequestAvatarDisplay.author": "Show the pull request author avatar", + "githubPullRequests.pullRequestAvatarDisplay.state": "Show the pull request type (draft or not) and state (open/closed/merged) as a colored icon", + "githubPullRequests.pullRequestAvatarDisplay.generic": "Show a GitHub icon", + "githubIssues.issueAvatarDisplay.state": "Show the issue state (open/closed) as a colored icon", + "githubIssues.issueAvatarDisplay.generic": "Show an issues icon regardless of state", "githubIssues.alwaysPromptForNewIssueRepo.description": "Enabling will always prompt which repository to create an issue in instead of basing off the current open file.", "view.github.pull.requests.name": "GitHub", "view.github.pull.request.name": "GitHub Pull Request", @@ -208,6 +215,8 @@ "command.pr.openChanges.title": "Open Changes", "command.pr.pickOnVscodeDev.title": "Checkout Pull Request on vscode.dev", "command.pr.pickOnCodespaces.title": "Checkout Pull Request on Codespaces", + "command.pr.pickInWorktree.title": "Checkout in Worktree", + "command.pr.pickInWorktreeFromDescription.title": "Checkout Pull Request in Worktree", "command.pr.exit.title": "Checkout Default Branch", "command.pr.dismissNotification.title": "Dismiss Notification", "command.pr.markAllCopilotNotificationsAsRead.title": "Dismiss All Copilot Notifications", @@ -433,10 +442,14 @@ "languageModelTools.github-pull-request_doSearch.displayName": "Execute a GitHub search", "languageModelTools.github-pull-request_doSearch.description": "Search for GitHub issues and pull requests.", "languageModelTools.github-pull-request_renderIssues.displayName": "Render issue items in a markdown table", - "languageModelTools.github-pull-request_activePullRequest.displayName": "Active Pull Request", - "languageModelTools.github-pull-request_activePullRequest.description": "Get information about the active GitHub pull request. This information includes: comments, files changed, pull request title + description, and pull request state.", + "languageModelTools.github-pull-request_currentActivePullRequest.displayName": "Active Pull Request", + "languageModelTools.github-pull-request_currentActivePullRequest.description": "Get information about the active GitHub pull request. This information includes: comments, files changed, pull request title + description, and pull request state.", "languageModelTools.github-pull-request_pullRequestStatusChecks.displayName": "Pull Request Status Checks", "languageModelTools.github-pull-request_pullRequestStatusChecks.description": "Get the status checks and CI results for a GitHub pull request.", - "languageModelTools.github-pull-request_openPullRequest.displayName": "Open Pull Request", - "languageModelTools.github-pull-request_openPullRequest.description": "Get information about the open GitHub pull request. This information includes: comments, files changed, pull request title + description, and pull request state." + "languageModelTools.github-pull-request_pullRequestInViewport.displayName": "Open Pull Request", + "languageModelTools.github-pull-request_pullRequestInViewport.description": "Get information about the open GitHub pull request. This information includes: comments, files changed, pull request title + description, and pull request state.", + "languageModelTools.github-pull-request_resolveReviewThread.displayName": "Resolve Review Thread", + "languageModelTools.github-pull-request_resolveReviewThread.description": "Resolve a review thread on the active GitHub pull request.", + "languageModelTools.github-pull-request_create_pull_request.displayName": "Create a GitHub pull request", + "languageModelTools.github-pull-request_create_pull_request.description": "Create a new GitHub pull request with a title, head branch, and optional body, base branch, and draft flag." } \ No newline at end of file diff --git a/scripts/ci/common-setup.yml b/scripts/ci/common-setup.yml index 8cb20e9f94..5d835ccc52 100644 --- a/scripts/ci/common-setup.yml +++ b/scripts/ci/common-setup.yml @@ -4,6 +4,6 @@ steps: inputs: versionSpec: "20.x" - - script: yarn install --frozen-lockfile --check-files + - script: npm ci displayName: Install dependencies retryCountOnTaskFailure: 3 diff --git a/src/@types/git.d.ts b/src/@types/git.d.ts index 718d8f4b6b..8f25bbd79f 100644 --- a/src/@types/git.d.ts +++ b/src/@types/git.d.ts @@ -76,6 +76,14 @@ export interface Remote { readonly isReadOnly: boolean; } +export interface Worktree { + readonly name: string; + readonly path: string; + readonly ref: string; + readonly main: boolean; + readonly detached: boolean; +} + export const enum Status { INDEX_MODIFIED, INDEX_ADDED, @@ -113,11 +121,14 @@ export interface Change { readonly status: Status; } +export type RepositoryKind = 'repository' | 'submodule' | 'worktree'; + export interface RepositoryState { readonly HEAD: Branch | undefined; readonly refs: Ref[]; readonly remotes: Remote[]; readonly submodules: Submodule[]; + readonly worktrees: Worktree[]; readonly rebaseCommit: Commit | undefined; readonly mergeChanges: Change[]; @@ -287,6 +298,15 @@ export interface Repository { applyStash(index?: number): Promise; popStash(index?: number): Promise; dropStash(index?: number): Promise; + + createWorktree?(options?: { path?: string; commitish?: string; branch?: string }): Promise; + deleteWorktree?(path: string, options?: { force?: boolean }): Promise; + + migrateChanges?(sourceRepositoryPath: string, options?: { confirmation?: boolean; deleteFromSource?: boolean; untracked?: boolean }): Promise; + + generateRandomBranchName?(): Promise; + + isBranchProtected?(branch?: Branch): boolean; } export interface RemoteSource { diff --git a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts index 603f8a6fcb..40babc9343 100644 --- a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts +++ b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts @@ -223,6 +223,16 @@ declare module 'vscode' { }; language: string; + /** + * Overrides for how the command is presented in the UI. + * For example, when a `cd && ` prefix is detected, + * the presentation can show only the actual command. + */ + presentationOverrides?: { + commandLine: string; + language?: string; + }; + /** * Terminal command output. Displayed when the terminal is no longer available. */ @@ -443,6 +453,11 @@ declare module 'vscode' { constructor(value: string | MarkdownString); } + export class ChatResponseInfoPart { + value: MarkdownString; + constructor(value: string | MarkdownString); + } + export class ChatResponseProgressPart2 extends ChatResponseProgressPart { value: string; task?: (progress: Progress) => Thenable; @@ -623,6 +638,15 @@ declare module 'vscode' { */ warning(message: string | MarkdownString): void; + /** + * Push an info banner to this stream. Short-hand for + * `push(new ChatResponseInfoPart(message))`. + * + * @param message An informational message + * @returns This stream. + */ + info(message: string | MarkdownString): void; + reference(value: Uri | Location | { variableName: string; value?: Uri | Location }, iconPath?: Uri | ThemeIcon | { light: Uri; dark: Uri }): void; reference2(value: Uri | Location | string | { variableName: string; value?: Uri | Location }, iconPath?: Uri | ThemeIcon | { light: Uri; dark: Uri }, options?: { status?: { description: string; kind: ChatResponseReferencePartStatusKind } }): void; @@ -829,6 +853,12 @@ declare module 'vscode' { */ readonly completionTokens: number; + /** + * The number of tokens reserved for the response. + * This is rendered specially in the UI to indicate that these tokens aren't used but are reserved. + */ + readonly outputBuffer?: number; + /** * Optional breakdown of prompt token usage by category and label. * If the percentages do not sum to 100%, the remaining will be shown as "Uncategorized". @@ -974,10 +1004,6 @@ declare module 'vscode' { readonly toolReferences?: readonly ChatLanguageModelToolReference[]; } - export interface ChatResultFeedback { - readonly unhelpfulReason?: string; - } - export namespace lm { export function fileIsIgnored(uri: Uri, token?: CancellationToken): Thenable; } @@ -1020,8 +1046,6 @@ declare module 'vscode' { readonly rawInput?: unknown; readonly chatRequestId?: string; - /** @deprecated Use {@link chatSessionResource} instead */ - readonly chatSessionId?: string; readonly chatSessionResource?: Uri; readonly chatInteractionId?: string; } @@ -1051,9 +1075,15 @@ declare module 'vscode' { } export interface ChatRequestModeInstructions { + /** set when the mode a custom agent (not built-in), to be used as identifier */ + readonly uri?: Uri; readonly name: string; readonly content: string; readonly toolReferences?: readonly ChatLanguageModelToolReference[]; readonly metadata?: Record; + /** + * Whether the mode is a builtin mode (e.g. Ask, Edit, Agent) rather than a user or extension-defined custom mode. + */ + readonly isBuiltin?: boolean; } } diff --git a/src/@types/vscode.proposed.chatParticipantPrivate.d.ts b/src/@types/vscode.proposed.chatParticipantPrivate.d.ts index 63f9ec2488..2276e22cba 100644 --- a/src/@types/vscode.proposed.chatParticipantPrivate.d.ts +++ b/src/@types/vscode.proposed.chatParticipantPrivate.d.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -// version: 14 +// version: 15 declare module 'vscode' { @@ -116,10 +116,25 @@ declare module 'vscode' { */ readonly parentRequestId?: string; + /** + * The permission level for tool auto-approval in this request. + * - `'autoApprove'`: Auto-approve all tool calls and retry on errors. + * - `'autopilot'`: Everything autoApprove does plus continues until the task is done. + */ + readonly permissionLevel?: string; + /** * Whether any hooks are enabled for this request. */ readonly hasHooksEnabled: boolean; + + /** + * When true, this request was initiated by the system (e.g. a terminal + * command completion notification) rather than by the user typing a + * message. Extensions can use this to render the prompt differently + * and skip billing. + */ + readonly isSystemInitiated?: boolean; } export enum ChatRequestEditedFileEventKind { @@ -176,10 +191,20 @@ declare module 'vscode' { */ readonly editedFileEvents?: ChatRequestEditedFileEvent[]; + /** + * The identifier of the language model that was used for this request, if known. + */ + readonly modelId?: string; + + /** + * The mode instructions that were active for this request, if any. + */ + readonly modeInstructions2?: ChatRequestModeInstructions; + /** * @hidden */ - constructor(prompt: string, command: string | undefined, references: ChatPromptReference[], participant: string, toolReferences: ChatLanguageModelToolReference[], editedFileEvents: ChatRequestEditedFileEvent[] | undefined, id: string | undefined); + constructor(prompt: string, command: string | undefined, references: ChatPromptReference[], participant: string, toolReferences: ChatLanguageModelToolReference[], editedFileEvents: ChatRequestEditedFileEvent[] | undefined, id: string | undefined, modelId: string | undefined, modeInstructions2: ChatRequestModeInstructions | undefined); } export class ChatResponseTurn2 { @@ -231,6 +256,15 @@ declare module 'vscode' { isRateLimited?: boolean; + /** + * If true, the error is an expected operational condition (e.g. user-actionable + * configuration, network connectivity, missing dependency) and should not be + * logged as a `chatAgentError` telemetry event. The error is still surfaced to + * the user. Throwing an `Error` whose `name` is `'ChatExpectedError'` from a + * chat participant handler will set this flag automatically. + */ + isExpectedError?: boolean; + level?: ChatErrorLevel; code?: string; @@ -262,8 +296,6 @@ declare module 'vscode' { export interface LanguageModelToolInvocationOptions { chatRequestId?: string; - /** @deprecated Use {@link chatSessionResource} instead */ - chatSessionId?: string; chatSessionResource?: Uri; chatInteractionId?: string; terminalCommand?: string; @@ -289,8 +321,6 @@ declare module 'vscode' { */ input: T; chatRequestId?: string; - /** @deprecated Use {@link chatSessionResource} instead */ - chatSessionId?: string; chatSessionResource?: Uri; chatInteractionId?: string; /** @@ -392,7 +422,27 @@ declare module 'vscode' { * will immediately follow up with a new request in the same conversation. */ readonly yieldRequested: boolean; + + /** + * The resource URI identifying the chat session this context belongs to. + * Available when the context is provided for title generation, summarization, + * or other session-scoped operations. Extracted from the session's history entries. + */ + readonly sessionResource?: Uri; } // #endregion + + export interface LanguageModelToolInformation { + /** + * The full reference name of this tool as used in agent definition files. + * + * For MCP tools, this is the canonical name in the format `serverShortName/toolReferenceName` + * (e.g., `github/search_issues`). This can be used to map between the tool names specified + * in agent `.md` files and the tool's internal {@link LanguageModelToolInformation.name id}. + * + * This property is only set for MCP tools. For other tool types, it is `undefined`. + */ + readonly fullReferenceName?: string; + } } diff --git a/src/@types/vscode.proposed.chatSessionsProvider.d.ts b/src/@types/vscode.proposed.chatSessionsProvider.d.ts index c3641a3706..b46ec3015d 100644 --- a/src/@types/vscode.proposed.chatSessionsProvider.d.ts +++ b/src/@types/vscode.proposed.chatSessionsProvider.d.ts @@ -35,6 +35,8 @@ declare module 'vscode' { /** * Registers a new {@link ChatSessionItemProvider chat session item provider}. * + * @deprecated Use {@linkcode createChatSessionItemController} instead. + * * To use this, also make sure to also add `chatSessions` contribution in the `package.json`. * * @param chatSessionType The type of chat session the provider is for. @@ -46,12 +48,21 @@ declare module 'vscode' { /** * Creates a new {@link ChatSessionItemController chat session item controller} with the given unique identifier. + * + * To use this, also make sure to also add `chatSessions` contribution in the `package.json`. + * + * @param chatSessionType The type of chat session the provider is for. + * @param refreshHandler The controller's {@link ChatSessionItemController.refreshHandler refresh handler}. + * + * @returns A new controller instance that can be used to manage chat session items for the given chat session type. */ - export function createChatSessionItemController(id: string, refreshHandler: (token: CancellationToken) => Thenable): ChatSessionItemController; + export function createChatSessionItemController(chatSessionType: string, refreshHandler: ChatSessionItemControllerRefreshHandler): ChatSessionItemController; } /** * Provides a list of information about chat sessions. + * + * @deprecated Use {@linkcode ChatSessionItemController} instead. */ export interface ChatSessionItemProvider { /** @@ -65,6 +76,23 @@ declare module 'vscode' { // TODO: Do we need a flag to try auth if needed? provideChatSessionItems(token: CancellationToken): ProviderResult; + /** + * @deprecated Use {@linkcode ChatSessionItemController.resolveChatSessionItem} instead. + * + * Given a chat session item fill in more data, like {@link ChatSessionItem.timing timing}, + * {@link ChatSessionItem.changes changes}, or {@link ChatSessionItem.badge badge}. + * + * The editor will call this when a chat session item becomes visible in the UI, for example + * when the user scrolls to it or when it is first rendered. + * + * @param item A chat session item currently visible in the UI. Treat this as read-only. + * @param token A cancellation token. + * @returns A new {@link ChatSessionItem} instance (or a thenable that resolves to one) with the + * same `resource` as `item` and any additional properties filled in. When no result is returned, + * the given `item` is left unchanged. + */ + resolveChatSessionItem?: (item: ChatSessionItem, token: CancellationToken) => ProviderResult; + // #region Unstable parts of API /** @@ -77,7 +105,59 @@ declare module 'vscode' { } /** - * Provides a list of information about chat sessions. + * Extension callback invoked to refresh the collection of chat session items for a {@linkcode ChatSessionItemController}. + */ + export type ChatSessionItemControllerRefreshHandler = (token: CancellationToken) => Thenable; + + export interface ChatSessionItemControllerNewItemHandlerContext { + // TODO: Use a better type but for now decrease this down to just the prompt and command since that's all we currently need. + // The problem with ChatRequest is that it has a resourceUri which is not good for this code path. + readonly request: { + readonly prompt: string; + readonly command?: string; + }; + + readonly inputState: ChatSessionInputState; + } + + /** + * Extension callback invoked when a new chat session is started. + */ + export type ChatSessionItemControllerNewItemHandler = (context: ChatSessionItemControllerNewItemHandlerContext, token: CancellationToken) => Thenable; + + /** + * Extension callback invoked to get the input state for a chat session. + * + * @param sessionResource The resource of the chat session to get the input state for. `undefined` indicates this is + * for a blank chat editor that is not yet associated with a session. + * @param context Additional context + * @param token Cancellation token. + * + * @return A new chat session input state. This should be created using {@link ChatSessionItemController.createChatSessionInputState}. + */ + export type ChatSessionControllerGetInputState = (sessionResource: Uri | undefined, context: { + /** + * The previous input state for the session. + */ + readonly previousInputState: ChatSessionInputState | undefined; + }, token: CancellationToken) => Thenable | ChatSessionInputState; + + /** + * Extension callback invoked to fork an existing chat session item managed by a {@linkcode ChatSessionItemController}. + * + * The handler should create a new session on the provider's backend and + * return the new {@link ChatSessionItem} representing the forked session. + * + * @param sessionResource The resource of the chat session being forked. + * @param request The request turn that marks the fork point. The forked session includes all turns + * upto this request turn and excludes this request turn itself. If undefined, fork the full session. + * @param token A cancellation token. + * @returns The forked session item. + */ + export type ChatSessionItemControllerForkHandler = (sessionResource: Uri, request: ChatRequestTurn2 | undefined, token: CancellationToken) => Thenable | ChatSessionItem; + + /** + * Manages chat sessions for a specific chat session type */ export interface ChatSessionItemController { readonly id: string; @@ -93,7 +173,7 @@ declare module 'vscode' { readonly items: ChatSessionItemCollection; /** - * Creates a new managed chat session item that be added to the collection. + * Creates a new managed chat session item that can be added to the collection. */ createChatSessionItem(resource: Uri, label: string): ChatSessionItem; @@ -102,12 +182,59 @@ declare module 'vscode' { * * This is also called on first load to get the initial set of items. */ - readonly refreshHandler: (token: CancellationToken) => Thenable; + readonly refreshHandler: ChatSessionItemControllerRefreshHandler; /** * Fired when an item's archived state changes. */ readonly onDidChangeChatSessionItemState: Event; + + /** + * Invoked when a new chat session is started. + * + * This allows the controller to initialize the chat session item with information from the initial request. + * + * The returned chat session is added to the collection and shown in the UI. + */ + newChatSessionItemHandler?: ChatSessionItemControllerNewItemHandler; + + /** + * Invoked when an existing chat session is forked. + * + * When both this handler and {@linkcode ChatSession.forkHandler} are registered, + * this handler takes precedence. + */ + forkHandler?: ChatSessionItemControllerForkHandler; + + /** + * Gets the input state for a chat session. + */ + getChatSessionInputState?: ChatSessionControllerGetInputState; + + /** + * Called to fill in more data on a chat session item, like {@link ChatSessionItem.timing timing}, + * {@link ChatSessionItem.changes changes}, or {@link ChatSessionItem.badge badge}. + * + * The editor will call this when a chat session item becomes visible in the UI, for example + * when the user scrolls to it or when it is first rendered. + * + * The editor will only resolve a chat session item once, unless the item is updated via + * {@link ChatSessionItemCollection.add add} or {@link ChatSessionItemCollection.replace replace}, + * which invalidates the resolve cache. + * + * The handler should update the item in the {@link ChatSessionItemController.items items collection} via + * {@link ChatSessionItemCollection.add add}. The editor picks up the updated item from + * the collection after the returned thenable resolves. + * + * @param item A chat session item currently visible in the UI. + * @param token A cancellation token. + */ + resolveChatSessionItem?: (item: ChatSessionItem, token: CancellationToken) => Thenable; + + /** + * Create a new managed ChatSessionInputState object. + */ + createChatSessionInputState(groups: ChatSessionProviderOptionGroup[]): ChatSessionInputState; } /** @@ -121,7 +248,8 @@ declare module 'vscode' { /** * Replaces the items stored by the collection. - * @param items Items to store. + * + * @param items Items to store. If two items have the same resource URI, the last one will be used. */ replace(items: readonly ChatSessionItem[]): void; @@ -136,31 +264,42 @@ declare module 'vscode' { /** * Adds the chat session item to the collection. If an item with the same resource URI already * exists, it'll be replaced. + * * @param item Item to add. */ add(item: ChatSessionItem): void; /** * Removes a single chat session item from the collection. + * * @param resource Item resource to delete. */ delete(resource: Uri): void; /** * Efficiently gets a chat session item by resource, if it exists, in the collection. + * * @param resource Item resource to get. + * * @returns The found item or undefined if it does not exist. */ get(resource: Uri): ChatSessionItem | undefined; } + /** + * A chat session show in the UI. + * + * This should be created by calling a {@link ChatSessionItemController.createChatSessionItem createChatSessionItem} + * method on the controller. The item can then be added to the controller's {@link ChatSessionItemController.items items collection} + * to show it in the UI. + */ export interface ChatSessionItem { /** * The resource associated with the chat session. * * This is uniquely identifies the chat session and is used to open the chat session. */ - resource: Uri; + readonly resource: Uri; /** * Human readable name of the session shown in the UI @@ -236,7 +375,7 @@ declare module 'vscode' { /** * Statistics about the chat session. */ - changes?: readonly ChatSessionChangedFile[] | readonly ChatSessionChangedFile2[]; + changes?: readonly ChatSessionChangedFile[]; /** * Arbitrary metadata for the chat session. Can be anything, but must be JSON-stringifyable. @@ -247,30 +386,6 @@ declare module 'vscode' { } export class ChatSessionChangedFile { - /** - * URI of the file. - */ - modifiedUri: Uri; - - /** - * File opened when the user takes the 'compare' action. - */ - originalUri?: Uri; - - /** - * Number of insertions made during the session. - */ - insertions: number; - - /** - * Number of deletions made during the session. - */ - deletions: number; - - constructor(modifiedUri: Uri, insertions: number, deletions: number, originalUri?: Uri); - } - - export class ChatSessionChangedFile2 { /** * URI of the file. */ @@ -300,6 +415,15 @@ declare module 'vscode' { } export interface ChatSession { + /** + * An optional title for the chat session. + * + * When provided, this title is used as the display name for the session + * (e.g. in the editor tab). When not provided, the title defaults to + * the first user message in the session history. + */ + readonly title?: string; + /** * The full history of the session * @@ -335,7 +459,24 @@ declare module 'vscode' { */ // TODO: Should we introduce our own type for `ChatRequestHandler` since not all field apply to chat sessions? // TODO: Revisit this to align with code. + // TODO: pass in options? readonly requestHandler: ChatRequestHandler | undefined; + + /** + * Handles a request to fork the session. + * + * The handler should create a new session on the provider's backend and + * return the new {@link ChatSessionItem} representing the forked session. + * + * @deprecated Use {@linkcode ChatSessionItemController.forkHandler} instead. This remains supported for backwards compatibility. + * + * @param sessionResource The resource of the chat session being forked. + * @param request The request turn that marks the fork point. The forked session includes all turns + * upto this request turn and excludes this request turn itself. If undefined, fork the full session. + * @param token A cancellation token. + * @returns The forked session item. + */ + readonly forkHandler?: ChatSessionItemControllerForkHandler; } /** @@ -367,11 +508,15 @@ declare module 'vscode' { */ export interface ChatSessionContentProvider { /** + * @deprecated + * * Event that the provider can fire to signal that the options for a chat session have changed. */ readonly onDidChangeChatSessionOptions?: Event; /** + * @deprecated + * * Event that the provider can fire to signal that the available provider options have changed. * * When fired, the editor will re-query {@link ChatSessionContentProvider.provideChatSessionProviderOptions} @@ -386,12 +531,17 @@ declare module 'vscode' { * * @param resource The URI of the chat session to resolve. * @param token A cancellation token that can be used to cancel the operation. + * @param context Additional context for the chat session. * * @return The {@link ChatSession chat session} associated with the given URI. */ - provideChatSessionContent(resource: Uri, token: CancellationToken): Thenable | ChatSession; + provideChatSessionContent(resource: Uri, token: CancellationToken, context: { + readonly inputState: ChatSessionInputState; + }): Thenable | ChatSession; /** + * @deprecated + * * @param resource Identifier of the chat session being updated. * @param updates Collection of option identifiers and their new values. Only the options that changed are included. * @param token A cancellation token that can be used to cancel the notification if the session is disposed. @@ -399,10 +549,11 @@ declare module 'vscode' { provideHandleOptionsChange?(resource: Uri, updates: ReadonlyArray, token: CancellationToken): void; /** + * @deprecated + * * Called as soon as you register (call me once) - * @param token */ - provideChatSessionProviderOptions?(token: CancellationToken): Thenable; + provideChatSessionProviderOptions?(token: CancellationToken): Thenable; } export interface ChatSessionOptionUpdate { @@ -423,10 +574,11 @@ declare module 'vscode' { * * @param scheme The uri-scheme to register for. This must be unique. * @param provider The provider to register. + * @param defaultChatParticipant The default {@link ChatParticipant chat participant} used in sessions provided by this provider. * * @returns A disposable that unregisters the provider when disposed. */ - export function registerChatSessionContentProvider(scheme: string, provider: ChatSessionContentProvider, chatParticipant: ChatParticipant, capabilities?: ChatSessionCapabilities): Disposable; + export function registerChatSessionContentProvider(scheme: string, provider: ChatSessionContentProvider, defaultChatParticipant: ChatParticipant, capabilities?: ChatSessionCapabilities): Disposable; } export interface ChatContext { @@ -435,7 +587,22 @@ declare module 'vscode' { export interface ChatSessionContext { readonly chatSessionItem: ChatSessionItem; // Maps to URI of chat session editor (could be 'untitled-1', etc..) + + /** @deprecated This will be removed along with the concept of `untitled-` sessions. */ readonly isUntitled: boolean; + + /** + * The initial option selections for the session, provided with the first request. + * Contains the options the user selected (or defaults) before the session was created. + * + * @deprecated Use `inputState` instead + */ + readonly initialSessionOptions?: ReadonlyArray<{ optionId: string; value: string | ChatSessionProviderOptionItem }>; + + /** + * The current input state of the chat session. + */ + readonly inputState: ChatSessionInputState; } export interface ChatSessionCapabilities { @@ -481,6 +648,16 @@ declare module 'vscode' { * Only one item per option group should be marked as default. */ readonly default?: boolean; + + /** + * Optional slash-command alias (without leading `/`) that selects this option + * when the user submits `/`. Does not send a chat request; only + * updates the selection so the next prompt runs with this option active. + * + * Scoped to chat sessions owned by the contributing provider. Names must be + * unique across the provider's groups; on conflict, the first declared wins. + */ + readonly slashCommand?: string; } /** @@ -502,10 +679,15 @@ declare module 'vscode' { */ readonly description?: string; + /** + * The currently selected option for this group. This must be one of the items provided in the `items` array. + */ + readonly selected?: ChatSessionProviderOptionItem; + /** * The selectable items within this option group. */ - readonly items: ChatSessionProviderOptionItem[]; + readonly items: readonly ChatSessionProviderOptionItem[]; /** * A context key expression that controls when this option group picker is visible. @@ -517,33 +699,38 @@ declare module 'vscode' { */ readonly when?: string; - /** - * When true, displays a searchable QuickPick with a "See more..." option. - * Recommended for option groups with additional async items (e.g., repositories). - */ - readonly searchable?: boolean; - /** * An icon for the option group shown in UI. */ readonly icon?: ThemeIcon; /** - * Handler for dynamic search when `searchable` is true. - * Called when the user types in the searchable QuickPick or clicks "See more..." to load additional items. + * Optional commands. * - * @param query The search query entered by the user. Empty string for initial load. - * @param token A cancellation token. - * @returns Additional items to display in the searchable QuickPick. + * These commands will be displayed at the bottom of the group. + * + * For extensions using the legacy `commands` API, these commands are passed the sessionResource as the first argument. + * + * For extensions that use the new `provideChatSessionInputState` API, these commands are passed a context object + * `{ inputState: ChatSessionInputState; sessionResource: Uri | undefined }` that they can use to determine which session and options they are being invoked for. */ - readonly onSearch?: (query: string, token: CancellationToken) => Thenable; + readonly commands?: Command[]; /** - * Optional commands. + * Optional kind that hints how this option group should be presented in the UI. * - * These commands will be displayed at the bottom of the group. + * - `'permissions'`: The group represents tool-approval permissions for the session. + * The editor will not render this group as its own picker. Instead, its items + * replace the built-in items in the chat permission picker for the session, + * and the user's selection is reported back through the standard + * {@link ChatSessionContentProvider.handleChatSessionOptionsChange} flow. + * At most one option group per provider may use this kind; if more than one is + * declared, the first one (in declaration order) is used. The group is invisible + * if the chat permission picker itself is hidden by other `when` clauses. + * + * When omitted, the group is rendered as a standalone picker as usual. */ - readonly commands?: Command[]; + readonly kind?: 'permissions'; } export interface ChatSessionProviderOptions { @@ -551,6 +738,44 @@ declare module 'vscode' { * Provider-defined option groups (0-2 groups supported). * Examples: models picker, sub-agents picker, etc. */ - optionGroups?: ChatSessionProviderOptionGroup[]; + readonly optionGroups?: readonly ChatSessionProviderOptionGroup[]; + + /** + * The set of default options used for new chat sessions, provided as key-value pairs. + * + * Keys correspond to option group IDs (e.g., 'models', 'subagents'). + */ + readonly newSessionOptions?: Record; + } + + /** + * Represents the current state of user inputs for a chat session. + */ + export interface ChatSessionInputState { + /** + * Fired when the input state is disposed. + */ + readonly onDidDispose: Event; + + /** + * Fired when the input state is changed by the user. + * + * Move to controller? + */ + readonly onDidChange: Event; + + /** + * The resource associated with this chat session. + * + * This is `undefined` for chat sessions that have not yet started. + */ + readonly sessionResource: Uri | undefined; + + /** + * The groups of options to show in the UI for user input. + * + * To update the groups you must replace the entire `groups` array with a new array. + */ + groups: readonly ChatSessionProviderOptionGroup[]; } } diff --git a/src/api/api.d.ts b/src/api/api.d.ts index 011cbd9cfa..1889c05fa2 100644 --- a/src/api/api.d.ts +++ b/src/api/api.d.ts @@ -53,6 +53,14 @@ export interface Remote { readonly isReadOnly: boolean; } +export interface Worktree { + readonly name: string; + readonly path: string; + readonly ref: string; + readonly main: boolean; + readonly detached: boolean; +} + export { Status } from './api1'; export interface Change { @@ -71,6 +79,7 @@ export interface RepositoryState { readonly HEAD: Branch | undefined; readonly remotes: Remote[]; readonly submodules: Submodule[]; + readonly worktrees?: Worktree[]; readonly rebaseCommit: Commit | undefined; readonly mergeChanges: Change[]; @@ -209,6 +218,9 @@ export interface Repository { add(paths: string[]): Promise; merge(ref: string): Promise; mergeAbort(): Promise; + + createWorktree?(options?: { path?: string; commitish?: string; branch?: string }): Promise; + deleteWorktree?(path: string, options?: { force?: boolean }): Promise; } /** @@ -244,7 +256,7 @@ export interface IGit { } export interface TitleAndDescriptionProvider { - provideTitleAndDescription(context: { commitMessages: string[], patches: string[] | { patch: string, fileUri: string, previousFileUri?: string }[], issues?: { reference: string, content: string }[], template?: string }, token: CancellationToken): Promise<{ title: string, description?: string } | undefined>; + provideTitleAndDescription(context: { commitMessages: string[], patches: string[] | { patch: string, fileUri: string, previousFileUri?: string }[], issues?: { reference: string, content: string }[], template?: string, compareBranch?: string }, token: CancellationToken): Promise<{ title: string, description?: string } | undefined>; } export interface ReviewerComments { diff --git a/src/commands.ts b/src/commands.ts index 88e3784b06..c48ddda7ab 100644 --- a/src/commands.ts +++ b/src/commands.ts @@ -32,6 +32,7 @@ import { chooseItem } from './github/quickPicks'; import { RepositoriesManager } from './github/repositoriesManager'; import { codespacesPrLink, getIssuesUrl, getPullsUrl, isInCodespaces, ISSUE_OR_URL_EXPRESSION, parseIssueExpressionOutput, vscodeDevPrLink } from './github/utils'; import { BaseContext, OverviewContext } from './github/views'; +import { checkoutPRInWorktree } from './github/worktree'; import { IssueChatContextItem } from './lm/issueContextProvider'; import { PRChatContextItem } from './lm/pullRequestContextProvider'; import { isNotificationTreeItem, NotificationTreeItem } from './notifications/notificationItem'; @@ -825,6 +826,47 @@ export function registerCommands( ), ); + context.subscriptions.push( + vscode.commands.registerCommand('pr.pickInWorktree', async (pr: PRNode | PullRequestModel | unknown) => { + if (pr === undefined) { + Logger.error('Unexpectedly received undefined when picking a PR for worktree checkout.', logId); + return vscode.window.showErrorMessage(vscode.l10n.t('No pull request was selected to checkout, please try again.')); + } + + let pullRequestModel: PullRequestModel; + let repository: Repository | undefined; + + if (pr instanceof PRNode) { + pullRequestModel = pr.pullRequestModel; + repository = pr.repository; + } else if (pr instanceof PullRequestModel) { + pullRequestModel = pr; + } else { + Logger.error('Unexpectedly received unknown type when picking a PR for worktree checkout.', logId); + return vscode.window.showErrorMessage(vscode.l10n.t('No pull request was selected to checkout, please try again.')); + } + + // Get the folder manager to access the repository + const folderManager = reposManager.getManagerForIssueModel(pullRequestModel); + if (!folderManager) { + return vscode.window.showErrorMessage(vscode.l10n.t('Unable to find repository for this pull request.')); + } + + return checkoutPRInWorktree(telemetry, folderManager, pullRequestModel, repository); + }), + ); + + context.subscriptions.push(vscode.commands.registerCommand('pr.pickInWorktreeFromDescription', async (ctx: BaseContext | undefined) => { + if (!ctx) { + return vscode.window.showErrorMessage(vscode.l10n.t('No pull request context provided for checkout.')); + } + const resolved = await resolvePr(ctx); + if (!resolved) { + return vscode.window.showErrorMessage(vscode.l10n.t('Unable to resolve pull request for checkout.')); + } + return checkoutPRInWorktree(telemetry, resolved.folderManager, resolved.pr, undefined); + })); + context.subscriptions.push(vscode.commands.registerCommand('pr.checkoutOnVscodeDevFromDescription', async (context: BaseContext | undefined) => { if (!context) { return vscode.window.showErrorMessage(vscode.l10n.t('No pull request context provided for checkout.')); @@ -1848,9 +1890,31 @@ ${contents} const isThread = GHPRCommentThread.is(comment); const commentThread = isThread ? comment : comment.parent; - const commentBody = isThread ? comment.comments[0].body : comment.body; + const firstComment = isThread ? comment.comments[0] : comment; commentThread.collapsibleState = vscode.CommentThreadCollapsibleState.Collapsed; - const message = commentBody instanceof vscode.MarkdownString ? commentBody.value : commentBody; + let commentBody: string; + let filePath: string | undefined; + if (firstComment instanceof GHPRComment) { + commentBody = firstComment.rawComment.body; + filePath = firstComment.rawComment.path; + } else { + commentBody = firstComment.body instanceof vscode.MarkdownString ? firstComment.body.value : firstComment.body; + filePath = undefined; + } + const range = commentThread.range; + let message: string; + if (filePath && range) { + const startLine = range.start.line + 1; + const endLine = range.end.line + 1; + const lineRef = startLine === endLine + ? vscode.l10n.t('line {0}', startLine) + : vscode.l10n.t('lines {0}-{1}', startLine, endLine); + message = vscode.l10n.t('There is a code review comment for file {0} at {1}:\n{2}', filePath, lineRef, commentBody); + } else if (filePath) { + message = vscode.l10n.t('There is a code review comment for file {0}:\n{1}', filePath, commentBody); + } else { + message = commentBody; + } if (isThread) { // For threads, open the Chat view instead of inline chat @@ -2084,7 +2148,7 @@ ${contents} const tokenSource = new vscode.CancellationTokenSource(); const result = await provider.provider.provideTitleAndDescription( - { commitMessages, patches, issues, template }, + { commitMessages, patches, issues, template, compareBranch: args.compareBranch }, tokenSource.token, ); diff --git a/src/common/settingKeys.ts b/src/common/settingKeys.ts index 0b35cd539f..ba0654cc23 100644 --- a/src/common/settingKeys.ts +++ b/src/common/settingKeys.ts @@ -36,6 +36,7 @@ export const DEFAULT_MERGE_METHOD = 'defaultMergeMethod'; export const DEFAULT_DELETION_METHOD = 'defaultDeletionMethod'; export const SELECT_LOCAL_BRANCH = 'selectLocalBranch'; export const SELECT_REMOTE = 'selectRemote'; +export const SELECT_WORKTREE = 'selectWorktree'; export const DELETE_BRANCH_AFTER_MERGE = 'deleteBranchAfterMerge'; export const REMOTES = 'remotes'; export const PULL_PR_BRANCH_BEFORE_CHECKOUT = 'pullPullRequestBranchBeforeCheckout'; @@ -72,6 +73,10 @@ export const EXPERIMENTAL_NOTIFICATIONS_SCORE = 'experimental.notificationsScore export const WEBVIEW_REFRESH_INTERVAL = 'webviewRefreshInterval'; export const DEV_MODE = 'devMode'; +export const PULL_REQUEST_AVATAR_DISPLAY = 'pullRequestAvatarDisplay'; +export type IssueAvatarDisplay = 'author' | 'assignee' | 'state' | 'generic'; +export type PullRequestAvatarDisplay = 'author' | 'state' | 'generic'; + // git export const GIT = 'git'; export const PULL_BEFORE_CHECKOUT = 'pullBeforeCheckout'; diff --git a/src/common/utils.ts b/src/common/utils.ts index 0f36f1202b..10ee3c7005 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -1009,9 +1009,183 @@ export function escapeRegExp(string: string) { return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } +export function escapeHtmlAttr(value: string): string { + const escapedCharacters: Record = { + '&': '&', + '"': '"', + '\'': ''', + '<': '<', + '>': '>', + }; + + return value.replace(/[&"'<>]/g, (char) => escapedCharacters[char]); +} + export function truncate(value: string, maxLength: number, suffix = '...'): string { if (value.length <= maxLength) { return value; } return `${value.substr(0, maxLength)}${suffix}`; -} \ No newline at end of file +} + +/** + * Metadata extracted from code reference link data attributes. + * This interface defines the contract between the extension (which creates the attributes) + * and the webview (which reads them). + */ +export interface CodeReferenceLinkMetadata { + localFile: string; + startLine: number; + endLine: number; + linkType: 'blob' | 'diff'; + href: string; +} + +/** + * Extracts code reference link metadata from an anchor element's data attributes. + * Returns null if any required attributes are missing. + */ +export function extractCodeReferenceLinkMetadata(anchor: Element): CodeReferenceLinkMetadata | null { + const localFile = anchor.getAttribute('data-local-file'); + const startLine = anchor.getAttribute('data-start-line'); + const endLine = anchor.getAttribute('data-end-line'); + const linkType = anchor.getAttribute('data-link-type'); + const href = anchor.getAttribute('href'); + + if (!localFile || !startLine || !endLine || !linkType || !href) { + return null; + } + + return { + localFile, + startLine: parseInt(startLine), + endLine: parseInt(endLine), + linkType: linkType as 'blob' | 'diff', + href + }; +} + +/** + * Process GitHub blob permalinks in HTML and add data attributes for local file handling. + * Finds blob permalinks (e.g., /blob/[sha]/file.ts#L10), checks if files exist locally, + * and adds data attributes to enable clicking to open local files. + * Supports links from any repository owner to work across forks. + * + * @param bodyHTML - The HTML content to process + * @param repoName - GitHub repository name + * @param authority - Git protocol URL authority (e.g., 'github.com') + * @param fileExistsCheck - Async function that checks if a file exists locally given its relative path + * @returns Promise resolving to processed HTML + */ +export async function processPermalinks( + bodyHTML: string, + repoName: string, + authority: string, + fileExistsCheck: (filePath: string) => Promise +): Promise { + try { + const escapedRepoName = escapeRegExp(repoName); + const escapedAuthority = escapeRegExp(authority); + + // Process blob permalinks (exclude already processed links) + // Allow any owner to support links across forks + const blobPattern = new RegExp( + `]*data-permalink-processed)([^>]*?href="https?:\/\/${escapedAuthority}\/[^\/]+\/${escapedRepoName}\/blob\/[0-9a-f]{40}\/(?[^"#]+)#L(?\\d+)(?:-L(?\\d+))?"[^>]*?)>(?[^<]*?)<\/a>`, + 'g' + ); + + return await stringReplaceAsync(bodyHTML, blobPattern, async ( + fullMatch: string, + attributes: string, + filePath: string, + startLine: string, + endLine: string | undefined, + linkText: string + ) => { + try { + // Extract the original URL from attributes + const hrefMatch = attributes.match(/href="([^"]+)"/); + const originalUrl = hrefMatch ? hrefMatch[1] : ''; + + // Check if file exists locally + const exists = await fileExistsCheck(filePath); + if (exists) { + // File exists - add data attributes for local handling and "(view on GitHub)" suffix + const endLineValue = endLine || startLine; + const escapedFilePath = escapeHtmlAttr(filePath); + return `${linkText} (view on GitHub)`; + } + } catch (error) { + // File doesn't exist or check failed - keep original link + } + return fullMatch; + }); + } catch (error) { + // Return original HTML if processing fails + return bodyHTML; + } +} + +/** + * Process GitHub diff permalinks in HTML and add data attributes for local file handling. + * Finds diff permalinks (e.g., /pull/123/files#diff-[hash]R10), maps hashes to filenames, + * and adds data attributes to enable clicking to open diff views. + * + * @param bodyHTML - The HTML content to process + * @param repoOwner - GitHub repository owner + * @param repoName - GitHub repository name + * @param authority - Git protocol URL authority (e.g., 'github.com') + * @param hashMap - Map of diff hashes to file paths + * @param prNumber - Pull request number + * @returns Promise resolving to processed HTML + */ +export async function processDiffLinks( + bodyHTML: string, + repoOwner: string, + repoName: string, + authority: string, + hashMap: Record, + prNumber: number +): Promise { + try { + const escapedRepoName = escapeRegExp(repoName); + const escapedRepoOwner = escapeRegExp(repoOwner); + const escapedAuthority = escapeRegExp(authority); + + const diffPattern = new RegExp( + `]*data-permalink-processed)([^>]*?href="https?:\/\/${escapedAuthority}\/${escapedRepoOwner}\/${escapedRepoName}\/pull\/${prNumber}\/(?:files|changes)#diff-(?[a-f0-9]{64})(?:R(?\\d+)(?:-R(?\\d+))?)?"[^>]*?)>(?[^<]*?)<\/a>`, + 'g' + ); + + return await stringReplaceAsync(bodyHTML, diffPattern, async ( + fullMatch: string, + attributes: string, + diffHash: string, + startLine: string | undefined, + endLine: string | undefined, + linkText: string + ) => { + try { + // Extract the original URL from attributes + const hrefMatch = attributes.match(/href="([^"]+)"/); + const originalUrl = hrefMatch ? hrefMatch[1] : ''; + + // Look up filename from hash + const fileName = hashMap[diffHash]; + if (fileName) { + // Hash found - add data attributes for diff handling and "(view on GitHub)" suffix + const startLineValue = startLine || '1'; + const endLineValue = endLine || startLineValue; + const escapedFileName = escapeHtmlAttr(fileName); + return `${linkText} (view on GitHub)`; + } + } catch (error) { + // Failed to process - keep original link + } + return fullMatch; + }); + } catch (error) { + // Return original HTML if processing fails + return bodyHTML; + } +} diff --git a/src/common/webview.ts b/src/common/webview.ts index f887fd349b..a41fab61e4 100644 --- a/src/common/webview.ts +++ b/src/common/webview.ts @@ -74,6 +74,7 @@ export class WebviewBase extends Disposable { seq: originalMessage.req, res: message, }; + await this._waitForReady; this._webview?.postMessage(reply); } @@ -82,6 +83,7 @@ export class WebviewBase extends Disposable { seq: originalMessage?.req, err: error, }; + await this._waitForReady; this._webview?.postMessage(reply); } } diff --git a/src/gitProviders/vslsguest.ts b/src/gitProviders/vslsguest.ts index fd823781af..aa4370d9be 100644 --- a/src/gitProviders/vslsguest.ts +++ b/src/gitProviders/vslsguest.ts @@ -6,7 +6,7 @@ import * as vscode from 'vscode'; import { LiveShare, SharedServiceProxy } from 'vsls/vscode.js'; -import { Branch, Change, Commit, Ref, Remote, RepositoryState, Submodule } from '../@types/git'; +import { Branch, Change, Commit, Ref, Remote, RepositoryState, Submodule, Worktree } from '../@types/git'; import { IGit, Repository } from '../api/api'; import { Disposable } from '../common/lifecycle'; import { @@ -138,6 +138,7 @@ class LiveShareRepositoryState implements RepositoryState { HEAD: Branch | undefined; remotes: Remote[]; submodules: Submodule[] = []; + worktrees: Worktree[] = []; rebaseCommit: Commit | undefined; mergeChanges: Change[] = []; indexChanges: Change[] = []; diff --git a/src/github/copilotRemoteAgent.ts b/src/github/copilotRemoteAgent.ts index bc2c7ce9e4..9f3c987aee 100644 --- a/src/github/copilotRemoteAgent.ts +++ b/src/github/copilotRemoteAgent.ts @@ -4,24 +4,15 @@ *--------------------------------------------------------------------------------------------*/ import * as vscode from 'vscode'; -import { RepoInfo } from './common'; -import { CopilotApi, getCopilotApi } from './copilotApi'; import { CopilotPRWatcher } from './copilotPrWatcher'; import { CredentialStore } from './credentials'; -import { FolderRepositoryManager } from './folderRepositoryManager'; -import { GitHubRepository } from './githubRepository'; import { RepositoriesManager } from './repositoriesManager'; -import { CopilotRemoteAgentConfig } from '../common/config'; -import { COPILOT_CLOUD_AGENT, COPILOT_LOGINS } from '../common/copilot'; +import { COPILOT_CLOUD_AGENT } from '../common/copilot'; import { Disposable } from '../common/lifecycle'; -import Logger from '../common/logger'; -import { GitHubRemote } from '../common/remote'; import { ITelemetry } from '../common/telemetry'; import { PrsTreeModel } from '../view/prsTreeModel'; -const PREFERRED_GITHUB_CODING_AGENT_REMOTE_WORKSPACE_KEY = 'PREFERRED_GITHUB_CODING_AGENT_REMOTE'; - export namespace SessionIdForPr { const prefix = 'pull-session-by-index'; @@ -59,113 +50,4 @@ export class CopilotRemoteAgentManager extends Disposable { this._register(new CopilotPRWatcher(this.repositoriesManager, this.prsTreeModel)); } - private _copilotApiPromise: Promise | undefined; - private get copilotApi(): Promise { - if (!this._copilotApiPromise) { - this._copilotApiPromise = this.initializeCopilotApi(); - } - return this._copilotApiPromise; - } - - private async initializeCopilotApi(): Promise { - return await getCopilotApi(this.credentialStore, this.telemetry); - } - - async isAssignable(): Promise { - const setCachedResult = (b: boolean) => { - this._isAssignable = b; - return b; - }; - - if (this._isAssignable !== undefined) { - return this._isAssignable; - } - - const repoInfo = await this.repoInfo(); - if (!repoInfo) { - return setCachedResult(false); - } - - const { fm } = repoInfo; - - try { - // Ensure assignable users are loaded - await fm.getAssignableUsers(); - const allAssignableUsers = fm.getAllAssignableUsers(); - - if (!allAssignableUsers) { - return setCachedResult(false); - } - return setCachedResult(allAssignableUsers.some(user => COPILOT_LOGINS.includes(user.login))); - } catch (error) { - // If there's an error fetching assignable users, assume not assignable - return setCachedResult(false); - } - } - - async isAvailable(): Promise { - // Check if the manager is enabled, copilot API is available, and it's assignable - if (!CopilotRemoteAgentConfig.getEnabled()) { - return false; - } - - if (!this.credentialStore.isAnyAuthenticated()) { - // If not signed in, then we optimistically say it's available. - return true; - } - - const repoInfo = await this.repoInfo(); - if (!repoInfo) { - return false; - } - - const copilotApi = await this.copilotApi; - if (!copilotApi) { - return false; - } - - return await this.isAssignable(); - } - - private firstFolderManager(): FolderRepositoryManager | undefined { - if (!this.repositoriesManager.folderManagers.length) { - return; - } - return this.repositoriesManager.folderManagers[0]; - } - - async repoInfo(fm?: FolderRepositoryManager): Promise { - fm = fm || this.firstFolderManager(); - const repository = fm?.repository; - const ghRepository = fm?.gitHubRepositories.find(repo => repo.remote instanceof GitHubRemote) as GitHubRepository | undefined; - if (!fm || !repository || !ghRepository) { - return; - } - const baseRef = repository.state.HEAD?.name; // TODO: Consider edge cases - const preferredRemoteName = this.context.workspaceState.get(PREFERRED_GITHUB_CODING_AGENT_REMOTE_WORKSPACE_KEY); - const ghRemotes = await fm.getGitHubRemotes(); - if (!ghRemotes || ghRemotes.length === 0) { - return; - } - - const remote = - preferredRemoteName - ? ghRemotes.find(remote => remote.remoteName === preferredRemoteName) // Cached preferred value - : (ghRemotes.find(remote => remote.remoteName === 'origin') || ghRemotes[0]); // Fallback to the first remote - - if (!remote) { - Logger.error(`no valid remotes for coding agent`, CopilotRemoteAgentManager.ID); - // Clear preference, something is wrong - this.context.workspaceState.update(PREFERRED_GITHUB_CODING_AGENT_REMOTE_WORKSPACE_KEY, undefined); - return; - } - - // Extract repo data from target remote - const { owner, repositoryName: repo } = remote; - if (!owner || !repo || !baseRef || !repository) { - return; - } - return { owner, repo, baseRef, remote, repository, ghRepository, fm }; - } - } \ No newline at end of file diff --git a/src/github/createPRViewProvider.ts b/src/github/createPRViewProvider.ts index d031cdb98a..f0be3b4f33 100644 --- a/src/github/createPRViewProvider.ts +++ b/src/github/createPRViewProvider.ts @@ -10,12 +10,12 @@ import { PullRequestDefaults, titleAndBodyFrom, } from './folderRepositoryManager'; -import { GitHubRepository } from './githubRepository'; +import { GitHubRepository, isRateLimitError, ViewerPermission } from './githubRepository'; import { IAccount, ILabel, IMilestone, IProject, isITeam, ITeam, MergeMethod, RepoAccessAndMergeMethods } from './interface'; import { BaseBranchMetadata, PullRequestGitHelper } from './pullRequestGitHelper'; import { PullRequestModel } from './pullRequestModel'; import { getDefaultMergeMethod } from './pullRequestOverview'; -import { branchPicks, getAssigneesQuickPickItems, getLabelOptions, getMilestoneFromQuickPick, getProjectFromQuickPick, reviewersQuickPick } from './quickPicks'; +import { branchPicks, cachedBranchPicks, getAssigneesQuickPickItems, getLabelOptions, getMilestoneFromQuickPick, getProjectFromQuickPick, reviewersQuickPick } from './quickPicks'; import { ISSUE_EXPRESSION, parseIssueExpressionOutput, variableSubstitution } from './utils'; import { ChangeTemplateReply, DisplayLabel, PreReviewState } from './views'; import { RemoteInfo } from '../../common/types'; @@ -129,8 +129,11 @@ export abstract class BaseCreatePullRequestViewProvider; - protected async getMergeConfiguration(owner: string, name: string, refetch: boolean = false): Promise { + protected async getMergeConfiguration(owner: string, name: string, refetch: boolean = false): Promise { const repo = await this._folderRepositoryManager.createGitHubRepositoryFromOwnerName(owner, name); + if (!repo) { + return undefined; + } return repo.getRepoAccessAndMergeMethods(refetch); } @@ -211,17 +214,51 @@ export abstract class BaseCreatePullRequestViewProvider(DEFAULT_CREATE_OPTION, 'lastUsed'); const lastCreateMethod: { autoMerge: boolean, mergeMethod: MergeMethod | undefined, isDraft: boolean } | undefined = this._folderRepositoryManager.context.workspaceState.get<{ autoMerge: boolean, mergeMethod: MergeMethod, isDraft } | undefined>(PREVIOUS_CREATE_METHOD, undefined); - const repoMergeMethod = getDefaultMergeMethod(mergeConfiguration.mergeMethodsAvailability); + const repoMergeMethod = mergeConfiguration ? getDefaultMergeMethod(mergeConfiguration.mergeMethodsAvailability) : 'merge' as MergeMethod; // default values are for 'create' let defaultMergeMethod: MergeMethod = repoMergeMethod; @@ -232,11 +269,11 @@ export abstract class BaseCreatePullRequestViewProvider { - return `${name.charAt(0).toUpperCase()}${name.slice(1)}`; + const nameWithSpaces = name.replace(/[-_]/g, ' '); + return `${nameWithSpaces.charAt(0).toUpperCase()}${nameWithSpaces.slice(1)}`; }; // If branchName is selected, use the branch name as the title @@ -774,11 +812,12 @@ export class CreatePullRequestViewProvider extends BaseCreatePullRequestViewProv } // Set description - if (pullRequestTemplate && lastCommit?.body) { + // Match GitHub.com behavior: only use the commit body when there is a single commit. + if (pullRequestTemplate && lastCommit?.body && !useBranchName) { description = `${lastCommit.body}\n\n${pullRequestTemplate}`; } else if (pullRequestTemplate) { description = pullRequestTemplate; - } else if (lastCommit?.body && (this._pullRequestDefaults.base !== compareBranch.name)) { + } else if (lastCommit?.body && !useBranchName && (this._pullRequestDefaults.base !== compareBranch.name)) { description = lastCommit.body; } @@ -975,9 +1014,22 @@ Don't forget to commit your template file to the repository so that it can be us const params = await super.getCreateParams(); this.model.baseOwner = params.defaultBaseRemote!.owner; this.model.baseBranch = params.defaultBaseBranch!; + // Pre-fetch branches so they're cached when the user opens the branch picker + this.prefetchBranches(params.defaultBaseRemote!); return params; } + private prefetchBranches(baseRemote: RemoteInfo): void { + const githubRepository = this._folderRepositoryManager.findRepo( + repo => repo.remote.owner === baseRemote.owner && repo.remote.repositoryName === baseRemote.repositoryName, + ); + if (githubRepository) { + githubRepository.listBranches(baseRemote.owner, baseRemote.repositoryName, undefined).catch(e => { + Logger.debug(`Pre-fetching branches failed: ${e}`, CreatePullRequestViewProvider.ID); + }); + } + } + private async remotePicks(isBase: boolean): Promise<(vscode.QuickPickItem & { remote?: RemoteInfo })[]> { const remotes = isBase ? await this._folderRepositoryManager.getActiveGitHubRemotes(await this._folderRepositoryManager.getGitHubRemotes()) : this._folderRepositoryManager.gitHubRepositories.map(repo => repo.remote); @@ -994,7 +1046,18 @@ Don't forget to commit your template file to the repository so that it can be us } private async processRemoteAndBranchResult(githubRepository: GitHubRepository, result: { remote: RemoteInfo, branch: string }, isBase: boolean) { - const [defaultBranch, viewerPermission] = await Promise.all([githubRepository.getDefaultBranch(), githubRepository.getViewerPermission()]); + let viewerPermission: ViewerPermission; + try { + viewerPermission = await githubRepository.getViewerPermission(); + } catch (e) { + if (isRateLimitError(e)) { + vscode.window.showErrorMessage(vscode.l10n.t('GitHub API rate limit exceeded. Please wait and try again.')); + viewerPermission = ViewerPermission.Unknown; + } else { + throw e; + } + } + const defaultBranch = await githubRepository.getDefaultBranch(); commands.setContext(contexts.CREATE_PR_PERMISSIONS, viewerPermission); let chooseResult: ChooseBaseRemoteAndBranchResult | ChooseCompareRemoteAndBranchResult; @@ -1013,7 +1076,7 @@ Don't forget to commit your template file to the repository so that it can be us this.getTitleAndDescription(compareBranch, this.model.baseBranch), this._folderRepositoryManager.mergeQueueMethodForBranch(this.model.baseBranch, this.model.baseOwner, this.model.repositoryName)]); let autoMergeDefault = false; - if (mergeConfiguration.viewerCanAutoMerge) { + if (mergeConfiguration?.viewerCanAutoMerge) { const defaultCreateOption = vscode.workspace.getConfiguration(PR_SETTINGS_NAMESPACE).get<'lastUsed' | 'create' | 'createDraft' | 'createAutoMerge'>(DEFAULT_CREATE_OPTION, 'lastUsed'); const lastCreateMethod: { autoMerge: boolean, mergeMethod: MergeMethod | undefined, isDraft: boolean } | undefined = this._folderRepositoryManager.context.workspaceState.get<{ autoMerge: boolean, mergeMethod: MergeMethod, isDraft } | undefined>(PREVIOUS_CREATE_METHOD, undefined); autoMergeDefault = (defaultCreateOption === 'lastUsed' && lastCreateMethod?.autoMerge) || (defaultCreateOption === 'createAutoMerge'); @@ -1023,10 +1086,10 @@ Don't forget to commit your template file to the repository so that it can be us baseRemote: result.remote, baseBranch: result.branch, defaultBaseBranch: defaultBranch, - defaultMergeMethod: getDefaultMergeMethod(mergeConfiguration.mergeMethodsAvailability), - allowAutoMerge: mergeConfiguration.viewerCanAutoMerge, + defaultMergeMethod: mergeConfiguration ? getDefaultMergeMethod(mergeConfiguration.mergeMethodsAvailability) : 'merge' as MergeMethod, + allowAutoMerge: mergeConfiguration?.viewerCanAutoMerge ?? false, baseHasMergeQueue: !!mergeQueueMethodForBranch, - mergeMethodsAvailability: mergeConfiguration.mergeMethodsAvailability, + mergeMethodsAvailability: mergeConfiguration?.mergeMethodsAvailability ?? { merge: true, squash: true, rebase: true }, autoMergeDefault, defaultTitle: titleAndDescription.title, defaultDescription: titleAndDescription.description @@ -1095,19 +1158,21 @@ Don't forget to commit your template file to the repository so that it can be us quickPick.show(); quickPick.busy = true; if (githubRepository) { - await updateItems(githubRepository, undefined); - } else { - quickPick.items = await this.remotePicks(isBase); + // Show cached branches immediately if available, then refresh in the background + const cached = cachedBranchPicks(githubRepository, this._folderRepositoryManager, chooseDifferentRemote, isBase); + if (cached) { + quickPick.items = cached; + const activeItem = message.args.currentBranch ? quickPick.items.find(item => item.branch === message.args.currentBranch) : undefined; + quickPick.activeItems = activeItem ? [activeItem] : []; + } } - const activeItem = message.args.currentBranch ? quickPick.items.find(item => item.branch === message.args.currentBranch) : undefined; - quickPick.activeItems = activeItem ? [activeItem] : []; - quickPick.busy = false; + // Register event handlers before awaiting async operations to avoid missing early user interactions const remoteAndBranch: Promise<{ remote: RemoteInfo, branch: string } | undefined> = new Promise((resolve) => { quickPick.onDidAccept(async () => { - if (quickPick.selectedItems.length === 0) { + const selectedPick = quickPick.selectedItems[0] ?? quickPick.activeItems[0]; + if (!selectedPick) { return; } - const selectedPick = quickPick.selectedItems[0]; if (selectedPick.label === chooseDifferentRemote) { quickPick.busy = true; quickPick.items = await this.remotePicks(isBase); @@ -1128,6 +1193,14 @@ Don't forget to commit your template file to the repository so that it can be us }); }); const hidePromise = new Promise((resolve) => quickPick.onDidHide(() => resolve())); + if (githubRepository) { + await updateItems(githubRepository, undefined); + } else { + quickPick.items = await this.remotePicks(isBase); + } + const activeItem = message.args.currentBranch ? quickPick.items.find(item => item.branch === message.args.currentBranch) : undefined; + quickPick.activeItems = activeItem ? [activeItem] : []; + quickPick.busy = false; const result = await Promise.race([remoteAndBranch, hidePromise]); if (!result || !githubRepository) { quickPick.hide(); @@ -1159,8 +1232,7 @@ Don't forget to commit your template file to the repository so that it can be us const template = await templatePromise; const provider = this._folderRepositoryManager.getTitleAndDescriptionProvider(searchTerm); - const result = await provider?.provider.provideTitleAndDescription({ commitMessages, patches, issues, template }, token); - + const result = await provider?.provider.provideTitleAndDescription({ commitMessages, patches, issues, template, compareBranch: this.model.compareBranch }, token); if (provider) { this.lastGeneratedTitleAndDescription = { ...result, providerTitle: provider.title }; /* __GDPR__ diff --git a/src/github/folderRepositoryManager.ts b/src/github/folderRepositoryManager.ts index 951476efc5..2ed186fbfa 100644 --- a/src/github/folderRepositoryManager.ts +++ b/src/github/folderRepositoryManager.ts @@ -11,8 +11,8 @@ import { ConflictModel } from './conflictGuide'; import { ConflictResolutionCoordinator } from './conflictResolutionCoordinator'; import { Conflict, ConflictResolutionModel } from './conflictResolutionModel'; import { CredentialStore } from './credentials'; -import { CopilotWorkingStatus, GitHubRepository, ItemsData, PULL_REQUEST_PAGE_SIZE, PullRequestChangeEvent, PullRequestData, TeamReviewerRefreshKind, ViewerPermission } from './githubRepository'; -import { PullRequestResponse, PullRequestState } from './graphql'; +import { CopilotWorkingStatus, GitHubRepository, isRateLimitError, ItemsData, PULL_REQUEST_PAGE_SIZE, PullRequestChangeEvent, PullRequestData, TeamReviewerRefreshKind, ViewerPermission } from './githubRepository'; +import { PullRequestState } from './graphql'; import { IAccount, ILabel, IMilestone, IProject, IPullRequestsPagingOptions, Issue, ITeam, MergeMethod, PRType, PullRequestMergeability, RepoAccessAndMergeMethods, User } from './interface'; import { IssueModel } from './issueModel'; import { PullRequestGitHelper, PullRequestMetadata } from './pullRequestGitHelper'; @@ -24,7 +24,6 @@ import { getPRFetchQuery, getStateFromQuery, loginComparator, - parseGraphQLPullRequest, teamComparator, variableSubstitution, } from './utils'; @@ -46,6 +45,7 @@ import { CHAT_SETTINGS_NAMESPACE, CHECKOUT_DEFAULT_BRANCH, CHECKOUT_PULL_REQUEST_BASE_BRANCH, + DEFAULT_DELETION_METHOD, DISABLE_AI_FEATURES, GIT, POST_DONE, @@ -53,6 +53,7 @@ import { PULL_BEFORE_CHECKOUT, PULL_BRANCH, REMOTES, + SELECT_WORKTREE, UPSTREAM_REMOTE, } from '../common/settingKeys'; import { ITelemetry } from '../common/telemetry'; @@ -226,6 +227,7 @@ export class FolderRepositoryManager extends Disposable { readonly onDidDispose: vscode.Event = this._onDidDispose.event; private _sessionIgnoredRemoteNames: Set = new Set(); + private _inaccessibleRepos: Set = new Set(); constructor( private readonly _id: number, @@ -950,7 +952,7 @@ export class FolderRepositoryManager extends Disposable { ); if (githubRepo) { - const pullRequest: PullRequestModel | undefined = await githubRepo.getPullRequest(prNumber); + const pullRequest: PullRequestModel | undefined = await githubRepo.getPullRequest(prNumber, 'FolderRepositoryManager.getLocalPullRequests'); if (pullRequest) { pullRequest.localBranchName = localBranchName; @@ -1305,7 +1307,7 @@ export class FolderRepositoryManager extends Disposable { async getPullRequestsForCategory(githubRepository: GitHubRepository, categoryQuery: string, page?: number): Promise { try { Logger.debug(`Fetch pull request category ${categoryQuery} - enter`, this.id); - const { octokit, query, schema } = await githubRepository.ensure(); + const { octokit } = await githubRepository.ensure(); /* __GDPR__ "pr.search.category" : { @@ -1321,18 +1323,14 @@ export class FolderRepositoryManager extends Disposable { page: page || 1, }); - const promises: Promise<{ data: PullRequestResponse, repo: GitHubRepository } | undefined>[] = data.items.map(async (item) => { + const promises: Promise<{ data: PullRequestModel | undefined, repo: GitHubRepository } | undefined>[] = data.items.map(async (item) => { const protocol = new Protocol(item.repository_url); const prRepo = await this.createGitHubRepositoryFromOwnerName(protocol.owner, protocol.repositoryName); - const { data } = await query({ - query: schema.PullRequest, - variables: { - owner: prRepo.remote.owner, - name: prRepo.remote.repositoryName, - number: item.number - } - }); + if (!prRepo) { + return undefined; + } + const data = await prRepo.getPullRequest(item.number, 'FolderRepositoryManager.getPullRequestsForCategory', false, true); return { data, repo: prRepo }; }); @@ -1341,16 +1339,12 @@ export class FolderRepositoryManager extends Disposable { const pullRequests = (await Promise.all(pullRequestResponses .map(async response => { - if (!response?.data.repository) { + if (!response?.data) { Logger.appendLine('Pull request doesn\'t appear to exist.', this.id); return null; } - // Pull requests fetched with a query can be from any repo. - // We need to use the correct GitHubRepository for this PR. - return response.repo.createOrUpdatePullRequestModel( - await parseGraphQLPullRequest(response.data.repository.pullRequest, response.repo), true - ); + return response.data; }))) .filter(item => item !== null) as PullRequestModel[]; @@ -1460,16 +1454,28 @@ export class FolderRepositoryManager extends Disposable { } } - async getMaxIssue(): Promise { - const maxIssues = await Promise.all( - this._githubRepositories.map(repository => { - return repository.getMaxIssue(); - }), - ); - let max: number = 0; - for (const issueNumber of maxIssues) { - if (issueNumber !== undefined) { - max = Math.max(max, issueNumber); + async getMaxIssue(repository: Repository): Promise { + const remoteNames = new Set(repository.state.remotes.map(remote => remote.name)); + const ghRepo = this._githubRepositories.find(repo => remoteNames.has(repo.remote.remoteName)); + if (!ghRepo) { + return 0; + } + + const reposToCheck: GitHubRepository[] = [ghRepo]; + const metadata = await ghRepo.getMetadata(); + if (metadata.fork) { + for (const repo of this._githubRepositories) { + if (repo !== ghRepo && repo.remote.repositoryName === ghRepo.remote.repositoryName) { + reposToCheck.push(repo); + } + } + } + + const maxIssues = await Promise.all(reposToCheck.map(repo => repo.getMaxIssue())); + let max = 0; + for (const value of maxIssues) { + if (value !== undefined) { + max = Math.max(max, value); } } return max; @@ -2148,35 +2154,89 @@ export class FolderRepositoryManager extends Disposable { quickPick.items = [{ label: vscode.l10n.t('No local branches to delete'), picked: false }]; } - let firstStep = true; + let step: 'branches' | 'worktrees' | 'remotes' = 'branches'; + let nonExistantBranches = new Set(); + let branchPicks: readonly vscode.QuickPickItem[] = []; + + const showWorktreeStep = (worktreeItems: (vscode.QuickPickItem & { worktreePath: string })[]) => { + quickPick.canSelectMany = true; + quickPick.value = ''; + quickPick.placeholder = vscode.l10n.t('Do you want to delete the associated worktrees?'); + quickPick.items = worktreeItems; + quickPick.selectedItems = worktreeItems.filter(item => item.picked); + step = 'worktrees'; + }; + + const deleteBranchesAndShowRemoteStep = async () => { + if (branchPicks.length) { + await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: vscode.l10n.t('Cleaning up') }, async (progress) => { + try { + await this.deleteBranches(branchPicks, nonExistantBranches, progress, branchPicks.length, 0, []); + } catch (e) { + quickPick.hide(); + vscode.window.showErrorMessage(vscode.l10n.t('Deleting branches failed: {0} {1}', e.message, e.stderr)); + } + }); + } + + const remoteItems = await this.getRemoteDeletionItems(nonExistantBranches); + if (remoteItems && remoteItems.length) { + quickPick.canSelectMany = true; + quickPick.placeholder = vscode.l10n.t('Choose remotes you want to delete permanently'); + quickPick.items = remoteItems; + quickPick.selectedItems = remoteItems.filter(item => item.picked); + step = 'remotes'; + } else { + quickPick.hide(); + } + }; + quickPick.onDidAccept(async () => { quickPick.busy = true; - if (firstStep) { - const picks = quickPick.selectedItems; - const nonExistantBranches = new Set(); - if (picks.length) { - await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: vscode.l10n.t('Cleaning up') }, async (progress) => { - try { - await this.deleteBranches(picks, nonExistantBranches, progress, picks.length, 0, []); - } catch (e) { - quickPick.hide(); - vscode.window.showErrorMessage(vscode.l10n.t('Deleting branches failed: {0} {1}', e.message, e.stderr)); - } - }); + if (step === 'branches') { + branchPicks = quickPick.selectedItems; + nonExistantBranches = new Set(); + + // Find which selected branches have worktrees (must be deleted before the branch) + const preferredWorktreeDeletion = !!vscode.workspace + .getConfiguration(PR_SETTINGS_NAMESPACE) + .get(`${DEFAULT_DELETION_METHOD}.${SELECT_WORKTREE}`); + const worktreeItems: (vscode.QuickPickItem & { worktreePath: string })[] = []; + for (const pick of branchPicks) { + const worktreeUri = this.getWorktreeForBranch(pick.label); + if (worktreeUri && !vscode.workspace.workspaceFolders?.some(folder => + folder.uri.fsPath === worktreeUri.fsPath || + (process.platform === 'win32' && folder.uri.fsPath.toLowerCase() === worktreeUri.fsPath.toLowerCase()) + )) { + worktreeItems.push({ + label: pick.label, + description: worktreeUri.fsPath, + picked: preferredWorktreeDeletion, + worktreePath: worktreeUri.fsPath, + }); + } } - firstStep = false; - const remoteItems = await this.getRemoteDeletionItems(nonExistantBranches); - - if (remoteItems && remoteItems.length) { - quickPick.canSelectMany = true; - quickPick.placeholder = vscode.l10n.t('Choose remotes you want to delete permanently'); - quickPick.items = remoteItems; - quickPick.selectedItems = remoteItems.filter(item => item.picked); + if (worktreeItems.length && this.repository.deleteWorktree) { + showWorktreeStep(worktreeItems); } else { - quickPick.hide(); + await deleteBranchesAndShowRemoteStep(); + } + } else if (step === 'worktrees') { + const picks = quickPick.selectedItems as readonly (vscode.QuickPickItem & { worktreePath: string })[]; + if (picks.length) { + await vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: vscode.l10n.t('Deleting {0} worktrees...', picks.length) }, async () => { + for (const pick of picks) { + try { + await this.removeWorktree(pick.worktreePath); + } catch (e) { + Logger.error(`Failed to delete worktree ${pick.worktreePath}: ${e}`, this.id); + } + } + }); } + await deleteBranchesAndShowRemoteStep(); } else { // batch deleting the remotes to avoid consuming all available resources const picks = quickPick.selectedItems; @@ -2296,7 +2356,7 @@ export class FolderRepositoryManager extends Disposable { const githubRepo = await this.resolveItem(owner, repositoryName); Logger.trace(`Found GitHub repo for pr #${pullRequestNumber}: ${githubRepo ? 'yes' : 'no'}`, this.id); if (githubRepo) { - const pr = await githubRepo.getPullRequest(pullRequestNumber, useCache); + const pr = await githubRepo.getPullRequest(pullRequestNumber, 'FolderRepositoryManager.resolvePullRequest', useCache); Logger.trace(`Found GitHub pr repo for pr #${pullRequestNumber}: ${pr ? 'yes' : 'no'}`, this.id); return pr; } @@ -2323,7 +2383,7 @@ export class FolderRepositoryManager extends Disposable { async resolveUser(owner: string, repositoryName: string, login: string): Promise { Logger.debug(`Fetch user ${login}`, this.id); const githubRepository = await this.createGitHubRepositoryFromOwnerName(owner, repositoryName); - return githubRepository.resolveUser(login); + return githubRepository?.resolveUser(login); } async getMatchingPullRequestMetadataForBranch() { @@ -2450,6 +2510,35 @@ export class FolderRepositoryManager extends Disposable { return await PullRequestGitHelper.getBranchNRemoteForPullRequest(this.repository, pullRequest); } + getWorktreeForBranch(branchName: string): vscode.Uri | undefined { + const worktrees = this.repository.state.worktrees; + if (!worktrees) { + return undefined; + } + const refsHeadsPrefix = 'refs/heads/'; + const worktree = worktrees.find(wt => { + if (wt.main) { + return false; + } + const ref = wt.ref.startsWith(refsHeadsPrefix) ? wt.ref.substring(refsHeadsPrefix.length) : wt.ref; + return ref === branchName; + }); + return worktree ? vscode.Uri.file(worktree.path) : undefined; + } + + async removeWorktree(worktreePath: string): Promise { + if (!this.repository.deleteWorktree) { + Logger.error(`deleteWorktree is not available on this repository`, this.id); + return; + } + try { + await this.repository.deleteWorktree(worktreePath); + } catch (e) { + Logger.error(`Failed to remove worktree ${worktreePath}: ${e}`, this.id); + throw e; + } + } + async fetchAndCheckout(pullRequest: PullRequestModel, progress: vscode.Progress<{ message?: string; increment?: number }>): Promise { await PullRequestGitHelper.fetchAndCheckout(this.repository, this._allGitHubRemotes, pullRequest, progress); } @@ -2473,7 +2562,8 @@ export class FolderRepositoryManager extends Disposable { } let continueWithMerge = true; if (pullRequest.item.mergeable === PullRequestMergeability.Conflict) { - const githubRepos = await Promise.all([this.createGitHubRepositoryFromOwnerName(pullRequest.head!.owner, pullRequest.head!.repositoryCloneUrl.repositoryName), this.createGitHubRepositoryFromOwnerName(pullRequest.base.owner, pullRequest.base.repositoryCloneUrl.repositoryName)]); + const githubRepoResults = await Promise.all([this.createGitHubRepositoryFromOwnerName(pullRequest.head!.owner, pullRequest.head!.repositoryCloneUrl.repositoryName), this.createGitHubRepositoryFromOwnerName(pullRequest.base.owner, pullRequest.base.repositoryCloneUrl.repositoryName)]); + const githubRepos = githubRepoResults.filter((r): r is GitHubRepository => !!r); const coordinator = new ConflictResolutionCoordinator(this.telemetry, conflictModel, githubRepos); continueWithMerge = await coordinator.enterConflictResolutionAndWaitForExit(); coordinator.dispose(); @@ -2486,7 +2576,7 @@ export class FolderRepositoryManager extends Disposable { } } - if (pullRequest.item.mergeable !== PullRequestMergeability.Conflict) { + if (pullRequest.item.mergeable !== PullRequestMergeability.Conflict && !pullRequest.githubRepository.remote.isEnterprise) { const result = await vscode.window.withProgress( { location: vscode.ProgressLocation.Notification, title: vscode.l10n.t('Updating branch...') }, async () => { @@ -2547,7 +2637,7 @@ export class FolderRepositoryManager extends Disposable { } async fetchById(githubRepo: GitHubRepository, id: number): Promise { - const pullRequest = await githubRepo.getPullRequest(id); + const pullRequest = await githubRepo.getPullRequest(id, 'FolderRepositoryManager.fetchById'); if (pullRequest) { return pullRequest; } else { @@ -2815,15 +2905,39 @@ export class FolderRepositoryManager extends Disposable { }); } - async createGitHubRepositoryFromOwnerName(owner: string, repositoryName: string): Promise { + async createGitHubRepositoryFromOwnerName(owner: string, repositoryName: string): Promise { const existing = this.findExistingGitHubRepository({ owner, repositoryName }); if (existing) { return existing; } + const repoKey = `${owner.toLowerCase()}/${repositoryName.toLowerCase()}`; + if (this._inaccessibleRepos.has(repoKey)) { + Logger.debug(`Skipping inaccessible repository: ${owner}/${repositoryName}`, this.id); + return undefined; + } const gitRemotes = parseRepositoryRemotes(this.repository); const gitRemote = gitRemotes.find(r => r.owner === owner && r.repositoryName === repositoryName); const uri = gitRemote?.url ?? `https://github.com/${owner}/${repositoryName}`; - return this.createAndAddGitHubRepository(new Remote(gitRemote?.remoteName ?? repositoryName, uri, new Protocol(uri)), this._credentialStore); + const repo = await this.createAndAddGitHubRepository(new Remote(gitRemote?.remoteName ?? repositoryName, uri, new Protocol(uri)), this._credentialStore); + let reason: string; + try { + await repo.getMetadata(); + return repo; + } catch (e) { + reason = 'error'; + Logger.appendLine(`Repository ${owner}/${repositoryName} is not accessible: ${e}`, this.id); + } + Logger.appendLine(`Repository ${owner}/${repositoryName} is not accessible.`, this.id); + this._inaccessibleRepos.add(repoKey); + this.removeGitHubRepository(repo.remote); + /* __GDPR__ + "repository.inaccessible" : { + "hasLocalRemote" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }, + "reason" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } + */ + this.telemetry.sendTelemetryEvent('repository.inaccessible', { hasLocalRemote: (!!gitRemote).toString(), reason }); + return undefined; } async findUpstreamForItem(item: { @@ -2957,7 +3071,16 @@ export class FolderRepositoryManager extends Disposable { pushRemote, this.credentialStore, ); - const permission = await githubRepo.getViewerPermission(); + let permission: ViewerPermission; + try { + permission = await githubRepo.getViewerPermission(); + } catch (e) { + if (isRateLimitError(e)) { + vscode.window.showErrorMessage(vscode.l10n.t('GitHub API rate limit exceeded. Please wait and try again.'), { modal: true }); + return; + } + throw e; + } let selectedRemote: GitHubRemote | undefined; if ( permission === ViewerPermission.Read || diff --git a/src/github/githubRepository.ts b/src/github/githubRepository.ts index f60942ed46..e761abcdf9 100644 --- a/src/github/githubRepository.ts +++ b/src/github/githubRepository.ts @@ -55,7 +55,7 @@ import { User, } from './interface'; import { IssueChangeEvent, IssueModel } from './issueModel'; -import { LoggingOctokit } from './loggingOctokit'; +import { getErrorCode, GraphQLError, LoggingOctokit } from './loggingOctokit'; import { PullRequestModel } from './pullRequestModel'; import defaultSchema from './queries.gql'; import * as extraSchema from './queriesExtra.gql'; @@ -124,6 +124,26 @@ export enum ViewerPermission { Write = 'WRITE', } +export class RateLimitError extends Error { + constructor(message?: string) { + super(message ?? 'GitHub API rate limit exceeded'); + this.name = 'RateLimitError'; + } +} + +export function isRateLimitError(e: unknown): boolean { + if (e instanceof RateLimitError) { + return true; + } + if (e instanceof Error) { + const msg = e.message.toLowerCase(); + if (msg.includes('rate limit') || msg.includes('secondary rate') || msg.includes('abuse detection')) { + return true; + } + } + return false; +} + export enum TeamReviewerRefreshKind { None, Try, @@ -142,18 +162,6 @@ export interface ForkDetails { export type IMetadata = OctokitCommon.ReposGetResponseData; -export enum GraphQLErrorType { - Unprocessable = 'UNPROCESSABLE', -} - -export interface GraphQLError { - extensions?: { - code: string; - }; - type?: GraphQLErrorType; - message?: string; -} - export enum CopilotWorkingStatus { NotCopilotIssue = 'NotCopilotIssue', InProgress = 'InProgress', @@ -168,6 +176,8 @@ export interface PullRequestChangeEvent { export class GitHubRepository extends Disposable { static ID = 'GitHubRepository'; + private static _allRepoIds: Set = new Set(); + private static _succeededPullRequests: Map> = new Map(); protected _initialized: boolean = false; protected _hub: GitHub | undefined; protected _metadata: Promise | undefined; @@ -190,8 +200,15 @@ export class GitHubRepository extends Disposable { // eslint-disable-next-line rulesdir/no-any-except-union-method-signature private _queriesSchema: any; private _areQueriesLimited: boolean = false; + + private static readonly MAX_ITEM_NUMBER_TTL_MS = 60 * 60 * 1000; /* 1 hour */ + private static readonly MAX_ITEM_NUMBER_BUFFER = 50; + private _maxItemNumberCache: { value: number; fetchedAt: number } | undefined; + private _maxItemNumberPromise: Promise | undefined; get areQueriesLimited(): boolean { return this._areQueriesLimited; } + private _branchesCache: Map = new Map(); + private _onDidAddPullRequest: vscode.EventEmitter = this._register(new vscode.EventEmitter()); public readonly onDidAddPullRequest: vscode.Event = this._onDidAddPullRequest.event; private _onDidChangePullRequests: vscode.EventEmitter = this._register(new vscode.EventEmitter()); @@ -248,6 +265,10 @@ export class GitHubRepository extends Disposable { override dispose() { super.dispose(); + GitHubRepository._allRepoIds.delete(this._id); + for (const repoIds of GitHubRepository._succeededPullRequests.values()) { + repoIds.delete(this._id); + } this.commentsController = undefined; this.commentsHandler = undefined; } @@ -269,6 +290,7 @@ export class GitHubRepository extends Disposable { silent: boolean = false ) { super(); + GitHubRepository._allRepoIds.add(this._id); this._queriesSchema = mergeQuerySchemaWithShared(sharedSchema.default, defaultSchema); // kick off the comments controller early so that the Comments view is visible and doesn't pop up later in an way that's jarring if (!silent) { @@ -502,7 +524,18 @@ export class GitHubRepository extends Disposable { Logger.debug('Fetch pull request templates - done', this.id); return result.data.repository.pullRequestTemplates.map(template => template.body); } catch (e) { - // The template was not found. + Logger.error(`Fetching pull request templates failed: ${e}`, this.id); + const properties: { errorCode?: string } = {}; + const errorCode = getErrorCode(e); + if (errorCode) { + properties.errorCode = errorCode; + } + /* __GDPR__ + "pr.getPullRequestTemplatesFailed" : { + "errorCode": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } + } + */ + this.telemetry.sendTelemetryErrorEvent('pr.getPullRequestTemplatesFailed', properties); } } @@ -926,6 +959,62 @@ export class GitHubRepository extends Disposable { return this._getMaxItem(false); } + /** + * Returns the highest known issue or pull request number for this repository. + * Issues and pull requests share the same number sequence on GitHub, so the + * larger of the two latest items is an upper bound for any valid number. + * Result is cached for a short TTL to avoid extra round-trips. + */ + private async getCachedMaxItemNumber(forceRefresh: boolean = false): Promise { + const now = Date.now(); + if (!forceRefresh && this._maxItemNumberCache && (now - this._maxItemNumberCache.fetchedAt) < GitHubRepository.MAX_ITEM_NUMBER_TTL_MS) { + return this._maxItemNumberCache.value; + } + if (this._maxItemNumberPromise) { + return this._maxItemNumberPromise; + } + this._maxItemNumberPromise = (async () => { + const [maxIssue, maxPr] = await Promise.all([this._getMaxItem(true), this._getMaxItem(false)]); + const max = Math.max(maxIssue ?? 0, maxPr ?? 0); + if (max > 0) { + this._maxItemNumberCache = { value: max, fetchedAt: Date.now() }; + return max; + } + return undefined; + })(); + try { + return await this._maxItemNumberPromise; + } finally { + this._maxItemNumberPromise = undefined; + } + } + + /** + * Returns false when `number` is implausibly higher than the latest known + * issue/PR number for this repository. Used to short-circuit fetches for + * numbers that came from arbitrary text (e.g. `#1234567890` in source code) + * before they hit the network and produce noisy error telemetry. + */ + private async isPlausibleItemNumber(itemNumber: number): Promise { + if (!Number.isFinite(itemNumber) || itemNumber <= 0) { + return false; + } + let max = await this.getCachedMaxItemNumber(); + if (max === undefined) { + // Couldn't determine the max (e.g. network error); allow through. + return true; + } + if (itemNumber <= max + GitHubRepository.MAX_ITEM_NUMBER_BUFFER) { + return true; + } + // Number is above the cached max; refresh once before deciding to handle newly-created items. + max = await this.getCachedMaxItemNumber(true); + if (max === undefined) { + return true; + } + return itemNumber <= max + GitHubRepository.MAX_ITEM_NUMBER_BUFFER; + } + async getViewerPermission(): Promise { try { Logger.debug(`Fetch viewer permission - enter`, this.id); @@ -941,6 +1030,9 @@ export class GitHubRepository extends Disposable { return parseGraphQLViewerPermission(data); } catch (e) { Logger.error(`Unable to fetch viewer permission: ${e}`, this.id); + if (isRateLimitError(e)) { + throw new RateLimitError(); + } return ViewerPermission.Unknown; } } @@ -1182,12 +1274,17 @@ export class GitHubRepository extends Disposable { } } - async getPullRequest(id: number, useCache: boolean = false): Promise { + async getPullRequest(id: number, callerName: string, useCache: boolean = false, silent: boolean = false): Promise { if (useCache && this._pullRequestModelsByNumber.has(id)) { Logger.debug(`Using cached pull request model for ${id}`, this.id); return this._pullRequestModelsByNumber.get(id)!.model; } + if (!(await this.isPlausibleItemNumber(id))) { + Logger.debug(`Skipping pull request fetch for implausible number ${id} (caller: ${callerName})`, this.id); + return; + } + try { const { query, remote, schema } = await this.ensure(); Logger.debug(`Fetch pull request ${remote.owner}/${remote.repositoryName} ${id} - enter`, this.id); @@ -1206,11 +1303,40 @@ export class GitHubRepository extends Disposable { } Logger.debug(`Fetch pull request ${id} - done`, this.id); - const pr = this.createOrUpdatePullRequestModel(await parseGraphQLPullRequest(data.repository.pullRequest, this)); + const pr = this.createOrUpdatePullRequestModel(await parseGraphQLPullRequest(data.repository.pullRequest, this), silent); await pr.getLastUpdateTime(new Date(pr.item.updatedAt)); + let repoIds = GitHubRepository._succeededPullRequests.get(id); + if (!repoIds) { + repoIds = new Set(); + GitHubRepository._succeededPullRequests.set(id, repoIds); + } + repoIds.add(this._id); return pr; } catch (e) { Logger.error(`Unable to fetch PR: ${e}`, this.id); + const succeededRepos = GitHubRepository._succeededPullRequests.get(id); + const succeededInOtherRepo = succeededRepos ? succeededRepos.size > 0 && !succeededRepos.has(this._id) : false; + const properties: { succeededInOtherRepo: string; callerName: string; errorCode?: string } = { + succeededInOtherRepo: String(succeededInOtherRepo), + callerName + }; + const errorCode = getErrorCode(e); + if (errorCode) { + properties.errorCode = errorCode; + } + /* __GDPR__ + "pr.getPullRequestFailed" : { + "prNumber": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "gitHubRepoCount": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "succeededInOtherRepo": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "errorCode": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "callerName": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } + } + */ + this.telemetry.sendTelemetryErrorEvent('pr.getPullRequestFailed', properties, { + prNumber: id, + gitHubRepoCount: GitHubRepository._allRepoIds.size + }); return; } } @@ -1223,6 +1349,10 @@ export class GitHubRepository extends Disposable { return cached; } } + if (!(await this.isPlausibleItemNumber(id))) { + Logger.debug(`Skipping issue fetch for implausible number ${id}`, this.id); + return undefined; + } try { Logger.debug(`Fetch issue ${id} - enter`, this.id); const { query, remote, schema } = await this.ensure(); @@ -1318,6 +1448,14 @@ export class GitHubRepository extends Disposable { return data.repository?.ref?.target.oid; } + private branchesCacheKey(owner: string, repositoryName: string): string { + return `${owner}/${repositoryName}`; + } + + getCachedBranches(owner: string, repositoryName: string): string[] | undefined { + return this._branchesCache.get(this.branchesCacheKey(owner, repositoryName)); + } + async listBranches(owner: string, repositoryName: string, prefix: string | undefined): Promise { const { query, remote, schema } = await this.ensure(); Logger.debug(`List branches for ${owner}/${repositoryName} - enter`, this.id); @@ -1359,6 +1497,10 @@ export class GitHubRepository extends Disposable { if (!branches.includes(defaultBranch)) { branches.unshift(defaultBranch); } + // Cache results for unprefixed queries + if (!prefix) { + this._branchesCache.set(this.branchesCacheKey(owner, repositoryName), branches); + } return branches; } @@ -1451,11 +1593,14 @@ export class GitHubRepository extends Disposable { let after: string | null = null; let hasNextPage = false; const ret: IAccount[] = []; + // Once we fall back to the legacy assignableUsers query, the cursors are not compatible + // with suggestedActors, so stay on the legacy query for the rest of the pagination. + let useLegacyAssignableUsers = false; do { try { - let result: { data: AssignableUsersResponse | SuggestedActorsResponse } | undefined; - if (schema.GetSuggestedActors) { + let result: { data: AssignableUsersResponse | SuggestedActorsResponse | null } | undefined; + if (schema.GetSuggestedActors && !useLegacyAssignableUsers) { result = await query({ query: schema.GetSuggestedActors, variables: { @@ -1487,13 +1632,20 @@ export class GitHubRepository extends Disposable { }, true); // we ignore SAML errors here because this query can happen at startup } - if (result.data.repository === null) { + if (result.data?.repository === null) { Logger.error('Unexpected null repository when getting assignable users', this.id); return []; } const users = (result.data as AssignableUsersResponse).repository?.assignableUsers ?? (result.data as SuggestedActorsResponse).repository?.suggestedActors; + // If we got assignableUsers back (either because we already used the legacy query, or + // because the legacy fallback kicked in inside query()), the cursor is incompatible with + // suggestedActors. Stay on the legacy query for subsequent pages. + if ((result.data as AssignableUsersResponse).repository?.assignableUsers) { + useLegacyAssignableUsers = true; + } + ret.push( ...(users?.nodes.map(node => { return parseAccount(node, this); @@ -1504,6 +1656,20 @@ export class GitHubRepository extends Disposable { after = users?.pageInfo.endCursor; } catch (e) { Logger.debug(`Unable to fetch assignable users: ${e}`, this.id); + const properties: { errorCode?: string; usedSuggestedActors: string } = { + usedSuggestedActors: String(!!schema.GetSuggestedActors), + }; + const errorCode = getErrorCode(e); + if (errorCode) { + properties.errorCode = errorCode; + } + /* __GDPR__ + "pr.getAssignableUsersFailed" : { + "errorCode": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "usedSuggestedActors": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } + } + */ + this.telemetry.sendTelemetryErrorEvent('pr.getAssignableUsersFailed', properties); if ( e.graphQLErrors && e.graphQLErrors.length > 0 && @@ -1879,9 +2045,13 @@ export class GitHubRepository extends Disposable { const statusByContext = new Map(); for (const status of statuses) { - const existing = statusByContext.get(status.context); + // Include event and workflowName in the key so that checks from different + // workflow events (e.g. "push" vs "pull_request") or different workflows + // are not incorrectly merged during deduplication. + const key = `${status.context}\0${status.event ?? ''}\0${status.workflowName ?? ''}`; + const existing = statusByContext.get(key); if (!existing) { - statusByContext.set(status.context, status); + statusByContext.set(key, status); continue; } @@ -1891,7 +2061,7 @@ export class GitHubRepository extends Disposable { if (currentIsPending && !existingIsPending) { // Current is pending, existing is completed - prefer current - statusByContext.set(status.context, status); + statusByContext.set(key, status); } else if (!currentIsPending && existingIsPending) { // Current is completed, existing is pending - keep existing continue; @@ -1899,7 +2069,7 @@ export class GitHubRepository extends Disposable { // Both are same type (both pending or both completed) // Prefer the one with a higher ID (more recent), as GitHub IDs are monotonically increasing if (status.id > existing.id) { - statusByContext.set(status.context, status); + statusByContext.set(key, status); } } } diff --git a/src/github/issueModel.ts b/src/github/issueModel.ts index 7fb5c830b1..ff6b910ac7 100644 --- a/src/github/issueModel.ts +++ b/src/github/issueModel.ts @@ -503,7 +503,7 @@ export class IssueModel extends Disposable { for (const unseenPrs of crossRefs) { // Kick off getting the new PRs so that the system knows about them (and refreshes the tree when they're found) - this.githubRepository.getPullRequest(unseenPrs.source.number); + this.githubRepository.getPullRequest(unseenPrs.source.number, 'IssueModel.getTimelineEvents'); } this.timelineEvents = events; diff --git a/src/github/issueOverview.ts b/src/github/issueOverview.ts index 67f3aef622..17f8107ad4 100644 --- a/src/github/issueOverview.ts +++ b/src/github/issueOverview.ts @@ -5,13 +5,13 @@ 'use strict'; import * as vscode from 'vscode'; -import { CloseResult } from '../../common/views'; +import { CloseResult, OpenLocalFileArgs } from '../../common/views'; import { openPullRequestOnGitHub } from '../commands'; import { FolderRepositoryManager } from './folderRepositoryManager'; import { GithubItemStateEnum, IAccount, IMilestone, IProject, IProjectItem, RepoAccessAndMergeMethods } from './interface'; import { IssueModel } from './issueModel'; import { getAssigneesQuickPickItems, getLabelOptions, getMilestoneFromQuickPick, getProjectFromQuickPick } from './quickPicks'; -import { isInCodespaces, vscodeDevPrLink } from './utils'; +import { isInCodespaces, processPermalinks, vscodeDevPrLink } from './utils'; import { ChangeAssigneesReply, DisplayLabel, Issue, ProjectItemsReply, SubmitReviewReply, UnresolvedIdentity } from './views'; import { COPILOT_ACCOUNTS, IComment } from '../common/comment'; import { emojify, ensureEmojis } from '../common/emoji'; @@ -249,7 +249,7 @@ export class IssueOverviewPanel extends W return isInCodespaces(); } - protected getInitializeContext(currentUser: IAccount, issue: IssueModel, timelineEvents: TimelineEvent[], repositoryAccess: RepoAccessAndMergeMethods, viewerCanEdit: boolean, assignableUsers: IAccount[]): Issue { + protected async getInitializeContext(currentUser: IAccount, issue: IssueModel, timelineEvents: TimelineEvent[], repositoryAccess: RepoAccessAndMergeMethods, viewerCanEdit: boolean, assignableUsers: IAccount[]): Promise { const hasWritePermission = repositoryAccess.hasWritePermission; const canEdit = hasWritePermission || viewerCanEdit; const labels = issue.item.labels.map(label => ({ @@ -266,12 +266,12 @@ export class IssueOverviewPanel extends W url: issue.html_url, createdAt: issue.createdAt, body: issue.body, - bodyHTML: issue.bodyHTML, + bodyHTML: await this.processLinksInBodyHtml(issue.bodyHTML), labels: labels, author: issue.author, state: issue.state, stateReason: issue.stateReason, - events: timelineEvents, + events: await this.processTimelineEvents(timelineEvents), continueOnGitHub: this.continueOnGitHub(), canEdit, hasWritePermission, @@ -321,10 +321,13 @@ export class IssueOverviewPanel extends W this._item = issue as TItem; this.setPanelTitle(this.buildPanelTitle(issueModel.number, issueModel.title)); + // Process permalinks in bodyHTML before sending to webview + const context = await this.getInitializeContext(currentUser, issue, timelineEvents, repositoryAccess, viewerCanEdit, assignableUsers[this._item.remote.remoteName] ?? []); + Logger.debug('pr.initialize', IssueOverviewPanel.ID); this._postMessage({ command: 'pr.initialize', - pullrequest: this.getInitializeContext(currentUser, issue, timelineEvents, repositoryAccess, viewerCanEdit, assignableUsers[this._item.remote.remoteName] ?? []), + pullrequest: context, }); } catch (e) { @@ -445,6 +448,8 @@ export class IssueOverviewPanel extends W return this.copyVscodeDevLink(); case 'pr.openOnGitHub': return openPullRequestOnGitHub(this._item, this._telemetry); + case 'pr.open-local-file': + return this.openLocalFile(message); case 'pr.debug': return this.webviewDebug(message); default: @@ -568,16 +573,54 @@ export class IssueOverviewPanel extends W Logger.debug(message.args, IssueOverviewPanel.ID); } - private editDescription(message: IRequestMessage<{ text: string }>) { - this._item - .edit({ body: message.args.text }) - .then(result => { - this._replyMessage(message, { body: result.body, bodyHTML: result.bodyHTML }); - }) - .catch(e => { - this._throwError(message, e); - vscode.window.showErrorMessage(`Editing description failed: ${formatError(e)}`); - }); + /** + * Process code reference links in bodyHTML. Can be overridden by subclasses (e.g., PullRequestOverviewPanel) + * to provide custom processing logic for different item types. + * Returns undefined if bodyHTML is undefined. + */ + protected async processLinksInBodyHtml(bodyHTML: string | undefined): Promise { + if (!bodyHTML) { + return bodyHTML; + } + return processPermalinks( + bodyHTML, + this._item.githubRepository, + this._item.githubRepository.rootUri + ); + } + + /** + * Process code reference links in timeline events (comments, reviews, commits). + * Updates bodyHTML fields for all events that contain them. + */ + protected async processTimelineEvents(events: TimelineEvent[]): Promise { + return Promise.all(events.map(async (event) => { + // Create a shallow copy to avoid mutating the original + const processedEvent = { ...event }; + + if (processedEvent.event === EventType.Commented || processedEvent.event === EventType.Reviewed || processedEvent.event === EventType.Committed) { + processedEvent.bodyHTML = await this.processLinksInBodyHtml(processedEvent.bodyHTML); + // ReviewEvent also has comments array + if (processedEvent.event === EventType.Reviewed && processedEvent.comments) { + processedEvent.comments = await Promise.all(processedEvent.comments.map(async (comment: IComment) => ({ + ...comment, + bodyHTML: await this.processLinksInBodyHtml(comment.bodyHTML) + }))); + } + } + return processedEvent; + })); + } + + private async editDescription(message: IRequestMessage<{ text: string }>) { + try { + const result = await this._item.edit({ body: message.args.text }); + const bodyHTML = await this.processLinksInBodyHtml(result.bodyHTML); + this._replyMessage(message, { body: result.body, bodyHTML }); + } catch (e) { + this._throwError(message, e); + vscode.window.showErrorMessage(`Editing description failed: ${formatError(e)}`); + } } private editTitle(message: IRequestMessage<{ text: string }>) { return this._item @@ -591,8 +634,9 @@ export class IssueOverviewPanel extends W }); } - protected _getTimeline(): Promise { - return this._item.getIssueTimelineEvents(); + protected async _getTimeline(): Promise { + const events = await this._item.getIssueTimelineEvents(); + return this.processTimelineEvents(events); } private async changeAssignees(message: IRequestMessage): Promise { @@ -726,18 +770,15 @@ export class IssueOverviewPanel extends W return this._item.editIssueComment(comment, text); } - private editComment(message: IRequestMessage<{ comment: IComment; text: string }>) { - this.editCommentPromise(message.args.comment, message.args.text) - .then(result => { - this._replyMessage(message, { - body: result.body, - bodyHTML: result.bodyHTML, - }); - }) - .catch(e => { - this._throwError(message, e); - vscode.window.showErrorMessage(formatError(e)); - }); + private async editComment(message: IRequestMessage<{ comment: IComment; text: string }>) { + try { + const result = await this.editCommentPromise(message.args.comment, message.args.text); + const bodyHTML = await this.processLinksInBodyHtml(result.bodyHTML); + this._replyMessage(message, { body: result.body, bodyHTML }); + } catch (e) { + this._throwError(message, e); + vscode.window.showErrorMessage(formatError(e)); + } } protected deleteCommentPromise(comment: IComment): Promise { @@ -761,6 +802,29 @@ export class IssueOverviewPanel extends W }); } + protected async openLocalFile(message: IRequestMessage): Promise { + try { + const { file, startLine, endLine } = message.args; + // Resolve relative path to absolute using repository root + const fileUri = vscode.Uri.joinPath( + this._item.githubRepository.rootUri, + file + ); + const selection = new vscode.Range( + new vscode.Position(startLine - 1, 0), + new vscode.Position(endLine - 1, Number.MAX_SAFE_INTEGER) + ); + await vscode.window.showTextDocument(fileUri, { + selection, + viewColumn: vscode.ViewColumn.One + }); + } catch (e) { + Logger.error(`Open local file failed: ${formatError(e)}`, IssueOverviewPanel.ID); + // Fallback to opening external URL + await vscode.env.openExternal(vscode.Uri.parse(message.args.href)); + } + } + protected async close(message: IRequestMessage) { let comment: IComment | undefined; if (message.args) { diff --git a/src/github/loggingOctokit.ts b/src/github/loggingOctokit.ts index 09813b75ae..f1c6e9cc81 100644 --- a/src/github/loggingOctokit.ts +++ b/src/github/loggingOctokit.ts @@ -28,14 +28,91 @@ interface RateLimitResult { } | undefined; } +export enum GraphQLErrorType { + Unprocessable = 'UNPROCESSABLE', +} + +export interface GraphQLError { + extensions?: { + code: string; + }; + type?: GraphQLErrorType; + message?: string; +} + +function isObject(value: unknown): value is Record { + return typeof value === 'object' && value !== null; +} + +export function getErrorCode(e: unknown): string | undefined { + if (!isObject(e)) { + return undefined; + } + + if (e.status !== undefined) { + return String(e.status); + } + + const networkError = e.networkError; + if (isObject(networkError) && networkError.statusCode !== undefined) { + return String(networkError.statusCode); + } + + const graphQLErrors = e.graphQLErrors; + if (Array.isArray(graphQLErrors) && graphQLErrors.length > 0) { + const firstGraphQLError = graphQLErrors[0] as GraphQLError | undefined; + if (firstGraphQLError) { + if (firstGraphQLError.extensions?.code !== undefined) { + return String(firstGraphQLError.extensions.code); + } + if (firstGraphQLError.type !== undefined) { + return String(firstGraphQLError.type); + } + } + } + + if (e.code !== undefined) { + return String(e.code); + } + + if (typeof e.name === 'string' && e.name) { + const message = typeof e.message === 'string' ? e.message : ''; + if (e.name !== 'Error') { + return message ? `${e.name}: ${message}` : e.name; + } + if (message) { + return message; + } + } + + return undefined; +} + export class RateLogger { private bulkhead: BulkheadPolicy = bulkhead(140); private static ID = 'RateLimit'; private hasLoggedLowRateLimit: boolean = false; + private readonly _isInsiders: boolean; - constructor(private readonly telemetry: ITelemetry, private readonly errorOnFlood: boolean) { } + constructor(private readonly telemetry: ITelemetry, private readonly errorOnFlood: boolean) { + this._isInsiders = vscode.env.appName.toLowerCase().includes('insider'); + } + + private static sanitizeOperationName(info: string): string { + // REST URLs like /repos/{owner}/{repo}/pulls get redacted because they look + // like file paths. Convert slashes to dots to avoid redaction. + return info.replace(/\/+/g, '.').replace(/^\.+|\.+$/g, ''); + } public logAndLimit>(info: string | undefined, apiRequest: () => T): T | undefined { + if (this._isInsiders && info) { + /* __GDPR__ + "pr.apiCall" : { + "operation" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" } + } + */ + this.telemetry.sendTelemetryEvent('pr.apiCall', { operation: RateLogger.sanitizeOperationName(info) }); + } if (this.bulkhead.executionSlots === 0) { Logger.error('API call count has exceeded 140 concurrent calls.', RateLogger.ID); // We have hit more than 140 concurrent API requests. @@ -94,6 +171,25 @@ export class RateLogger { } } + public logApiError(info: string | undefined, apiResult: Promise): void { + apiResult.catch(e => { + const properties: { operation: string; errorCode?: string } = { + operation: RateLogger.sanitizeOperationName(info ?? 'unknown'), + }; + const errorCode = getErrorCode(e); + if (errorCode) { + properties.errorCode = errorCode; + } + /* __GDPR__ + "pr.apiCallFailed" : { + "operation": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" }, + "errorCode": { "classification": "SystemMetaData", "purpose": "PerformanceAndHealth" } + } + */ + this.telemetry.sendTelemetryErrorEvent('pr.apiCallFailed', properties); + }); + } + public async logRestRateLimit(info: string | undefined, restResponse: Promise) { let result; try { @@ -122,16 +218,18 @@ export class LoggingApolloClient { throw new Error('API call count has exceeded a rate limit.'); } this._rateLogger.logRateLimit(logInfo, result as Promise); + this._rateLogger.logApiError(logInfo, result); return result; } mutate(options: MutationOptions): Promise> { - const logInfo = options.context; + const logInfo = String(options.context); const result = this._rateLogger.logAndLimit(logInfo, () => this._graphql.mutate(options)); if (result === undefined) { throw new Error('API call count has exceeded a rate limit.'); } this._rateLogger.logRateLimit(logInfo, result as Promise); + this._rateLogger.logApiError(logInfo, result); return result; } } @@ -146,6 +244,7 @@ export class LoggingOctokit { throw new Error('API call count has exceeded a rate limit.'); } this._rateLogger.logRestRateLimit(logInfo, result as Promise as Promise); + this._rateLogger.logApiError(logInfo, result); return result; } } diff --git a/src/github/overviewRestorer.ts b/src/github/overviewRestorer.ts index fdb59e64b7..550379fb75 100644 --- a/src/github/overviewRestorer.ts +++ b/src/github/overviewRestorer.ts @@ -53,6 +53,11 @@ export class OverviewRestorer extends Disposable implements vscode.WebviewPanelS repo = await folderManager.createGitHubRepositoryFromOwnerName(state.owner, state.repo); } + if (!repo || !folderManager) { + webviewPanel.dispose(); + return; + } + const identity = { owner: state.owner, repo: state.repo, number: state.number }; if (state.isIssue) { const issueModel = await repo.getIssue(state.number, true); @@ -62,7 +67,7 @@ export class OverviewRestorer extends Disposable implements vscode.WebviewPanelS } return IssueOverviewPanel.createOrShow(this._telemetry, this._extensionUri, folderManager, identity, issueModel, undefined, true, webviewPanel); } else { - const pullRequestModel = await repo.getPullRequest(state.number, true); + const pullRequestModel = await repo.getPullRequest(state.number, 'OverviewRestorer.deserializeWebviewPanel', true); if (!pullRequestModel) { webviewPanel.dispose(); return; diff --git a/src/github/prComment.ts b/src/github/prComment.ts index bd7970b75e..d2ccba181e 100644 --- a/src/github/prComment.ts +++ b/src/github/prComment.ts @@ -175,7 +175,7 @@ export class TemporaryComment extends CommentBase { this.mode = vscode.CommentMode.Preview; this.originalAuthor = { name: currentUser.specialDisplayName ?? currentUser.login, - iconPath: currentUser.avatarUrl ? vscode.Uri.parse(`${currentUser.avatarUrl}&s=64`) : undefined, + iconPath: (currentUser.avatarUrl && DataUri.isGitHubDotComAvatar(currentUser.avatarUrl)) ? vscode.Uri.parse(`${currentUser.avatarUrl}&s=64`) : undefined, }; this.label = isDraft ? vscode.l10n.t('Pending') : undefined; this.state = isDraft ? vscode.CommentState.Draft : vscode.CommentState.Published; @@ -238,12 +238,12 @@ export class GHPRComment extends CommentBase { this.rawComment = comment; this.originalAuthor = { name: comment.user?.specialDisplayName ?? comment.user!.login, - iconPath: comment.user && comment.user.avatarUrl ? vscode.Uri.parse(comment.user.avatarUrl) : undefined, + iconPath: (comment.user && comment.user.avatarUrl && DataUri.isGitHubDotComAvatar(comment.user.avatarUrl)) ? vscode.Uri.parse(comment.user.avatarUrl) : undefined, }; const url = vscode.Uri.parse(comment.url); this.githubRepository = githubRepositories?.find(repo => repo.remote.host === url.authority); - const avatarUrisPromise = comment.user ? DataUri.avatarCirclesAsImageDataUris(context, [comment.user], 28, 28) : Promise.resolve([]); + const avatarUrisPromise = (comment.user && DataUri.isGitHubDotComAvatar(comment.user.avatarUrl)) ? DataUri.avatarCirclesAsImageDataUris(context, [comment.user], 28, 28) : Promise.resolve([]); this.doSetBody(comment.body, !comment.user).then(async () => { // only refresh if there's no user. If there's a user, we'll refresh in the then. const avatarUris = await avatarUrisPromise; if (avatarUris.length > 0) { diff --git a/src/github/pullRequestGitHelper.ts b/src/github/pullRequestGitHelper.ts index 74239cf974..7ae4031ce4 100644 --- a/src/github/pullRequestGitHelper.ts +++ b/src/github/pullRequestGitHelper.ts @@ -125,6 +125,7 @@ export class PullRequestGitHelper { // Make sure we aren't already on this branch if (repository.state.HEAD?.name === branch.name) { Logger.appendLine(`Tried to checkout ${localBranchName}, but branch is already checked out.`, PullRequestGitHelper.ID); + await PullRequestGitHelper.associateBranchWithPullRequest(repository, pullRequest, localBranchName); return; } diff --git a/src/github/pullRequestModel.ts b/src/github/pullRequestModel.ts index f37f2feda8..c6c0b18f58 100644 --- a/src/github/pullRequestModel.ts +++ b/src/github/pullRequestModel.ts @@ -13,7 +13,7 @@ import { ConflictResolutionModel } from './conflictResolutionModel'; import { CredentialStore } from './credentials'; import { showEmptyCommitWebview } from './emptyCommitWebview'; import { FolderRepositoryManager } from './folderRepositoryManager'; -import { GitHubRepository, GraphQLError, GraphQLErrorType } from './githubRepository'; +import { GitHubRepository } from './githubRepository'; import { AddCommentResponse, AddReactionResponse, @@ -66,7 +66,7 @@ import { ReviewEventEnum, } from './interface'; import { IssueChangeEvent, IssueModel } from './issueModel'; -import { compareCommits } from './loggingOctokit'; +import { compareCommits, GraphQLError, GraphQLErrorType } from './loggingOctokit'; import { convertRESTPullRequestToRawPullRequest, convertRESTReviewEvent, @@ -344,11 +344,11 @@ export class PullRequestModel extends IssueModel implements IPullRe let rejectMessage: string | undefined; if (this.isActive) { localHead = repository.state.HEAD?.commit; - remoteHead = (await this.githubRepository.getPullRequest(this.number))?.head?.sha; + remoteHead = (await this.githubRepository.getPullRequest(this.number, 'PullRequestModel.approve'))?.head?.sha; rejectMessage = vscode.l10n.t('The remote head of the pull request branch has changed. Please pull the latest changes from the remote branch before approving.'); } else { localHead = this.head?.sha; - remoteHead = (await this.githubRepository.getPullRequest(this.number))?.head?.sha; + remoteHead = (await this.githubRepository.getPullRequest(this.number, 'PullRequestModel.approve'))?.head?.sha; rejectMessage = vscode.l10n.t('The remote head of the pull request branch has changed. Please refresh the pull request before approving.'); } @@ -751,7 +751,7 @@ export class PullRequestModel extends IssueModel implements IPullRe pullRequestId: this.graphNodeId, pullRequestReviewId: pendingReviewId, startLine: startLine === endLine ? undefined : startLine, - line: (endLine === undefined) ? 0 : endLine, + line: endLine, side, subjectType: (startLine === undefined || endLine === undefined) ? SubjectType.FILE : SubjectType.LINE } diff --git a/src/github/pullRequestOverview.ts b/src/github/pullRequestOverview.ts index c669a47976..6019339ed2 100644 --- a/src/github/pullRequestOverview.ts +++ b/src/github/pullRequestOverview.ts @@ -4,8 +4,9 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; +import * as crypto from 'crypto'; import * as vscode from 'vscode'; -import { OpenCommitChangesArgs } from '../../common/views'; +import { OpenCommitChangesArgs, OpenLocalFileArgs } from '../../common/views'; import { openPullRequestOnGitHub } from '../commands'; import { getCopilotApi } from './copilotApi'; import { SessionIdForPr } from './copilotRemoteAgent'; @@ -26,7 +27,7 @@ import { IssueOverviewPanel, panelKey } from './issueOverview'; import { isCopilotOnMyBehalf, PullRequestModel } from './pullRequestModel'; import { PullRequestReviewCommon, ReviewContext } from './pullRequestReviewCommon'; import { branchPicks, pickEmail, reviewersQuickPick } from './quickPicks'; -import { parseReviewers } from './utils'; +import { parseReviewers, processDiffLinks, processPermalinks } from './utils'; import { CancelCodingAgentReply, ChangeBaseReply, ChangeReviewersReply, DeleteReviewResult, MergeArguments, MergeResult, PullRequest, ReadyForReviewAndMergeContext, ReadyForReviewContext, ReviewCommentContext, ReviewType, UnresolvedIdentity } from './views'; import { debounce } from '../common/async'; import { COPILOT_ACCOUNTS, IComment } from '../common/comment'; @@ -63,6 +64,7 @@ export class PullRequestOverviewPanel extends IssueOverviewPanel | undefined; + private _resolveCommentThreadQueue: Promise = Promise.resolve(); public static override async createOrShow( telemetry: ITelemetry, @@ -233,6 +235,38 @@ export class PullRequestOverviewPanel extends IssueOverviewPanel { + if (!bodyHTML) { + return bodyHTML; + } + // Check cache first, otherwise fetch raw file changes + const rawFileChanges = this._item.rawFileChanges ?? await this._item.getRawFileChangesInfo(); + + // Create hash-to-filename mapping for diff links + const hashMap: Record = {}; + rawFileChanges.forEach(file => { + const hash = crypto.createHash('sha256').update(file.filename).digest('hex'); + hashMap[hash] = file.filename; + }); + + let result = await processPermalinks( + bodyHTML, + this._item.githubRepository, + this._item.githubRepository.rootUri + ); + result = await processDiffLinks( + result, + this._item.githubRepository, + hashMap, + this._item.number + ); + return result; + } + protected override onDidChangeViewState(e: vscode.WebviewPanelOnDidChangeViewStateEvent): void { super.onDidChangeViewState(e); this.setVisibilityContext(); @@ -274,6 +308,11 @@ export class PullRequestOverviewPanel extends IssueOverviewPanel COPILOT_ACCOUNTS[user.login]); const isCopilotAlreadyReviewer = this._existingReviewers.some(reviewer => !isITeam(reviewer.reviewer) && reviewer.reviewer.login === COPILOT_REVIEWER); - const baseContext = this.getInitializeContext(currentUser, pullRequest, timelineEvents, repositoryAccess, viewerCanEdit, users); + const baseContext = await this.getInitializeContext(currentUser, pullRequest, timelineEvents, repositoryAccess, viewerCanEdit, users); this.preLoadInfoNotRequiredForOverview(pullRequest); @@ -530,6 +569,8 @@ export class PullRequestOverviewPanel extends IssueOverviewPanel { - return this._item.getTimelineEvents(); + protected override async _getTimeline(): Promise { + const events = await this._item.getTimelineEvents(); + return this.processTimelineEvents(events); } private async openDiff(message: IRequestMessage<{ comment: IComment }>): Promise { @@ -633,6 +675,36 @@ export class PullRequestOverviewPanel extends IssueOverviewPanel): Promise { + try { + const { file, startLine } = message.args; + const fileChanges = await this._item.getFileChangesInfo(); + const change = fileChanges.find( + fileChange => fileChange.fileName === file || fileChange.previousFileName === file, + ); + + if (change) { + + const pathSegments = file.split('/'); + // GitHub line numbers are 1-indexed, VSCode selection API is 0-indexed + await PullRequestModel.openDiff( + this._folderRepositoryManager, + this._item, + change, + pathSegments[pathSegments.length - 1], + startLine - 1, + ); + return; + } + Logger.warn(`Could not find file ${file} in PR changes`, PullRequestOverviewPanel.ID); + } catch (e) { + Logger.error(`Open diff from link failed: ${formatError(e)}`, PullRequestOverviewPanel.ID); + } + + // Fallback to opening external URL + await vscode.env.openExternal(vscode.Uri.parse(message.args.href)); + } + private async openSessionLog(message: IRequestMessage<{ link: SessionLinkInfo }>): Promise { try { const resource = SessionIdForPr.getResource(this._item.number, message.args.link.sessionIndex); @@ -714,20 +786,32 @@ export class PullRequestOverviewPanel extends IssueOverviewPanel) { - try { - if (message.args.toResolve) { - await this._item.resolveReviewThread(message.args.threadId); - } - else { - await this._item.unresolveReviewThread(message.args.threadId); - } - const timelineEvents = await this._getTimeline(); - this._replyMessage(message, timelineEvents); - } catch (e) { - vscode.window.showErrorMessage(e); - this._replyMessage(message, undefined); - } + private resolveCommentThread(message: IRequestMessage<{ threadId: string, toResolve: boolean, thread: IComment[] }>) { + // Serialize resolve/unresolve operations so that concurrent calls don't race. + // Each call fetches the full timeline after its mutation, and without serialization + // a stale timeline response from an earlier call can overwrite a newer one. + // Normalize any prior rejection so one unexpected failure does not permanently + // block later resolve/unresolve requests from running. + this._resolveCommentThreadQueue = this._resolveCommentThreadQueue + .catch(error => { + Logger.error(`Resolve comment thread queue failed: ${formatError(error)}`, PullRequestOverviewPanel.ID); + }) + .then(async () => { + try { + if (message.args.toResolve) { + await this._item.resolveReviewThread(message.args.threadId); + } + else { + await this._item.unresolveReviewThread(message.args.threadId); + } + const timelineEvents = await this._getTimeline(); + this._replyMessage(message, timelineEvents); + } catch (e) { + Logger.error(`Failed to ${message.args.toResolve ? 'resolve' : 'unresolve'} comment thread: ${formatError(e)}`, PullRequestOverviewPanel.ID); + vscode.window.showErrorMessage(vscode.l10n.t('Failed to {0} comment thread: {1}', message.args.toResolve ? 'resolve' : 'unresolve', formatError(e))); + this._replyMessage(message, undefined); + } + }); } private checkoutPullRequest(message: IRequestMessage): void { @@ -1015,7 +1099,7 @@ export class PullRequestOverviewPanel extends IssueOverviewPanel(quickPick.onDidAccept).then(() => { - return quickPick.selectedItems[0]?.branch; + return (quickPick.selectedItems[0] ?? quickPick.activeItems[0])?.branch; }); const hidePromise = asPromise(quickPick.onDidHide); + await updateItems(undefined); + + quickPick.busy = false; const selectedBranch = await Promise.race([acceptPromise, hidePromise]); quickPick.busy = true; quickPick.enabled = false; diff --git a/src/github/pullRequestReviewCommon.ts b/src/github/pullRequestReviewCommon.ts index fb7ea23785..4113ae3398 100644 --- a/src/github/pullRequestReviewCommon.ts +++ b/src/github/pullRequestReviewCommon.ts @@ -10,7 +10,7 @@ import { IAccount, isITeam, ITeam, MergeMethod, PullRequestMergeability, reviewe import { BranchInfo } from './pullRequestGitHelper'; import { PullRequestModel } from './pullRequestModel'; import { ConvertToDraftReply, PullRequest, ReadyForReviewReply, ReviewType, SubmitReviewReply } from './views'; -import { DEFAULT_DELETION_METHOD, PR_SETTINGS_NAMESPACE, SELECT_LOCAL_BRANCH, SELECT_REMOTE } from '../common/settingKeys'; +import { DEFAULT_DELETION_METHOD, PR_SETTINGS_NAMESPACE, SELECT_LOCAL_BRANCH, SELECT_REMOTE, SELECT_WORKTREE } from '../common/settingKeys'; import { ReviewEvent, TimelineEvent } from '../common/timelineEvent'; import { Schemes } from '../common/uri'; import { formatError } from '../common/utils'; @@ -289,9 +289,20 @@ export namespace PullRequestReviewCommon { } interface SelectedAction { - type: 'remoteHead' | 'local' | 'remote' | 'suspend' + type: 'remoteHead' | 'local' | 'remote' | 'suspend' | 'worktree' + /** Path to the worktree directory to remove. Only used when type is 'worktree'. */ + worktreePath?: string; }; + function isWorktreeInWorkspace(worktreePath: vscode.Uri): boolean { + const worktreeFsPath = worktreePath.fsPath; + return !!vscode.workspace.workspaceFolders?.some(folder => { + const folderPath = folder.uri.fsPath; + return folderPath === worktreeFsPath || + (process.platform === 'win32' && folderPath.toLowerCase() === worktreeFsPath.toLowerCase()); + }); + } + export async function deleteBranch(folderRepositoryManager: FolderRepositoryManager, item: PullRequestModel): Promise<{ isReply: boolean, message: any }> { const branchInfo = await folderRepositoryManager.getBranchNameForPullRequest(item); const actions: (vscode.QuickPickItem & SelectedAction)[] = []; @@ -333,6 +344,19 @@ export namespace PullRequestReviewCommon { picked: !!preferredRemoteDeletionMethod, }); } + + const worktreePath = folderRepositoryManager.getWorktreeForBranch(branchInfo.branch); + if (worktreePath && !isWorktreeInWorkspace(worktreePath)) { + const preferredWorktreeDeletion = vscode.workspace + .getConfiguration(PR_SETTINGS_NAMESPACE) + .get(`${DEFAULT_DELETION_METHOD}.${SELECT_WORKTREE}`); + actions.push({ + label: vscode.l10n.t('Remove worktree {0}', worktreePath.fsPath), + type: 'worktree', + worktreePath: worktreePath.fsPath, + picked: !!preferredWorktreeDeletion, + }); + } } if (vscode.env.remoteName === 'codespaces') { @@ -384,7 +408,16 @@ export namespace PullRequestReviewCommon { const isBranchActive = item.equals(folderRepositoryManager.activePullRequest) || (folderRepositoryManager.repository.state.HEAD?.name && folderRepositoryManager.repository.state.HEAD.name === branchInfo?.branch); const deletedBranchTypes: string[] = []; - const promises = selectedActions.map(async action => { + // Remove worktree first, before deleting the branch, since a branch checked out + // in a worktree cannot be deleted. + const worktreeAction = selectedActions.find(a => a.type === 'worktree'); + if (worktreeAction?.worktreePath) { + await folderRepositoryManager.removeWorktree(worktreeAction.worktreePath); + deletedBranchTypes.push(worktreeAction.type); + } + + const remainingActions = selectedActions.filter(a => a.type !== 'worktree'); + const promises = remainingActions.map(async action => { switch (action.type) { case 'remoteHead': await folderRepositoryManager.deleteBranch(item); @@ -497,6 +530,17 @@ export namespace PullRequestReviewCommon { selectedActions.push({ type: 'remote' }); } + // Remove worktree if preference is set + const deleteWorktree = vscode.workspace + .getConfiguration(PR_SETTINGS_NAMESPACE) + .get(`${DEFAULT_DELETION_METHOD}.${SELECT_WORKTREE}`, false); + if (branchInfo && deleteWorktree) { + const worktreePath = folderRepositoryManager.getWorktreeForBranch(branchInfo.branch); + if (worktreePath && !isWorktreeInWorkspace(worktreePath)) { + selectedActions.push({ type: 'worktree', worktreePath: worktreePath.fsPath }); + } + } + // Execute all deletions in parallel const deletedBranchTypes = await performBranchDeletion(folderRepositoryManager, item, defaultBranch, branchInfo!, selectedActions); diff --git a/src/github/quickPicks.ts b/src/github/quickPicks.ts index 1da63ea1a1..52f681d4f4 100644 --- a/src/github/quickPicks.ts +++ b/src/github/quickPicks.ts @@ -482,19 +482,7 @@ function getRecentlyUsedBranches(folderRepoManager: FolderRepositoryManager, own return state.branches[repoKey] || []; } -export async function branchPicks(githubRepository: GitHubRepository, folderRepoManager: FolderRepositoryManager, changeRepoMessage: string | undefined, isBase: boolean, prefix: string | undefined): Promise<(vscode.QuickPickItem & { remote?: RemoteInfo, branch?: string })[]> { - let branches: (string | Ref)[]; - if (isBase) { - // For the base, we only want to show branches from GitHub. - branches = await githubRepository.listBranches(githubRepository.remote.owner, githubRepository.remote.repositoryName, prefix); - } else { - // For the compare, we only want to show local branches. - branches = (await folderRepoManager.repository.getBranches({ remote: false })).filter(branch => branch.name); - } - - - const branchNames = branches.map(branch => typeof branch === 'string' ? branch : branch.name!); - +function buildBranchPickItems(branchNames: string[], githubRepository: GitHubRepository, folderRepoManager: FolderRepositoryManager, changeRepoMessage: string | undefined, isBase: boolean): (vscode.QuickPickItem & { remote?: RemoteInfo, branch?: string })[] { // Get recently used branches for base branches only let recentBranches: string[] = []; let otherBranches: string[] = branchNames; @@ -554,4 +542,29 @@ export async function branchPicks(githubRepository: GitHubRepository, folderRepo }); } return branchPicks; +} + +export function cachedBranchPicks(githubRepository: GitHubRepository, folderRepoManager: FolderRepositoryManager, changeRepoMessage: string | undefined, isBase: boolean): (vscode.QuickPickItem & { remote?: RemoteInfo, branch?: string })[] | undefined { + if (!isBase) { + return undefined; + } + const cached = githubRepository.getCachedBranches(githubRepository.remote.owner, githubRepository.remote.repositoryName); + if (!cached) { + return undefined; + } + return buildBranchPickItems(cached, githubRepository, folderRepoManager, changeRepoMessage, isBase); +} + +export async function branchPicks(githubRepository: GitHubRepository, folderRepoManager: FolderRepositoryManager, changeRepoMessage: string | undefined, isBase: boolean, prefix: string | undefined): Promise<(vscode.QuickPickItem & { remote?: RemoteInfo, branch?: string })[]> { + let branches: (string | Ref)[]; + if (isBase) { + // For the base, we only want to show branches from GitHub. + branches = await githubRepository.listBranches(githubRepository.remote.owner, githubRepository.remote.repositoryName, prefix); + } else { + // For the compare, we only want to show local branches. + branches = (await folderRepoManager.repository.getBranches({ remote: false })).filter(branch => branch.name); + } + + const branchNames = branches.map(branch => typeof branch === 'string' ? branch : branch.name!); + return buildBranchPickItems(branchNames, githubRepository, folderRepoManager, changeRepoMessage, isBase); } \ No newline at end of file diff --git a/src/github/repositoriesManager.ts b/src/github/repositoriesManager.ts index e2fce7a325..beff98508b 100644 --- a/src/github/repositoriesManager.ts +++ b/src/github/repositoriesManager.ts @@ -91,10 +91,39 @@ export class RepositoriesManager extends Disposable { folderManager.onDidChangeAnyPullRequests(e => this._onDidChangeAnyPullRequests.fire(e)), folderManager.onDidAddPullRequest(e => this._onDidAddPullRequest.fire(e)), folderManager.onDidChangeGithubRepositories(() => this._onDidAddAnyGitHubRepository.fire(folderManager)), + folderManager.repository.state.onDidChange(() => this.checkWorktreeChanges(folderManager.repository)), ]; this._subs.set(folderManager, disposables); } + private _previousWorktrees: Map> = new Map(); + + private checkWorktreeChanges(repo: Repository): void { + const worktrees = repo.state.worktrees; + if (!worktrees) { + return; + } + + const repoKey = repo.rootUri.toString(); + const currentPaths = new Set(worktrees.map(wt => vscode.Uri.file(wt.path).toString())); + const previousPaths = this._previousWorktrees.get(repoKey); + this._previousWorktrees.set(repoKey, currentPaths); + + if (!previousPaths) { + return; + } + + for (const previousPath of previousPaths) { + if (!currentPaths.has(previousPath)) { + const folderManager = this._folderManagers.find(m => m.repository.rootUri.toString() === previousPath); + if (folderManager) { + Logger.appendLine(`Removing folder manager for removed worktree ${previousPath}`, RepositoriesManager.ID); + this.removeRepo(folderManager.repository); + } + } + } + } + insertFolderManager(folderManager: FolderRepositoryManager) { this.registerFolderListeners(folderManager); @@ -127,7 +156,7 @@ export class RepositoriesManager extends Disposable { const folderManager = this._folderManagers[existingFolderManagerIndex]; disposeAll(this._subs.get(folderManager)!); this._subs.delete(folderManager); - this._folderManagers.splice(existingFolderManagerIndex); + this._folderManagers.splice(existingFolderManagerIndex, 1); folderManager.dispose(); this.updateActiveReviewCount(); this._onDidChangeFolderRepositories.fire({}); diff --git a/src/github/utils.ts b/src/github/utils.ts index f1e7f62e22..62035f7119 100644 --- a/src/github/utils.ts +++ b/src/github/utils.ts @@ -55,7 +55,7 @@ import { Remote } from '../common/remote'; import { GITHUB_ENTERPRISE, OVERRIDE_DEFAULT_BRANCH, PR_SETTINGS_NAMESPACE, URI } from '../common/settingKeys'; import * as Common from '../common/timelineEvent'; import { DataUri, toOpenIssueWebviewUri, toOpenPullRequestWebviewUri } from '../common/uri'; -import { escapeRegExp, gitHubLabelColor, stringReplaceAsync, uniqBy } from '../common/utils'; +import { escapeRegExp, gitHubLabelColor, processDiffLinks as processDiffLinksCore, processPermalinks as processPermalinksCore, stringReplaceAsync, uniqBy } from '../common/utils'; export const ISSUE_EXPRESSION = /(([A-Za-z0-9_.\-]+)\/([A-Za-z0-9_.\-]+))?(#|GH-)([1-9][0-9]*)($|\b)/; export const ISSUE_OR_URL_EXPRESSION = /(https?:\/\/github\.com\/(([^\s]+)\/([^\s]+))\/([^\s]+\/)?(issues|pull)\/([0-9]+)(#issuecomment\-([0-9]+))?)|(([A-Za-z0-9_.\-]+)\/([A-Za-z0-9_.\-]+))?(#|GH-)([1-9][0-9]*)($|\b)/; @@ -104,6 +104,10 @@ export function threadRange(startLine: number, endLine: number, endCharacter?: n export async function setReplyAuthor(thread: vscode.CommentThread | vscode.CommentThread2, currentUser: IAccount, context: vscode.ExtensionContext) { if (currentUser.avatarUrl) { const thread2 = thread as vscode.CommentThread2; + if (!DataUri.isGitHubDotComAvatar(currentUser.avatarUrl)) { + thread2.canReply = { name: currentUser.name ?? currentUser.login, iconPath: undefined }; + return; + } thread2.canReply = { name: currentUser.name ?? currentUser.login, iconPath: vscode.Uri.parse(currentUser.avatarUrl) }; const uri = await DataUri.avatarCirclesAsImageDataUris(context, [currentUser], 28, 28); thread2.canReply = { name: currentUser.name ?? currentUser.login, iconPath: uri[0] }; @@ -330,6 +334,61 @@ async function transformHtmlUrlsToExtensionUrls(body: string, githubRepository: }); } +/** + * Process GitHub blob permalinks in HTML and add data attributes for local file handling. + * Finds blob permalinks (e.g., /blob/[sha]/file.ts#L10), checks if files exist locally, + * and adds data attributes to enable clicking to open local files. + */ +export async function processPermalinks( + bodyHTML: string, + githubRepository: GitHubRepository, + rootUri: vscode.Uri +): Promise { + try { + const repoName = githubRepository.remote.repositoryName; + const authority = githubRepository.remote.gitProtocol.url.authority; + + // Create file existence check callback + const fileExistsCheck = async (filePath: string): Promise => { + try { + const localFileUri = vscode.Uri.joinPath(rootUri, filePath); + const stat = await vscode.workspace.fs.stat(localFileUri); + return stat.type === vscode.FileType.File; + } catch { + return false; + } + }; + + return await processPermalinksCore(bodyHTML, repoName, authority, fileExistsCheck); + } catch (error) { + Logger.error(`Failed to process blob permalinks in HTML: ${error}`, 'processPermalinks'); + return bodyHTML; + } +} + +/** + * Process GitHub diff permalinks in HTML and add data attributes for local file handling. + * Finds diff permalinks (e.g., /pull/123/files#diff-[hash]R10), maps hashes to filenames, + * and adds data attributes to enable clicking to open diff views. + */ +export async function processDiffLinks( + bodyHTML: string, + githubRepository: GitHubRepository, + hashMap: Record, + prNumber: number +): Promise { + try { + const repoName = githubRepository.remote.repositoryName; + const repoOwner = githubRepository.remote.owner; + const authority = githubRepository.remote.gitProtocol.url.authority; + + return await processDiffLinksCore(bodyHTML, repoOwner, repoName, authority, hashMap, prNumber); + } catch (error) { + Logger.error(`Failed to process diff permalinks in HTML: ${error}`, 'processDiffLinks'); + return bodyHTML; + } +} + export function convertRESTPullRequestToRawPullRequest( pullRequest: | OctokitCommon.PullsGetResponseData @@ -1882,4 +1941,4 @@ export async function extractRepoFromQuery(folderManager: FolderRepositoryManage } return undefined; -} \ No newline at end of file +} diff --git a/src/github/worktree.ts b/src/github/worktree.ts new file mode 100644 index 0000000000..ca466a8e8a --- /dev/null +++ b/src/github/worktree.ts @@ -0,0 +1,128 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import * as path from 'path'; +import * as vscode from 'vscode'; +import { FolderRepositoryManager } from './folderRepositoryManager'; +import { PullRequestModel } from './pullRequestModel'; +import { Repository } from '../api/api'; +import { commands } from '../common/executeCommands'; +import Logger from '../common/logger'; +import { ITelemetry } from '../common/telemetry'; + +const logId = 'Worktree'; + +/** + * Checks out a pull request in a new git worktree. + * @param telemetry Telemetry instance for tracking usage + * @param folderManager The folder repository manager + * @param pullRequestModel The pull request to checkout + * @param repository Optional repository to use (if not provided, uses folderManager.repository) + */ +export async function checkoutPRInWorktree( + telemetry: ITelemetry, + folderManager: FolderRepositoryManager, + pullRequestModel: PullRequestModel, + repository: Repository | undefined +): Promise { + // Validate that the PR has a valid head branch + if (!pullRequestModel.head) { + vscode.window.showErrorMessage(vscode.l10n.t('Unable to checkout pull request: missing head branch information.')); + return; + } + + const prHead = pullRequestModel.head; + const repositoryToUse = repository || folderManager.repository; + + /* __GDPR__ + "pr.checkoutInWorktree" : {} + */ + telemetry.sendTelemetryEvent('pr.checkoutInWorktree'); + + // Prepare for operations + const repoRootPath = repositoryToUse.rootUri.fsPath; + const parentDir = path.dirname(repoRootPath); + const defaultWorktreePath = path.join(parentDir, `pr-${pullRequestModel.number}`); + const branchName = prHead.ref; + const remoteName = pullRequestModel.remote.remoteName; + + // Ask user for worktree location first (not in progress) + const worktreeUri = await vscode.window.showSaveDialog({ + defaultUri: vscode.Uri.file(defaultWorktreePath), + title: vscode.l10n.t('Select Worktree Location'), + saveLabel: vscode.l10n.t('Create Worktree'), + }); + + if (!worktreeUri) { + return; // User cancelled + } + + const worktreePath = worktreeUri.fsPath; + const trackedBranchName = `${remoteName}/${branchName}`; + + try { + // Check if the createWorktree API is available + if (!repositoryToUse.createWorktree) { + throw new Error(vscode.l10n.t('Git worktree API is not available. Please update VS Code to the latest version.')); + } + + // Start progress for fetch and worktree creation + await vscode.window.withProgress( + { + location: vscode.ProgressLocation.Notification, + title: vscode.l10n.t('Creating worktree for Pull Request #{0}...', pullRequestModel.number), + }, + async () => { + // Fetch the PR branch first + await repositoryToUse.fetch({ remote: remoteName, ref: branchName }); + + // Check if the branch already exists locally + let branchExists = false; + try { + await repositoryToUse.getBranch(branchName); + branchExists = true; + } catch { + // Branch doesn't exist locally, we'll create it + branchExists = false; + } + + // Use the git extension's createWorktree API + // If branch already exists, don't specify the branch parameter to avoid "branch already exists" error + if (branchExists) { + await repositoryToUse.createWorktree!({ + path: worktreePath, + commitish: branchName + }); + } else { + await repositoryToUse.createWorktree!({ + path: worktreePath, + commitish: trackedBranchName, + branch: branchName + }); + } + } + ); + + // Ask user how they want to open the worktree (modal dialog) + const openInNewWindow = vscode.l10n.t('New Window'); + const openInCurrentWindow = vscode.l10n.t('Current Window'); + const result = await vscode.window.showInformationMessage( + vscode.l10n.t('Worktree created for Pull Request #{0}. How would you like to open it?', pullRequestModel.number), + { modal: true }, + openInNewWindow, + openInCurrentWindow + ); + + if (result === openInNewWindow) { + await commands.openFolder(worktreeUri, { forceNewWindow: true }); + } else if (result === openInCurrentWindow) { + await commands.openFolder(worktreeUri, { forceNewWindow: false }); + } + } catch (e) { + const errorMessage = e instanceof Error ? e.message : String(e); + Logger.error(`Failed to create worktree: ${errorMessage}`, logId); + vscode.window.showErrorMessage(vscode.l10n.t('Failed to create worktree: {0}', errorMessage)); + } +} diff --git a/src/issues/issuesView.ts b/src/issues/issuesView.ts index 3774b9a530..f43a04f15a 100644 --- a/src/issues/issuesView.ts +++ b/src/issues/issuesView.ts @@ -8,7 +8,7 @@ import * as vscode from 'vscode'; import { issueBodyHasLink } from './issueLinkLookup'; import { IssueItem, QueryGroup, StateManager } from './stateManager'; import { commands, contexts } from '../common/executeCommands'; -import { ISSUE_AVATAR_DISPLAY, ISSUES_SETTINGS_NAMESPACE } from '../common/settingKeys'; +import { ISSUE_AVATAR_DISPLAY, IssueAvatarDisplay, ISSUES_SETTINGS_NAMESPACE } from '../common/settingKeys'; import { DataUri } from '../common/uri'; import { groupBy } from '../common/utils'; import { FolderRepositoryManager, ReposManagerState } from '../github/folderRepositoryManager'; @@ -91,28 +91,36 @@ export class IssuesTreeData const avatarDisplaySetting = vscode.workspace .getConfiguration(ISSUES_SETTINGS_NAMESPACE, null) - .get<'author' | 'assignee'>(ISSUE_AVATAR_DISPLAY, 'author'); - - let avatarUser: IAccount | undefined; - if ((avatarDisplaySetting === 'assignee') && element.assignees && (element.assignees.length > 0)) { - avatarUser = element.assignees[0]; - } else if (avatarDisplaySetting === 'author') { - avatarUser = element.author; - } + .get(ISSUE_AVATAR_DISPLAY, 'author'); + + if (avatarDisplaySetting === 'state') { + treeItem.iconPath = element.isOpen + ? new vscode.ThemeIcon('issues', new vscode.ThemeColor('issues.open')) + : new vscode.ThemeIcon('issue-closed', new vscode.ThemeColor('issues.closed')); + } else if (avatarDisplaySetting === 'generic') { + treeItem.iconPath = new vscode.ThemeIcon('issues'); + } else { + let avatarUser: IAccount | undefined; + if ((avatarDisplaySetting === 'assignee') && element.assignees && (element.assignees.length > 0)) { + avatarUser = element.assignees[0]; + } else { + avatarUser = element.author; + } - if (avatarUser) { - // For enterprise, use placeholder icon instead of trying to fetch avatar - if (!DataUri.isGitHubDotComAvatar(avatarUser.avatarUrl)) { - treeItem.iconPath = new vscode.ThemeIcon('github'); + if (avatarUser) { + // For enterprise, use placeholder icon instead of trying to fetch avatar + if (!DataUri.isGitHubDotComAvatar(avatarUser.avatarUrl)) { + treeItem.iconPath = new vscode.ThemeIcon('github'); + } else { + treeItem.iconPath = (await DataUri.avatarCirclesAsImageDataUris(this.context, [avatarUser], 16, 16))[0] ?? + (element.isOpen + ? new vscode.ThemeIcon('issues', new vscode.ThemeColor('issues.open')) + : new vscode.ThemeIcon('issue-closed', new vscode.ThemeColor('github.issues.closed'))); + } } else { - treeItem.iconPath = (await DataUri.avatarCirclesAsImageDataUris(this.context, [avatarUser], 16, 16))[0] ?? - (element.isOpen - ? new vscode.ThemeIcon('issues', new vscode.ThemeColor('issues.open')) - : new vscode.ThemeIcon('issue-closed', new vscode.ThemeColor('github.issues.closed'))); + // Use GitHub codicon when assignee setting is selected but no assignees exist + treeItem.iconPath = new vscode.ThemeIcon('github'); } - } else { - // Use GitHub codicon when assignee setting is selected but no assignees exist - treeItem.iconPath = new vscode.ThemeIcon('github'); } treeItem.command = { diff --git a/src/issues/stateManager.ts b/src/issues/stateManager.ts index 14316c0818..904e16fddb 100644 --- a/src/issues/stateManager.ts +++ b/src/issues/stateManager.ts @@ -342,23 +342,26 @@ export class StateManager { singleRepoState.issueCollection.set(query.label, items); } } - singleRepoState.maxIssueNumber = await folderManager.getMaxIssue(); + singleRepoState.maxIssueNumber = await folderManager.getMaxIssue(folderManager.repository); singleRepoState.lastHead = folderManager.repository.state.HEAD?.commit; singleRepoState.lastBranch = folderManager.repository.state.HEAD?.name; } - private setIssues(folderManager: FolderRepositoryManager, query: string): Promise { - return new Promise(async resolve => { + private async setIssues(folderManager: FolderRepositoryManager, query: string): Promise { + try { const issues = await folderManager.getIssues(query, { fetchNextPage: false, fetchOnePagePerRepo: true }); + return issues?.items.map(item => { + const issueItem: IssueItem = item as IssueItem; + issueItem.uri = folderManager.repository.rootUri; + return issueItem; + }); + } catch { + // Errors from fetching issues are expected (e.g. network failures). + // Return undefined so the tree shows an empty state for this query. + return undefined; + } finally { this._onDidChangeIssueData.fire(); - resolve( - issues?.items.map(item => { - const issueItem: IssueItem = item as IssueItem; - issueItem.uri = folderManager.repository.rootUri; - return issueItem; - }), - ); - }); + } } private async setCurrentIssueFromBranch(singleRepoState: SingleRepoState, branchName: string, silent: boolean = false) { diff --git a/src/issues/userCompletionProvider.ts b/src/issues/userCompletionProvider.ts index fbd5413cfd..ffc96c9bba 100644 --- a/src/issues/userCompletionProvider.ts +++ b/src/issues/userCompletionProvider.ts @@ -238,7 +238,7 @@ export class UserCompletionProvider implements vscode.CompletionItemProvider { ); if (githubRepo) { - const pr = await githubRepo.getPullRequest(prNumber); + const pr = await githubRepo.getPullRequest(prNumber, 'UserCompletionProvider.provideCompletionItems'); this.cachedForPrNumber = prNumber; this.cachedPrTimelineEvents = await pr!.getTimelineEvents(); } diff --git a/src/lm/skills/address-pr-comments/SKILL.md b/src/lm/skills/address-pr-comments/SKILL.md new file mode 100644 index 0000000000..831dfe3233 --- /dev/null +++ b/src/lm/skills/address-pr-comments/SKILL.md @@ -0,0 +1,72 @@ +--- +name: address-pr-comments +description: "Address review comments (including Copilot comments) on the active pull request. Use when: responding to PR feedback, fixing review comments, resolving PR threads, implementing requested changes from reviewers, addressing code review, fixing PR issues." +argument-hint: "Optionally specify a reviewer name or file to focus on" +--- + +# Address PR Review Comments + +Read the active pull request, identify unresolved review comments and feedback, implement the requested changes, and resolve the threads. + +## When to Use + +- A reviewer has left comments or change requests on the active PR +- You need to systematically work through all open review threads +- You want to respond to or implement reviewer feedback + +## Procedure + +### 1. Read the Active PR + +Call the `github-pull-request_currentActivePullRequest` tool. + +**Refresh logic**: Check whether a refresh is needed before reading: +- Call the tool once *without* `refresh` to get the cached state +- Inspect the `lastUpdatedAt` field in the result +- If the timestamp is **less than 3 minutes ago**, the PR is actively changing - call the tool again with `refresh: true` to ensure you have the latest comments and state +- If the timestamp is older than 3 minutes, proceed with the cached data + +### 2. Identify Unresolved Comments + +From the tool result, collect all feedback that needs action: + +- **`reviewThreads`** array: inline review thread objects with an `id`, `isResolved` flag, `canResolve` flag, `file` path, and nested `comments`. Focus on threads where `isResolved` is `false`. +- **`timelineComments`** array: general PR comments and reviews where `commentType` is `"CHANGES_REQUESTED"` or `"COMMENTED"` + +Group related threads by file (`file` field) to handle them efficiently. + +### 3. Plan Changes + +Before modifying any files: +1. Read each unresolved comment carefully +2. Identify the file and location each comment refers to +3. Determine the minimal correct fix for each, if a fix is needed (not all comments are worthy of a change) +4. Note dependencies between comments (e.g., a rename that affects multiple files) + +### 4. Implement Changes + +Work through the grouped comments file by file: +- Read the relevant file section before editing +- Apply the requested change +- Do not refactor or modify code outside the scope of each comment +- If a comment is unclear or contradictory, note it for a follow-up reply rather than guessing + +### 5. Verify + +After all changes are made: +- Review that each originally unresolved thread has a corresponding code change or a note about why no code change was needed. +- Ensure no unrelated code was modified + +### 6. Resolve Threads + +For each thread that was addressed (either by a code change or by a deliberate decision not to change): +- Call `github-pull-request_resolveReviewThread` with the `id` from the `reviewThreads` array. +- Only resolve threads where `canResolve` is `true`. +- Skip threads that are already resolved (`isResolved: true`) or where `canResolve` is `false`. + +### 7. Summarize + +Provide a concise summary of: +- Which comments were addressed and what changes were made +- Any comments that were intentionally skipped (with reasoning) +- Any follow-up questions for the reviewer diff --git a/src/lm/skills/create-pull-request/SKILL.md b/src/lm/skills/create-pull-request/SKILL.md new file mode 100644 index 0000000000..41af3c3f1e --- /dev/null +++ b/src/lm/skills/create-pull-request/SKILL.md @@ -0,0 +1,98 @@ +--- +name: create-pull-request +description: "Create a GitHub Pull Request from the current or specified branch. Use when: opening a PR, submitting code for review, creating a draft PR, publishing a branch as a pull request, proposing changes to a repository." +argument-hint: "Optionally specify a title, base branch, or whether to create as a draft" +--- + +# Create a GitHub Pull Request + +Gather the necessary information, prepare a clear title and description, then call the tool to open the pull request. + +## When to Use + +- The user wants to open a PR for their current or a specified branch +- The user has finished a feature or fix and wants to submit it for review +- The user wants to create a draft PR to share work in progress +- The user asks to "open a PR", "create a pull request", or "submit for review" + +## Procedure + +### 1. Gather Information + +Determine the required parameters before calling the tool: + +- **Head branch**: If the user has not specified a branch, use workspace or git context to find the current branch name. Do not use `owner:branch` format - pass just the branch name (e.g. `my-feature`). +- **Base branch**: If the user has not specified a base branch, omit it and let the tool use the repository's default branch. +- **Title**: If the user has not provided a title, derive one from the branch name, recent commits, or the user's description of their work (see Best Practices below). +- **Body**: If the user has not provided a description, prepare a concise summary of what changed and why (see Best Practices below). +- **Draft**: Ask or infer whether the PR should be a draft. Default to non-draft unless the user indicates the work is not ready for review. + +### 2. Check for Uncommitted or Unpushed Changes + +Before creating the PR, inspect the working tree state. If you need to run git commands, give an explanation for why the command needs to be run. + +1. **Check for uncommitted changes**: Use the git tool or VS Code SCM context to determine whether there are staged or unstaged file changes. If yes: + - Ask the user if they want to commit these changes before opening the PR. + - If they do, help them write a commit message and commit the changes (`git add -A && git commit -m ""`). + - If they decline, proceed only if there are already commits on the branch that are ahead of the base - otherwise there is nothing to put in the PR. + +2. **Check for unpushed commits**: Determine whether the local branch has commits that have not been pushed to the remote (i.e. the branch is ahead of its upstream). If yes: + - Ask the user if they want to push before opening the PR, or let them know the tool will attempt to push automatically if needed. + - If pushing manually is preferred, run `git push` (or `git push --set-upstream origin ` if no upstream is set yet) before calling the tool. + +3. **Confirm the branch is on the remote**: The `create_pull_request` tool requires the head branch to be present on the remote. If it is not, push it first. + +If all changes are already committed and pushed, proceed directly to the next step. + +### 3. Prepare PR Details + +Write a good title and description if the user has not provided them: + +**Title**: Use imperative mood, keep it under 72 characters, and describe *what* the PR does (e.g. `Add retry logic for failed API requests`). + +**Body**: Include: +- A short summary of what changed and why +- Any relevant issue references (e.g. `Fixes #123`) +- Notable implementation decisions, if useful for the reviewer + +### 4. Call the Tool + +Use the `github-pull-request_create_pull_request` tool with the gathered parameters: + +``` +github-pull-request_create_pull_request({ + title: '', + head: '', // branch name only, not owner:branch + body: '', // optional but recommended + base: '', // optional; omit to use repo default + draft: false, // set true for work-in-progress + headOwner: '', // optional; omit if same as repo owner + repo: { owner: '', name: '' } // optional +}) +``` + +### 5. Confirm Result + +After the tool returns successfully: + +- Report the PR number and URL to the user as a markdown link. The link should be a VS Code URI like `vscode-insiders://github.vscode-pull-request-github/open-pull-request-webview?uri=https://github.com/microsoft/vscode-css-languageservice/pull/460` or `vscode://github.vscode-pull-request-github/open-pull-request-webview?uri=https://github.com/microsoft/vscode-css-languageservice/pull/460`. +- Mention the base branch the PR targets. +- If the PR was created as a draft, remind the user to mark it ready for review when appropriate. + +## Best Practices + +### Titles +- Use the imperative mood: `Fix`, `Add`, `Update`, `Remove`, `Refactor` - not `Fixed`, `Adding`, etc. +- Be specific: `Fix null pointer in user login flow` beats `Fix bug`. +- Keep it under 72 characters so it displays cleanly in GitHub and email notifications. + +### Descriptions +- Start with a one-sentence summary. +- Explain *why* the change is needed, not just *what* it does - reviewers benefit from context. +- Reference related issues with `Fixes #` or `Closes #` to auto-close them on merge. +- If the change is large, add a brief list of the main files or components touched. + +### Draft PRs +- Use `draft: true` when the code is not yet ready for formal review (e.g. work in progress, awaiting feedback on approach, CI not yet passing). +- Draft PRs are visible to collaborators but will not show as review-requested until marked ready. +- Suggest using a draft when the user mentions they are still working on it or just want early feedback. diff --git a/src/lm/tools/activePullRequestTool.ts b/src/lm/tools/activePullRequestTool.ts index 90cc3f4aaa..78f4911941 100644 --- a/src/lm/tools/activePullRequestTool.ts +++ b/src/lm/tools/activePullRequestTool.ts @@ -11,6 +11,10 @@ import { CommentEvent, EventType, ReviewEvent } from '../../common/timelineEvent import { PullRequestModel } from '../../github/pullRequestModel'; import { RepositoriesManager } from '../../github/repositoriesManager'; +interface PullRequestToolParams { + refresh?: boolean; +} + export abstract class PullRequestTool implements vscode.LanguageModelTool { constructor( protected readonly folderManagers: RepositoriesManager @@ -42,13 +46,21 @@ export abstract class PullRequestTool implements vscode.LanguageModelTool, _token: vscode.CancellationToken): Promise { + async invoke(options: vscode.LanguageModelToolInvocationOptions, _token: vscode.CancellationToken): Promise { let pullRequest = this._findActivePullRequest(); if (!pullRequest) { return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart('There is no active pull request')]); } + if ((options.input as PullRequestToolParams | undefined)?.refresh) { + await Promise.all([ + pullRequest.githubRepository.getPullRequest(pullRequest.number, 'ActivePullRequestTool.invoke'), + pullRequest.getTimelineEvents(), + pullRequest.initializeReviewThreadCacheAndReviewComments(), + ]); + } + const timeline = (pullRequest.timelineEvents && pullRequest.timelineEvents.length > 0) ? pullRequest.timelineEvents : await pullRequest.getTimelineEvents(); const reviewAndCommentEvents = timeline.filter((event): event is ReviewEvent | CommentEvent => event.event === EventType.Reviewed || event.event === EventType.Commented); @@ -62,12 +74,16 @@ export abstract class PullRequestTool implements vscode.LanguageModelTool { + reviewThreads: pullRequest.reviewThreadsCache.map(thread => { return { - author: comment.user?.login, - body: comment.body, - commentState: comment.isResolved ? 'resolved' : 'unresolved', - file: comment.path + id: thread.id, + isResolved: thread.isResolved, + canResolve: thread.viewerCanResolve, + file: thread.path, + comments: thread.comments.map(c => ({ + author: c.user?.login, + body: c.body, + })), }; }), timelineComments: reviewAndCommentEvents.map(event => { @@ -85,7 +101,8 @@ export abstract class PullRequestTool implements vscode.LanguageModelTool manager.activePullRequest); diff --git a/src/lm/tools/createPullRequestTool.ts b/src/lm/tools/createPullRequestTool.ts new file mode 100644 index 0000000000..fb00192972 --- /dev/null +++ b/src/lm/tools/createPullRequestTool.ts @@ -0,0 +1,104 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as vscode from 'vscode'; +import { RepoToolBase } from './toolsUtils'; +import { CredentialStore } from '../../github/credentials'; +import { FolderRepositoryManager } from '../../github/folderRepositoryManager'; +import { RepositoriesManager } from '../../github/repositoriesManager'; + +interface CreatePullRequestToolParameters { + title: string; + body?: string; + head: string; + headOwner?: string; + base?: string; + draft?: boolean; + repo?: { + owner?: string; + name?: string; + }; +} + +interface ResolvedPullRequestParams { + owner: string; + name: string; + head: string; + base: string; + folderManager: FolderRepositoryManager; +} + +export class CreatePullRequestTool extends RepoToolBase { + public static readonly toolId = 'github-pull-request_create_pull_request'; + + constructor(credentialStore: CredentialStore, repositoriesManager: RepositoriesManager) { + super(credentialStore, repositoriesManager); + } + + private async resolveParams(input: CreatePullRequestToolParameters): Promise { + const { owner, name, folderManager } = await this.getRepoInfo({ owner: input.repo?.owner, name: input.repo?.name }); + const defaults = await folderManager.getPullRequestDefaults(); + const headOwner = input.headOwner ?? defaults.owner; + const head = `${headOwner}:${input.head}`; + const base = input.base ?? defaults.base; + return { owner, name, head, base, folderManager }; + } + + async invoke(options: vscode.LanguageModelToolInvocationOptions, _token: vscode.CancellationToken): Promise { + const { owner, name, head, base, folderManager } = await this.resolveParams(options.input); + + const result = await folderManager.createPullRequest({ + owner, + repo: name, + title: options.input.title, + body: options.input.body, + head, + base, + draft: options.input.draft, + }); + + if (!result) { + return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart('Failed to create the pull request.')]); + } + + const prInfo = { + number: result.number, + title: result.title, + body: result.body, + url: result.html_url, + isDraft: result.isDraft, + state: result.state, + base: result.base?.ref, + head: result.head?.ref, + }; + + return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart(JSON.stringify(prInfo))]); + } + + async prepareInvocation(options: vscode.LanguageModelToolInvocationPrepareOptions): Promise { + const resolved = await this.resolveParams(options.input); + const { owner, name, base } = resolved; + // resolved.head is "owner:branch"; extract just the branch part for display + const headBranch = resolved.head.slice(resolved.head.indexOf(':') + 1); + + const repoLabel = `${owner}/${name}`; + const message = new vscode.MarkdownString(); + message.appendMarkdown(`**Title:** ${options.input.title}\n\n`); + if (options.input.body) { + message.appendMarkdown(`**Description:** ${options.input.body}\n\n`); + } + message.appendMarkdown(`**Branch:** \`${headBranch}\` → \`${base}\`\n\n`); + message.appendMarkdown(`**Repository:** ${repoLabel}\n\n`); + + return { + invocationMessage: vscode.l10n.t('Creating pull request'), + confirmationMessages: { + title: vscode.l10n.t('Create Pull Request'), + message, + }, + }; + } +} diff --git a/src/lm/tools/openPullRequestTool.ts b/src/lm/tools/openPullRequestTool.ts index 95ffa86aff..58ac7f364d 100644 --- a/src/lm/tools/openPullRequestTool.ts +++ b/src/lm/tools/openPullRequestTool.ts @@ -10,7 +10,7 @@ import { PullRequestModel } from '../../github/pullRequestModel'; import { PullRequestOverviewPanel } from '../../github/pullRequestOverview'; export class OpenPullRequestTool extends PullRequestTool { - public static readonly toolId = 'github-pull-request_openPullRequest'; + public static readonly toolId = 'github-pull-request_pullRequestInViewport'; protected _findActivePullRequest(): PullRequestModel | undefined { // First check if there's an active PR overview panel diff --git a/src/lm/tools/resolveReviewThreadTool.ts b/src/lm/tools/resolveReviewThreadTool.ts new file mode 100644 index 0000000000..d703cf1cfb --- /dev/null +++ b/src/lm/tools/resolveReviewThreadTool.ts @@ -0,0 +1,72 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import * as vscode from 'vscode'; +import { PullRequestModel } from '../../github/pullRequestModel'; +import { RepositoriesManager } from '../../github/repositoriesManager'; + +interface ResolveReviewThreadToolParameters { + threadId: string; +} + +export class ResolveReviewThreadTool implements vscode.LanguageModelTool { + public static readonly toolId = 'github-pull-request_resolveReviewThread'; + + constructor(private readonly folderManagers: RepositoriesManager) { } + + private _findActivePullRequest(): PullRequestModel | undefined { + const folderManager = this.folderManagers.folderManagers.find((manager) => manager.activePullRequest); + return folderManager?.activePullRequest; + } + + async prepareInvocation(options: vscode.LanguageModelToolInvocationPrepareOptions): Promise { + const pullRequest = this._findActivePullRequest(); + const threadId = options.input?.threadId; + + if (!pullRequest) { + return { + invocationMessage: vscode.l10n.t('Resolving review thread'), + }; + } + + const thread = pullRequest.reviewThreadsCache.find(t => t.id === threadId); + const file = thread?.path ? ` in \`${thread.path}\`` : ''; + const firstComment = thread?.comments[0]?.body; + const snippet = firstComment ? `: "${firstComment.length > 60 ? firstComment.slice(0, 57) + '...' : firstComment}"` : ''; + + return { + invocationMessage: vscode.l10n.t('Resolving review thread{0}{1}', file, snippet), + }; + } + + async invoke(options: vscode.LanguageModelToolInvocationOptions, _token: vscode.CancellationToken): Promise { + const pullRequest = this._findActivePullRequest(); + if (!pullRequest) { + return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart('There is no active pull request.')]); + } + + const { threadId } = options.input; + if (!threadId) { + return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart('No threadId provided.')]); + } + + const thread = pullRequest.reviewThreadsCache.find(t => t.id === threadId); + if (!thread) { + return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart(`Review thread with id "${threadId}" not found on the active pull request.`)]); + } + + if (thread.isResolved) { + return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart(`Review thread "${threadId}" is already resolved.`)]); + } + + if (!thread.viewerCanResolve) { + return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart(`You do not have permission to resolve review thread "${threadId}".`)]); + } + + await pullRequest.resolveReviewThread(threadId); + return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart(`Review thread "${threadId}" resolved successfully.`)]); + } +} diff --git a/src/lm/tools/tools.ts b/src/lm/tools/tools.ts index 01ac91eeaa..5d122caa42 100644 --- a/src/lm/tools/tools.ts +++ b/src/lm/tools/tools.ts @@ -6,11 +6,13 @@ import * as vscode from 'vscode'; import { ActivePullRequestTool } from './activePullRequestTool'; +import { CreatePullRequestTool } from './createPullRequestTool'; import { FetchIssueTool } from './fetchIssueTool'; import { FetchLabelsTool } from './fetchLabelsTool'; import { FetchNotificationTool } from './fetchNotificationTool'; import { OpenPullRequestTool } from './openPullRequestTool'; import { PullRequestStatusChecksTool } from './pullRequestStatusChecksTool'; +import { ResolveReviewThreadTool } from './resolveReviewThreadTool'; import { SearchTool } from './searchTools'; import { CredentialStore } from '../../github/credentials'; import { RepositoriesManager } from '../../github/repositoriesManager'; @@ -21,6 +23,8 @@ export function registerTools(context: vscode.ExtensionContext, credentialStore: context.subscriptions.push(vscode.lm.registerTool(ActivePullRequestTool.toolId, new ActivePullRequestTool(repositoriesManager))); context.subscriptions.push(vscode.lm.registerTool(OpenPullRequestTool.toolId, new OpenPullRequestTool(repositoriesManager))); context.subscriptions.push(vscode.lm.registerTool(PullRequestStatusChecksTool.toolId, new PullRequestStatusChecksTool(credentialStore, repositoriesManager))); + context.subscriptions.push(vscode.lm.registerTool(CreatePullRequestTool.toolId, new CreatePullRequestTool(credentialStore, repositoriesManager))); + context.subscriptions.push(vscode.lm.registerTool(ResolveReviewThreadTool.toolId, new ResolveReviewThreadTool(repositoriesManager))); } function registerFetchingTools(context: vscode.ExtensionContext, credentialStore: CredentialStore, repositoriesManager: RepositoriesManager) { diff --git a/src/test/common/utils.test.ts b/src/test/common/utils.test.ts index aabe5b77d3..b7e096775e 100644 --- a/src/test/common/utils.test.ts +++ b/src/test/common/utils.test.ts @@ -51,4 +51,230 @@ describe('utils', () => { assert.strictEqual(utils.formatError(error), 'Cannot push to this repo'); }); }); + + describe('processPermalinks', () => { + const repoName = 'vscode'; + const authority = 'github.com'; + const sha = 'a'.repeat(40); + + function makePermalink(filePath: string, startLine: number, endLine?: number): string { + const lineRef = endLine ? `#L${startLine}-L${endLine}` : `#L${startLine}`; + return `link text`; + } + + it('should add data attributes when file exists locally', async () => { + const html = makePermalink('src/file.ts', 10); + const result = await utils.processPermalinks(html, repoName, authority, async () => true); + + assert(result.includes('data-local-file="src/file.ts"')); + assert(result.includes('data-start-line="10"')); + assert(result.includes('data-end-line="10"')); + assert(result.includes('data-link-type="blob"')); + assert(result.includes('data-permalink-processed="true"')); + assert(result.includes('view on GitHub')); + }); + + it('should set end line when range is specified', async () => { + const html = makePermalink('src/file.ts', 10, 20); + const result = await utils.processPermalinks(html, repoName, authority, async () => true); + + assert(result.includes('data-start-line="10"')); + assert(result.includes('data-end-line="20"')); + }); + + it('should not modify links when file does not exist locally', async () => { + const html = makePermalink('src/file.ts', 10); + const result = await utils.processPermalinks(html, repoName, authority, async () => false); + + assert.strictEqual(result, html); + }); + + it('should not modify non-permalink links', async () => { + const html = 'example'; + const result = await utils.processPermalinks(html, repoName, authority, async () => true); + + assert.strictEqual(result, html); + }); + + it('should not modify links to a different repo', async () => { + const html = `link`; + const result = await utils.processPermalinks(html, repoName, authority, async () => true); + + assert.strictEqual(result, html); + }); + + it('should skip already processed links', async () => { + const html = `link`; + const result = await utils.processPermalinks(html, repoName, authority, async () => true); + + assert.strictEqual(result, html); + }); + + it('should process multiple links independently', async () => { + const html = makePermalink('src/exists.ts', 1) + makePermalink('src/missing.ts', 2); + const result = await utils.processPermalinks(html, repoName, authority, async (path) => path === 'src/exists.ts'); + + assert(result.includes('data-local-file="src/exists.ts"')); + assert(!result.includes('data-local-file="src/missing.ts"')); + }); + + it('should return original HTML when fileExistsCheck throws', async () => { + const html = makePermalink('src/file.ts', 10); + const result = await utils.processPermalinks(html, repoName, authority, async () => { throw new Error('fail'); }); + + assert.strictEqual(result, html); + }); + + it('should handle links without surrounding text', async () => { + const html = makePermalink('src/file.ts', 5); + const result = await utils.processPermalinks(html, repoName, authority, async () => true); + + assert(result.includes('link text')); + assert(result.includes('data-local-file="src/file.ts"')); + }); + + it('should escape HTML special characters in file paths', async () => { + const html = makePermalink('src/file&name-test.ts', 10); + const result = await utils.processPermalinks(html, repoName, authority, async () => true); + + assert(result.includes('data-local-file="src/file&name-test.ts"')); + assert(!result.includes('data-local-file="src/file&name-test.ts"')); + }); + }); + + describe('processDiffLinks', () => { + const repoOwner = 'microsoft'; + const repoName = 'vscode'; + const authority = 'github.com'; + const prNumber = 123; + const diffHash = 'a'.repeat(64); + + function makeDiffLink(hash: string, startLine?: number, endLine?: number, variant: 'files' | 'changes' = 'files'): string { + let fragment = `diff-${hash}`; + if (startLine !== undefined) { + fragment += `R${startLine}`; + if (endLine !== undefined) { + fragment += `-R${endLine}`; + } + } + return `link text`; + } + + it('should add data attributes when hash maps to a file', async () => { + const hashMap: Record = { [diffHash]: 'src/file.ts' }; + const html = makeDiffLink(diffHash, 10); + const result = await utils.processDiffLinks(html, repoOwner, repoName, authority, hashMap, prNumber); + + assert(result.includes('data-local-file="src/file.ts"')); + assert(result.includes('data-start-line="10"')); + assert(result.includes('data-end-line="10"')); + assert(result.includes('data-link-type="diff"')); + assert(result.includes('data-permalink-processed="true"')); + assert(result.includes('view on GitHub')); + }); + + it('should set end line when range is specified', async () => { + const hashMap: Record = { [diffHash]: 'src/file.ts' }; + const html = makeDiffLink(diffHash, 10, 20); + const result = await utils.processDiffLinks(html, repoOwner, repoName, authority, hashMap, prNumber); + + assert(result.includes('data-start-line="10"')); + assert(result.includes('data-end-line="20"')); + }); + + it('should default start line to 1 when no line is specified', async () => { + const hashMap: Record = { [diffHash]: 'src/file.ts' }; + const html = makeDiffLink(diffHash); + const result = await utils.processDiffLinks(html, repoOwner, repoName, authority, hashMap, prNumber); + + assert(result.includes('data-start-line="1"')); + assert(result.includes('data-end-line="1"')); + }); + + it('should not modify links when hash is not in the map', async () => { + const hashMap: Record = {}; + const html = makeDiffLink(diffHash, 10); + const result = await utils.processDiffLinks(html, repoOwner, repoName, authority, hashMap, prNumber); + + assert.strictEqual(result, html); + }); + + it('should not modify non-diff links', async () => { + const hashMap: Record = { [diffHash]: 'src/file.ts' }; + const html = 'example'; + const result = await utils.processDiffLinks(html, repoOwner, repoName, authority, hashMap, prNumber); + + assert.strictEqual(result, html); + }); + + it('should not modify links to a different repo', async () => { + const hashMap: Record = { [diffHash]: 'src/file.ts' }; + const html = `link`; + const result = await utils.processDiffLinks(html, repoOwner, repoName, authority, hashMap, prNumber); + + assert.strictEqual(result, html); + }); + + it('should skip already processed links', async () => { + const hashMap: Record = { [diffHash]: 'src/file.ts' }; + const html = `link`; + const result = await utils.processDiffLinks(html, repoOwner, repoName, authority, hashMap, prNumber); + + assert.strictEqual(result, html); + }); + + it('should match links using changes variant', async () => { + const hashMap: Record = { [diffHash]: 'src/file.ts' }; + const html = makeDiffLink(diffHash, 5, undefined, 'changes'); + const result = await utils.processDiffLinks(html, repoOwner, repoName, authority, hashMap, prNumber); + + assert(result.includes('data-local-file="src/file.ts"')); + assert(result.includes('data-start-line="5"')); + }); + + it('should process multiple links independently', async () => { + const otherHash = 'b'.repeat(64); + const hashMap: Record = { [diffHash]: 'src/found.ts' }; + const html = makeDiffLink(diffHash, 1) + makeDiffLink(otherHash, 2); + const result = await utils.processDiffLinks(html, repoOwner, repoName, authority, hashMap, prNumber); + + assert(result.includes('data-local-file="src/found.ts"')); + assert(!result.includes('data-local-file="src/other.ts"')); + }); + + it('should escape HTML special characters in file names', async () => { + const hashMap: Record = { [diffHash]: 'src/file&name"test.ts' }; + const html = makeDiffLink(diffHash, 10); + const result = await utils.processDiffLinks(html, repoOwner, repoName, authority, hashMap, prNumber); + + assert(result.includes('data-local-file="src/file&name"test.ts"')); + assert(!result.includes('data-local-file="src/file&name"test.ts"')); + }); + }); + + describe('escapeHtmlAttr', () => { + it('should escape ampersands', () => { + assert.strictEqual(utils.escapeHtmlAttr('foo&bar'), 'foo&bar'); + }); + + it('should escape double quotes', () => { + assert.strictEqual(utils.escapeHtmlAttr('foo"bar'), 'foo"bar'); + }); + + it('should escape single quotes', () => { + assert.strictEqual(utils.escapeHtmlAttr('foo\'bar'), 'foo'bar'); + }); + + it('should escape angle brackets', () => { + assert.strictEqual(utils.escapeHtmlAttr('